请问stm32f10x单片机的RTC设计时注意事项,应有遇同样问题的
我是按照开发板上的电路进行设置的
1.vbat供电
采用备份电池和3.3电源电源均经过二极管后接到vbat引脚;
2.晶振采用32.768Khz石英晶振,起振电容采用20uF;距单片机引脚很近
电路板我进行了两次设计,第一次时外部晶振能够进行工作。第二次时同样电路外部不能工作。
其它现象:
1. 如果使用内部晶振,可工作。但起始时必须对计数值进行设置,否则读出来的是0;(感觉设置的值没有保存起来,量vbat引脚电源供电正常)
2.使用外部晶振时,在while循环里死等了
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
3.向备份域BKP_DR1写值,读写正常
请各位虾客帮忙分析,分析出来绝对是高手。
请问你运行了以下代码了吗?
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
20uF ??? 20pF 吧?
用示波器 测试晶体的引脚 看看有没有震荡波形
回楼上各位有心人
1. to 2楼:那段代码有。程序一样。第一批板时程序可用。
2. to 3楼:测了,有波形,但是程序用外晶时,死等了
3. to 4楼:换了晶振不起作用.
用的芯片为stm32f103c8 48脚的。程序应该没问题,以下为配置程序
4. 我想问问,芯片不会有问题吧?但是这批我这里都这样。从万里拿的
void RTC_Configuration(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
#ifdef RTCClockSource_LSI
/* Enable LSI */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{
}
/* Select LSI as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
#elif defined RTCClockSource_LSE
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
#endif
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
#ifdef RTCClockOutput_Enable
/* Disable the Tamper Pin */
BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
functionality must be disabled */
/* Enable RTC Clock Output on Tamper Pin */
BKP_RTCCalibrationClockOutputCmd(ENABLE);
#endif
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
//这里因为其它中断太多,能不触发中断就不触发
// RTC_ITConfig(RTC_IT_SEC, ENABLE);
// RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
#ifdef RTCClockSource_LSI
RTC_SetPrescaler(31999); /* RTC period = RTCCLK/RTC_PR = (32.000 KHz)/(31999+1) */
#elif defined RTCClockSource_LSE
RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
#endif
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
你的晶振是哪里买的?看看晶振的数据手册
看看晶振的数据手册,再对照STM32的数据手册,检查一下是否满足条件。
钟振的起振电容可以先不要啦
两脚直接和STM32先连接,试一下
这一般是晶振的问题,
用示波器好好观测一下振荡波形,以及VBAT、VCC
芯片可能很少。。。
主电源掉电后内部RC震荡器也断电了,当然时钟的值不能继续
你的问题不是VBAT的问题就是外部晶振的问题。
肯定不是香版主那么解释的
香版主你敢确认吗?因为使用内部晶振时,我在别的板子上跑过,时钟是不走,但是先前的值还是保存的。上电或复位后从先前的值开始计数。而这批却是根本没有保存值。一复位时钟的值就是0。
对不起,我写错了,应该是主电源掉电后时钟的值不能继续
我认为你的问题还是VBAT没有搞好,能看看你的电路图吗?
STM32固件库中有一个使用RTC的例程可以参考
Example description
===================
This example demonstrates and explains how to use the RTC peripheral. As an application example, it demonstrates how to setup the RTC peripheral, in terms of prescaler and interrupts, to be used to keep time and to generate Second interrupt.
The Low Speed External (LSE) clock is used as RTC clock source. The RTC clock can be output on the Tamper pin (PC.13). To enable this functionality, uncomment the corresponding line: #define RTCClockOutput_Enable in the main.c file.
The RTC is in the backup (BKP) domain, still powered by VBAT when VDD is switched off, so the RTC configuration is not lost if a battery is connected to the VBAT pin. A key value is written in backup data register1 (BKP_DR1) to indicate if the RTC is already configured.
我感觉不是vbat供电的原因,谢谢香版主的热情
以下是电路图,看看有问题吗?
请把R3去掉,把D6、D7去掉
VBAT管脚没必要接VCC,如果没有电池,VBAT可以空着。
当VDD存在时,VBAT被自动断开,内部备份区域有VDD供电。
另外,没有看到你的VDDA,希望没有问题。
我把R3短路掉也不行。VDDA是电源引脚吗?
四侧的电源都有供电。每侧一组。不知你说的VDDA是什么指这几组电源不?
我看了VDDA与VDD相连。应该不用怀疑这个。
因为我的板子其它部分都工作正常,它的外围我基本上都试过了。现在就是RTC感觉不正常,所以请教香版
我看你还是使用外部时钟试试,把程序调好
记得在另一个帖子中提过此事。
另一贴是时钟校正问题,在那个板子上能没问题
在那个板子上可跑rtc,使用外部晶振。电路相同。芯片批次不同。
到现在,上面问的问题还是没有拿到答案。
1. 如果使用内部晶振,可工作。但起始时必须对计数值进行设置,否则读出来的是0;(感觉设置的值没有保存起来,量vbat引脚电源供电正常)
2.使用外部晶振时,在while循环里死等了
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
}
ST固件库中可运行的代码
这是我在12楼讲的STM32固件库中使用RTC的例程中有关配置RTC部分,我怀疑你漏了使能备份域。你给的程序不全,很难判断。
void RTC_Configuration(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE); // 怀疑你漏了这句
/* Reset Backup Domain */
BKP_DeInit();
/* Enable LSE */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{}
/* Select LSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
肯定没有漏了。说过多遍。在别的板子上能跑
能跑意味着程序应该没问题。我再自己使劲找找原因吧