zoukankan      html  css  js  c++  java
  • (转)CortexM3 (NXP LPC1788)之RTC

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

    程序运行串口打印信息如下图:

    RTC

  • 相关阅读:
    页面跳转
    vue项目流程
    前端框架发展史
    webpack构建react项目和发布流程
    React工作原理
    React项目中的registerServiceWorker作用?
    学习react总结
    浏览器的渲染:过程与原理
    浮动相关
    块级元素与内嵌元素
  • 原文地址:https://www.cnblogs.com/tdyizhen1314/p/2704593.html
Copyright © 2011-2022 走看看