万利的EK-STM32F板子,预分频值设置为32763,打开秒中断,在秒中断程序里LED翻转一次,看了一下,LED翻转一次的时间大概是15秒,不解?
相关的设置程序
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
//使能外部晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部晶振稳定
HSEStartUpStatus = RCC_WaitForHSEStartUp();
//如果外部晶振启动成功,则进行下一步操作
if(HSEStartUpStatus==SUCCESS)
{
//开启FLASH预取指功能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//FLASH时序控制
//推荐值:SYSCLK = 0~24MHz Latency=0
// SYSCLK = 24~48MHz Latency=1
// SYSCLK = 48~72MHz Latency=2
FLASH_SetLatency(FLASH_Latency_2);
//设置HCLK(AHB时钟)=SYSCLK
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//PCLK2(APB2) = HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//PCLK1(APB1) = HCLK/2
RCC_PCLK1Config(RCC_HCLK_Div2);
//PLL设置 SYSCLK/1 * 9 = 8*1*9 = 72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//启动PLL
RCC_PLLCmd(ENABLE);
//等待PLL稳定
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//系统时钟SYSCLK来自PLL输出
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//切换时钟后等待系统时钟稳定
while(RCC_GetSYSCLKSource()!=0x08)
{
}
}
else
{
/* If HSE fails to start-up, the application will have wrong clock configuration.
User can add here some code to deal with this error */
/* Go to infinite loop */
while (1)
{
}
}
//下面是给各模块开启时钟
//启动GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD,
ENABLE);
//启动AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
void RTC_Configuration(void)
{
//启用PWR和BKP的时钟(from APB1)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);
//后备域解锁
PWR_BackupAccessCmd(ENABLE);
//备份寄存器模块复位
BKP_DeInit();
//外部32.768K
RCC_LSEConfig(RCC_LSE_ON);
//等待稳定
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);
//RTC时钟源配置成LSE(外部32.768K)
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
//RTC开启
RCC_RTCCLKCmd(ENABLE);
//开启后需要等待APB1时钟与RTC时钟同步,才能读写寄存器
RTC_WaitForSynchro();
//读写寄存器前,要确定上一个操作已经结束
RTC_WaitForLastTask();
//设置RTC分频器,使RTC时钟为1Hz
//RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
RTC_SetPrescaler(32763);
//加快一点,设置为32767一天慢20秒 设置为32764一天慢1秒
//等待寄存器写入完成
RTC_WaitForLastTask();
//使能秒中断
RTC_ITConfig(RTC_IT_SEC,ENABLE);
//等待写入完成
RTC_WaitForLastTask();
}
实在查不出问题在哪儿,看到很多关于STM的RTC不准的问题,是不是也是这个原因。
配置了,要不LED怎么能翻转呢
这是NVIC部分。
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x00);
#else /* VECT_TAB_FLASH */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);
#endif
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the RTC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable and configure RCC global IRQ channel */
NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
请先使用内部的RC振荡器作为RTC的时钟
内部的RC振荡器大概在40kHz左右。
看看你能得到什么结果,这样对照一下如果与使用LSE差的不多,应该是RTC之后的问题;如果差的比较多,则可能是晶振的振荡有问题,可以用示波器检查看看。
内部RC一样的问题
主程序只是一个一秒钟点LED工作,如下
while(1)
{
if(TimeDisplay==1)
{
TimeDisplay = 0;
GPIOC->ODR ^= (1<<5);//PC5
}
}
这是RTC中断程序
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
GPIOC->ODR ^= (1<<4);
TimeDisplay = 1;
}
}
不知道其他哪儿会有影响,请指点一下。
不要使用RTC的中断,
就算你这次调试好了,下次修改程序时又会出现这样奇怪的问题,而且非常奇怪,不信你可以仿真并且在里面都使用几个条件语句,你看看这些条件语句是否会出现,至少我没有解决这个问题,最后放弃使用RTC的中断
怀疑是分频器设置有问题
试试修改这句中的参数:RTC_SetPrescaler(32763);
把参数大幅改小看看什么结果。
再有就是直接看看RTC预分频装载寄存器(RTC_PRLH/RTC_PRLL)的内容,确认是否正确。
RTC预分频装载寄存器是正确的
我查看了,RTC预分频装载寄存器值是0x7ffb=32763,正确的
RTC预分频装载寄存器是20位的,分别在2个16位的寄存器中
RTC_PRLH/RTC_PRLL
你肯定RTC_PRLH=0?
如果果真如此,只能把振荡器的信号输出到I/O脚上,用示波器检查它的振荡频率。这是我能想到的最后一招了~~~~
谢谢香主
RTC_PRLH=0的,所以没有写出来。
不过还是感谢,自己再慢慢查吧。
你可以看看应用笔记AN2604,可以更清楚地了解RTC的工作
该笔记第6页的图2显示了把振荡器的信号输出到I/O脚上的配置,方便用示波器检查它的振荡频率。
相关链接:
http://www.st.com/stonline/products/literature/an/13789.pdf