
一:问题现象和背景描述。
对于新手学习STM32单片机的视频教程网上一大堆,个人认为江协科技的视频挺不错的(这里绝不是打广告哈 ),对照着视频学习,当程序下载后功能实现正常,皆大欢喜,但也并不总是尽尽如人意,谁学习过程中没遇到一些疑难杂症的,但正是那些我们踩过的坑,才会让我们更加刻骨难忘,说远啦我们言归正传。
例如现在我遇到的这个问题:在做 【13-2】待机模式+RTC时钟实验时,程序编译下载什么都正常,但发现和视频演示功能不一样,出现异常,表现为一直唤醒待机模式,OLED显示CNT\ALR的值会同步增加。这个问题苦恼了我很久,因为我确信程序什么的都没问题,因为它演示的功能很简单,就是启用RTC的闹钟,然后循环显示秒计数器的值和RTC_FLAG_ALR的标志位,再进入待机模式,等到了RTC的闹钟的定时时间,退出待机模式重复执行,很简单的一段逻辑。最后通过汇集各方资料发现原因在于固件库/标准外设库的不一致导致的,视频用的固件库/标准外设库的版本 STM32F10x_StdPeriph_Lib_V3.5.0,而我采用的是 STM32F10x_StdPeriph_Lib_V3.6.0。它们内容几乎一样,但也有一些细微的差别,就拿本次实验所说,区别在于 V3.5.0 PWR.C 文件中 void PWR_EnterSTANDBYMode(void) 函数比 V3.6.0 PWR.C 文件中,多了一句 /* Clear Wake-up flag */PWR->CR |= PWR_CR_CWUF; 结果导致进入待机模式后不停的唤醒,就是因为少了一句对唤醒标志位的清除,从而导致出现异常。

二:解决办法
1:将 V3.6.0 的固件库替换成 V3.5.0。
2:如果嫌麻烦仍使用 V3.6.0的版本,那么在调用进入待机模式的函数前面添加一句对唤醒标志位的清除的操作。

三:示例代码如下:
- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "OLED.h"
- #include "MyRTC.h"
- int main(void)
- {
- OLED_Init();
- MyRTC_Init();
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
-
- OLED_ShowString(1, 1, "CNT :");
- OLED_ShowString(2, 1, "ALR :");
- OLED_ShowString(3, 1, "ALRF:");
-
- PWR_WakeUpPinCmd(ENABLE);
-
- uint32_t Alarm = RTC_GetCounter() + 10;
- RTC_SetAlarm(Alarm);
- OLED_ShowNum(2, 6, Alarm, 10);
-
- while (1)
- {
- OLED_ShowNum(1, 6, RTC_GetCounter(), 10);
- OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1);
-
- OLED_ShowString(4, 1, "Running");
- Delay_ms(100);
- OLED_ShowString(4, 1, " ");
- Delay_ms(100);
-
- OLED_ShowString(4, 9, "STANDBY");
- Delay_ms(1000);
- OLED_ShowString(4, 9, " ");
- Delay_ms(100);
-
- OLED_Clear();
-
- /* Clear Wake-up flag */
- PWR->CR |= PWR_CR_CWUF;
- PWR_EnterSTANDBYMode();
- }
- }
复制代码
四:图片对比
|