原创 STM32学习笔记(17)-RTC实践

2010-8-24 10:34 5625 10 12 分类: MCU/ 嵌入式

RTC实践


       BKP还没有搞完,怎么又换到了RTC上了,因为RTC和BKP有些联系,想不关联还不行呢。


以下是数据手册上有关RTC的介绍:


******介绍开始


15.1     RTC 简介 


       实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。


       RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。


       系统复位后,禁止访问后备寄存器和RTC,防止对后备区域(BKP)的意外写操作。执行以下操作使能对后备寄存器和RTC的访问:


●  设置寄存器RCC_APB1ENR的PWREN和BKPEN位来使能电源和后备接口时钟


●  设置寄存器PWR_CR的DBP位使能对后备寄存器和RTC的访问。


******介绍结束


       下面就以库中所带的实例来玩这个RTC,正好也要解决TAMPER引脚的问题。


       这次要用到的例子是这个:


055e4f28-ff8c-40d7-a29b-a5a928d5b3e8.jpg



       有关配置没有什么可多说的,把上一个例子:BKP->Backup_Data中修改过的:


stm32_eval.c


stm3210e_eval.h


stm32_eval.h


三个文件复制过来,建立工程,一路顺风,非常顺利地编译、链接好,然后进入调试,结果,出问题了,见下面:


       60d34a7e-a54f-4229-8dd3-95ddbc192d36.jpg


       进入调试界面即停在了反汇编界面。一旦执行程序,立即就停下来。这个BKPT指令是个什么东西呢?查了一下指令表,原来是个断点指令,那为什么会停止在这里呢?万能的网啊,一搜就出来了,感谢前人的努力,感谢伟大的网...。


     结论是:" 凡是用到printf的都会出现这样的问题。"


       解决方法:


cc73b102-b5f0-47f4-bd5b-d60e9530a47f.jpg



打开Options for Target项,把那个Use MicroLIB前面打上勾,重新编译链接即可。


      出现问题的原因,网上的相关解释是:这是Printf库函数的问题,需要使用MicroLIB这个库来替代默认的库。原因是默认printf并非使用串口,所以要改掉。


       在main.c中有这样一段函数:


/**


  * @brief  Retargets the C library printf function to the USART.


  * @param  None


  * @retval None


  */


PUTCHAR_PROTOTYPE


{


  /* Place your implementation of fputc here */


  /* e.g. write a character to the USART */


  USART_SendData(EVAL_COM1, (uint8_t) ch);


   /* Loop until the end of transmission */


  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)


  {}


   return ch;


}


       根据这段函数的说明,就是做这个事情的。


      但是还有一些疑问:


      (1)这个例子的readme.txt中并没有说明要用MicroLIB这个库的事情。


       (2)如果不用硬件,而是用软件仿真,也是不需要使用MicroLIB库的。


       因此,有关MicroLIB的问题还不是特别明确,还需要进一步研究。是否是这段程序还用到了scanf的原因?


例子的运行


       如果是第一次运行,那么会出现如下画面:


fc1852f6-5d30-495b-a1d3-8c501e4adc8c.jpg


即其中有提示RTC没有初始化,要求进行设置的提示,根据提示分别送入小时,分钟,秒的数值,即完成设置工作,程序不断地将当前时间通过串口送出。



如果在VBAT端接入后备电池,那么断电后再上电显示的信息如下:


425e8e08-d02d-465f-8ad6-0f30f61b9ae9.jpg


其中提示RTC已初始化,不需要再进行初始化,直接将时间不断地从串口送出。



程序解读


/**


  * @brief  Configures the RTC.


  * @param  None


  * @retval None


  */


void RTC_Configuration(void)


{


  /* 开启PWR和BKP模块的时钟 */


  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);


   /* 允许对BKP进行存取操作*/


  PWR_BackupAccessCmd(ENABLE);


   /* 初始化BKP区域*/


  BKP_DeInit();


   /* LSE允许,这里LSE是指外部接的32768HZ 晶振的一个振荡器,它使用PC14和PC15两条引脚。有关这部分的一些细节描述如下:


当备份区域由V DD (内部模拟开关连到V DD )供电时,下述功能可用:


●  PC14和PC15可以用于GPIO或LSE引脚


●  PC13可以作为通用I/O口、TAMPER引脚、RTC校准时钟、RTC闹钟或秒输出


当后备区域由VBAT供电时(VDD消失后模拟开关连到VBAT),可以使用下述功能:


●  PC14和PC15只能用于LSE引脚


●  PC13可以作为TAMPER引脚、RTC闹钟或秒输出


*/


  RCC_LSEConfig(RCC_LSE_ON);


  /* 等待LSE振荡器就绪 */


  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)


  {}


   /* 选择LSE作为RTC的时钟源


       说明:RTC时钟源可以是以下三种之一:


─    HSE 时钟除以 128


─    LSE 振荡器时钟


─    LSI振荡器时钟


其中LSI是一个内部的低频RC振荡器。关于RTC的这三个时钟各有何特点,见下面的说明。


*/


  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);


   /* RTC时钟允许*/


  RCC_RTCCLKCmd(ENABLE);


   /* 等待RTC寄存器同步


理由如下:


15.3.3  读 RTC 寄存器 


RTC核完全独立于RTC APB1接口。


软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是如此的。


这意味着,如果APB1接口刚刚被开启之后,在第一次的内部寄存器更新之前,从APB1上读出RTC寄存器的第一个值可能被破坏了(通常读到0)。下述几种情况下能够发生这种情形:


●  发生系统复位或电源复位


●  系统刚从待机模式唤醒(参见4.3节)。


●  系统刚从停机模式唤醒(参见4.3节)。


所有以上情况中,APB1接口被禁止时(复位、无时钟或断电)RTC核仍保持运行状态。 因此,若在读取RTC寄存器曾经被禁止的RTC  APB1接口,软件首先须等待RTC_CRL寄存器中


的RSF位(寄存器同步标志)被硬件置1。


void RTC_WaitForSynchro(void)


{


  /* Clear RSF flag */


  RTC->CRL &= (uint16_t)~RTC_FLAG_RSF;


  /* Loop until RSF flag is set */


  while ((RTC->CRL & RTC_FLAG_RSF) == (uint16_t)RESET)


  {


  }


}


*/


  RTC_WaitForSynchro();


   /* 等待最后写操作完成*/


  RTC_WaitForLastTask();


   /* 允许秒中断,相应代码如下:


void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState)


{


  /* Check the parameters */


  assert_param(IS_RTC_IT(RTC_IT)); 


  assert_param(IS_FUNCTIONAL_STATE(NewState));


    if (NewState != DISABLE)


  {


    RTC->CRH |= RTC_IT;


  }


  else


  {


    RTC->CRH &= (uint16_t)~RTC_IT;


  }


}


而调用这段程序的代码中的第一个参数是:


#define RTC_IT_SEC           ((uint16_t)0x0001)  /*!< Second interrupt */


可见它是对RTC->CRH的最低位进行操作,CRH相关内容见下面的图。


*/


  RTC_ITConfig(RTC_IT_SEC, ENABLE);


   /* 等待最后的写操作完成*/


  RTC_WaitForLastTask();


   /* 设置RTC预分频器: set RTC period to 1sec */


  RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */


   /* 等待最后的写操作完成*/


  RTC_WaitForLastTask();


}


    下面的图是有关RTC时钟选择的问题,其中说明了各种时钟的工作特性:


d1c3b0e9-4c6e-48b2-a07f-b410945eae57.jpg



       下面的图是有关RTC_CRH寄存器的描述,放在这里是为了说明SECIE标志位。


d50fb5c7-1ca6-4071-8abe-8258fa444100.jpg

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

teach51_109853927 2010-8-23 18:59

嗯,谢谢!有空时多交流!

用户324396 2010-8-22 21:55

我顶 我也正在学STM32 在弄示波器,
相关推荐阅读
teach51_109853927 2015-10-25 22:37
带“锁定输出”的数控稳压电源(二)
3.控制程序编写        硬件电路设计完成后,就要编写软件了。软件基本上可以分为键盘驱动,PWM生成,功能实现等部分。 3.1 键盘处理程序        STC单片机的引脚可以...
teach51_109853927 2014-03-02 12:17
带“锁定输出”的数控稳压电源(一)
本文是探索“开源培训”思想的作品。 所谓“开源培训”是指在某个社区,各志愿者提供有一定实用价值和教学价值的作品,同时详细说明制作过程,并提供制作所需的各类资源,帮助入门者快速找到适合自己的项目...
teach51_109853927 2014-02-22 21:15
《单片机项目教程》、《单片机项目教程C语言版》电子课件
《单片机项目教程》电子课件 http://pan.baidu.com/s/1kT2Yb6f 《单片机项目教程C语言版》电子课件 http://pan.baidu.com/s/1gd5O...
teach51_109853927 2014-02-22 21:05
《单片机应用与接口技术》相关资源
单片机应用与接口技术    机械工业出版社出版,江苏省教育厅推荐教材 《单片机应用与接口技术》课件 http://pan.baidu.com/s/1c0kpzUg 《单片机应用与接...
teach51_109853927 2014-02-22 15:25
便携式无线抢答器
本产品专门为开展活动时需要用到抢答器的场合设计,已制作成品,读者可以参考作为练手之用。 如图1所示左边为信号接收装置(主持人用),右边两个为发射装置(比赛选手用)。都只需要使用干电池供电即可。...
teach51_109853927 2014-02-22 15:22
Modbus通讯协议
Modbus协议最初由Modicon公司开发出来,在1979年末该公司成为施耐德自动化(Schneider Automation)部门的一部分,现在Modbus已经是工业领域全球最流行的协议。此协...
EE直播间
更多
我要评论
2
10
关闭 站长推荐上一条 /3 下一条