查看: 4358|回复: 1

[原创] 【我要分享】Cortex-M3 (NXP LPC1788)之RTC

[复制链接]

该用户从未签到

17

主题

32

帖子

0

注册会员

Rank: 2

积分
85
最后登录
2018-6-13
发表于 2017-2-27 08:54:19 | 显示全部楼层 |阅读模式
实时时钟是一组用于测量时间的计数器,如果使用电池供电,在系统掉电以后它也可以正常运行以记录系统的时间。LPC1788时钟采用内部的32K振荡器输出1HZ的时钟信号做为RTC的时钟源。

    RTC的寄存器比较简单,主要有时钟计数器寄存器包括秒SEC 分MIN 小时HOUR  日期(月)DOM 星期DOW 日期(年)DOY 月MONTH 年YEAR, 这些寄存器为R/W 可以从中读出具体的时间信息。其中的秒计数由1HZ时钟驱动。报警寄存器组中的值将和时间计数器寄存器中的值比较,如果所有为屏蔽的报警寄存器都与他们对应的时间计数器相匹配,那么将产生一次中断。报警屏蔽在报警屏蔽寄存器AMR中设置。中断设置在中断位置寄存器ILR中设置。RTC中断不仅可以在报警寄存器和时间计数器匹配时产生,我们也可以配置计数器增量中断寄存器CIIR,使计数器每增加1就产生一次中断。RTC的控制在时钟控制寄存器CCR中,我们可以使能或禁止时钟,以及复位等。

    在下面的程序中,首先PC端使用串口软件发送一串固定格式的时间信息给开发板,开发板收到字符‘a’表示后面跟着的是时间信息,设置了初始时间后,我们配置CCIR使1秒产生一次中断,配置报警寄存器组合报价屏蔽寄存器,使秒计数为30的时候产生中断。在RTC的中断函数中,如果是计数中断,就让接LED的GPIO输出反向电平,根据设置LED灯将1S闪烁。 如果是报警中断,就通过串口在PC打印时间信息。

注意:为了程序的简洁,省去了之前介绍了的系统时钟配置和串口的配置。具体的信息可查询之前的文章。

  1.     #include "LPC1788_REG.h"
  2.     #include "uart.h"
  3.      
  4.     #define rILR    (*(volatile unsigned*)0x40024000)
  5.     #define rCCR    (*(volatile unsigned*)0x40024008)
  6.     #define rCIIR   (*(volatile unsigned*)0x4002400C)
  7.     #define rAMR    (*(volatile unsigned*)0x40024010)
  8.     #define rCALIBRATION    (*(volatile unsigned*)0x40024040)
  9.      
  10.     #define rYEAR   (*(volatile unsigned*)0x4002403C)
  11.     #define rMONTH  (*(volatile unsigned*)0x40024038)
  12.     #define rDOM    (*(volatile unsigned*)0x4002402C)
  13.     #define rHOUR   (*(volatile unsigned*)0x40024028)
  14.     #define rMIN    (*(volatile unsigned*)0x40024024)
  15.     #define rSEC    (*(volatile unsigned*)0x40024020)
  16.      
  17.     #define rALSEC  (*(volatile unsigned*)0x40024060)
  18.      
  19.     #define rCTIME0 (*(volatile unsigned*)0x40024014)
  20.     #define rCTIME1 (*(volatile unsigned*)0x40024018)
  21.     #define rCTIME2 (*(volatile unsigned*)0x4002401C)
  22.      
  23.     unsigned char flag_setTime=1;
  24.     unsigned char flag_receiveStatus=0;
  25.     unsigned char timeData[14],cnt;
  26.      
  27.     void Set_Data()
  28.     {
  29.         rCCR &= ~(0x1<<0);
  30.         rYEAR = (timeData[0]-'0')*1000 + (timeData[1]-'0')*100 + (timeData[2]-'0')*10 + (timeData[3]-'0');
  31.         rMONTH = (timeData[4]-'0')*10 + (timeData[5]-'0');
  32.         rDOM = (timeData[6]-'0')*10 + (timeData[7]-'0');
  33.         rHOUR = (timeData[8]-'0')*10 + (timeData[9]-'0');
  34.         rMIN =  (timeData[10]-'0')*10 + (timeData[11]-'0');
  35.         rSEC =  (timeData[12]-'0')*10 + (timeData[13]-'0');
  36.     }
  37.      
  38.     void Display_Data()
  39.     {
  40.         Uart2SendC('\n');
  41.         Uart2SendC(rYEAR/1000+'0');
  42.         Uart2SendC(rYEAR%1000/100+'0');
  43.         Uart2SendC(rYEAR%100/10+'0');
  44.         Uart2SendC(rYEAR%10+'0');
  45.         Uart2SendC('-');
  46.         Uart2SendC(rMONTH/10+'0');
  47.         Uart2SendC(rMONTH%10+'0');
  48.         Uart2SendC('-');
  49.         Uart2SendC(rDOM/10+'0');
  50.         Uart2SendC(rDOM%10+'0');
  51.         Uart2SendC('\n');
  52.         Uart2SendC(rHOUR/10+'0');
  53.         Uart2SendC(rHOUR%10+'0');
  54.         Uart2SendC(':');
  55.         Uart2SendC(rMIN/10+'0');
  56.         Uart2SendC(rMIN%10+'0');
  57.         Uart2SendC(':');
  58.         Uart2SendC(rSEC/10+'0');
  59.         Uart2SendC(rSEC%10+'0');
  60.     }
  61.          
  62.     void UART2_IRQHandler()
  63.     {
  64.         unsigned int intId;
  65.         char tmp_char;
  66.          
  67.         intId = rU2IIR&0xf;
  68.         if(intId == 0xc || intId == 0x4)    //RDA或者CTI中断
  69.         {
  70.             rU2LCR &= ~(0x1<<7);  //DLAB=0
  71.             tmp_char = rU2RBR&0xff;
  72.             rU2THR = tmp_char;
  73.         }
  74.          
  75.         if(tmp_char == 'a' && flag_receiveStatus == 0)
  76.         {
  77.             flag_receiveStatus = 1;
  78.             cnt = 0;
  79.         }
  80.         elseif(flag_receiveStatus == 1)
  81.         {
  82.             timeData[cnt]=tmp_char;
  83.             cnt++;
  84.             if(cnt == 14)
  85.             {
  86.                 Set_Data();
  87.                 cnt = 0;
  88.                 flag_receiveStatus = 0;
  89.                 flag_setTime=0;
  90.             }
  91.         }
  92.     }
  93.      
  94.     void RTC_IRQHandler()
  95.     {
  96.         unsigned char IntStatus;
  97.         IntStatus = rILR;
  98.         if(IntStatus & 0x1)  //计数中断
  99.         {
  100.             rFIO1PIN = ~rFIO1PIN;
  101.             rILR = IntStatus;
  102.         }
  103.         elseif (IntStatus & (0x1<<1))    //报警中断
  104.         {
  105.             Display_Data();
  106.             rILR = IntStatus;
  107.         }
  108.          
  109.     }
  110.          
  111.     void Init_RTC()
  112.     {
  113.         rILR = 0;
  114.         rCCR = 0;
  115.         rCIIR = 0;
  116.         rAMR = 0xff;
  117.         rCALIBRATION = 0;
  118.          
  119.         rCCR |= 0x1<<1;   //CTC Reset
  120.         rCCR &= ~(0x1<<1);
  121.     }
  122.      
  123.     int main(void)
  124.     {
  125.         char menu[] = {"\n\r===> Send a frame with 6 Byte data to set RTC \n['a']+[year]+[month]+[day]+[hour]+[minute]+[second]\n"};
  126.         char str[]={"\r\nTime set ok! \r\nCurrent time set to:\r\n"};
  127.         rFIO1DIR |= (1<<18); //GPIO1.18 -> OUTPUT
  128.         Init_Uart2();
  129.         Uart2SendS(menu);
  130.         while(flag_setTime);
  131.         Uart2SendS(str);
  132.         Display_Data();
  133.      
  134.         rCCR |= 0x1;
  135.         rCCR |= 0x1<<4;
  136.         rCIIR |= 0x1;       //秒值增加产生一次中断
  137.         rAMR &= ~(0x1<<0);  //秒值与报警寄存器比较
  138.      
  139.         rALSEC = 30;    //秒值为30的时候产生一个报警
  140.      
  141.         rISER0 |= 0x1<<17;  //使能RTC中断
  142.         while(1);
  143.     }
复制代码
  1. #include "LPC1788_REG.h"
  2. #include "uart.h"

  3. #define rILR        (*(volatile unsigned*)0x40024000)
  4. #define rCCR        (*(volatile unsigned*)0x40024008)
  5. #define rCIIR        (*(volatile unsigned*)0x4002400C)
  6. #define rAMR        (*(volatile unsigned*)0x40024010)
  7. #define rCALIBRATION        (*(volatile unsigned*)0x40024040)

  8. #define rYEAR        (*(volatile unsigned*)0x4002403C)
  9. #define rMONTH        (*(volatile unsigned*)0x40024038)
  10. #define rDOM        (*(volatile unsigned*)0x4002402C)
  11. #define rHOUR        (*(volatile unsigned*)0x40024028)
  12. #define rMIN        (*(volatile unsigned*)0x40024024)
  13. #define rSEC        (*(volatile unsigned*)0x40024020)

  14. #define rALSEC        (*(volatile unsigned*)0x40024060)

  15. #define rCTIME0        (*(volatile unsigned*)0x40024014)
  16. #define rCTIME1        (*(volatile unsigned*)0x40024018)
  17. #define rCTIME2        (*(volatile unsigned*)0x4002401C)

  18. unsigned char flag_setTime=1;
  19. unsigned char flag_receiveStatus=0;
  20. unsigned char timeData[14],cnt;

  21. void Set_Data()
  22. {
  23.         rCCR &= ~(0x1<<0);
  24.         rYEAR = (timeData[0]-'0')*1000 + (timeData[1]-'0')*100 + (timeData[2]-'0')*10 + (timeData[3]-'0');
  25.         rMONTH = (timeData[4]-'0')*10 + (timeData[5]-'0');
  26.         rDOM = (timeData[6]-'0')*10 + (timeData[7]-'0');
  27.         rHOUR = (timeData[8]-'0')*10 + (timeData[9]-'0');
  28.         rMIN =  (timeData[10]-'0')*10 + (timeData[11]-'0');
  29.         rSEC =  (timeData[12]-'0')*10 + (timeData[13]-'0');
  30. }

  31. void Display_Data()
  32. {
  33.         Uart2SendC('\n');
  34.         Uart2SendC(rYEAR/1000+'0');
  35.         Uart2SendC(rYEAR%1000/100+'0');
  36.         Uart2SendC(rYEAR%100/10+'0');
  37.         Uart2SendC(rYEAR%10+'0');
  38.         Uart2SendC('-');
  39.         Uart2SendC(rMONTH/10+'0');
  40.         Uart2SendC(rMONTH%10+'0');
  41.         Uart2SendC('-');
  42.         Uart2SendC(rDOM/10+'0');
  43.         Uart2SendC(rDOM%10+'0');
  44.         Uart2SendC('\n');
  45.         Uart2SendC(rHOUR/10+'0');
  46.         Uart2SendC(rHOUR%10+'0');
  47.         Uart2SendC(':');
  48.         Uart2SendC(rMIN/10+'0');
  49.         Uart2SendC(rMIN%10+'0');
  50.         Uart2SendC(':');
  51.         Uart2SendC(rSEC/10+'0');
  52.         Uart2SendC(rSEC%10+'0');
  53. }
  54.        
  55. void UART2_IRQHandler()
  56. {
  57.         unsigned int intId;
  58.         char tmp_char;
  59.        
  60.         intId = rU2IIR&0xf;
  61.         if(intId == 0xc || intId == 0x4)        //RDA或者CTI中断
  62.         {
  63.                 rU2LCR &= ~(0x1<<7);        //DLAB=0
  64.                 tmp_char = rU2RBR&0xff;
  65.                 rU2THR = tmp_char;
  66.         }
  67.        
  68.         if(tmp_char == 'a' && flag_receiveStatus == 0)
  69.         {
  70.                 flag_receiveStatus = 1;
  71.                 cnt = 0;
  72.         }
  73.         else if(flag_receiveStatus == 1)
  74.         {
  75.                 timeData[cnt]=tmp_char;
  76.                 cnt++;
  77.                 if(cnt == 14)
  78.                 {
  79.                         Set_Data();
  80.                         cnt = 0;
  81.                         flag_receiveStatus = 0;
  82.                         flag_setTime=0;
  83.                 }
  84.         }
  85. }

  86. void RTC_IRQHandler()
  87. {
  88.         unsigned char IntStatus;
  89.         IntStatus = rILR;
  90.         if(IntStatus & 0x1)  //计数中断
  91.         {
  92.                 rFIO1PIN = ~rFIO1PIN;
  93.                 rILR = IntStatus;
  94.         }
  95.         else if (IntStatus & (0x1<<1))        //报警中断
  96.         {
  97.                 Display_Data();
  98.                 rILR = IntStatus;
  99.         }
  100.        
  101. }
  102.        
  103. void Init_RTC()
  104. {
  105.         rILR = 0;
  106.         rCCR = 0;
  107.         rCIIR = 0;
  108.         rAMR = 0xff;
  109.         rCALIBRATION = 0;
  110.        
  111.         rCCR |= 0x1<<1;          //CTC Reset
  112.         rCCR &= ~(0x1<<1);
  113. }

  114. int main(void)
  115. {
  116.         char menu[] = {"\n\r===> Send a frame with 6 Byte data to set RTC \n['a']+[year]+[month]+[day]+[hour]+[minute]+[second]\n"};
  117.         char str[]={"\r\nTime set ok! \r\nCurrent time set to:\r\n"};
  118.         rFIO1DIR |= (1<<18); //GPIO1.18 -> OUTPUT
  119.         Init_Uart2();
  120.         Uart2SendS(menu);
  121.         while(flag_setTime);
  122.         Uart2SendS(str);
  123.         Display_Data();

  124.         rCCR |= 0x1;
  125.         rCCR |= 0x1<<4;
  126.         rCIIR |= 0x1;                //秒值增加产生一次中断
  127.         rAMR &= ~(0x1<<0);  //秒值与报警寄存器比较

  128.         rALSEC = 30;        //秒值为30的时候产生一个报警

  129.         rISER0 |= 0x1<<17;  //使能RTC中断
  130.         while(1);
  131. }
复制代码


程序运行串口打印信息如下图:
1341199465_9617.jpg
回复

使用道具 举报

该用户从未签到

6

主题

47

帖子

0

注册会员

Rank: 2

积分
105
最后登录
2018-5-22
发表于 2017-2-27 11:08:35 | 显示全部楼层
感谢分享
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-7-18 05:43 , Processed in 0.091311 second(s), 23 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表