Chinaunix首页 | 论坛 | 博客
  • 博客访问: 241056
  • 博文数量: 41
  • 博客积分: 928
  • 博客等级: 准尉
  • 技术积分: 550
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-01 10:07
文章分类
文章存档

2011年(41)

分类: 嵌入式

2011-05-29 17:01:33

对于2440的实时时钟操作还是比较简单的,难点的地方在于用设置串口通信来控制时钟时钟的读写设置时间和闹铃。但是用串口控制时钟终将只能用于测试,对于产品的话必然要用到显示器,或者lcd或者数码管,不过现代的时钟更加趋向于用lcd 况且能显示更多的信息。


1. 时钟的数据已经存到寄存器中了,只有读取寄存器的值就可以读出时钟,注意当秒钟为0的时候需要重新读取寄存器的值,这里有个一秒的问题。

2.数据的格式为BCD码,用4位二进制表示出十进制数,其本质还是二进制编码。

3. 数据的格式适合用结构体,还有多命令控制时用枚举类型比较好,以后要多用习惯这样的用法。

4. 闹铃中断的发生,当设定的闹铃时间和时钟的时间相同时闹铃中断,其中可以有选择的使能year mon date hour min sec ,匹配时从year到sec。例如 只使能分和秒的时候,当时钟的值和设定闹铃的分和秒相同时闹铃中断,即每个小时的多少分多少秒时中断发生。这样一来就可以很灵活的运用闹铃功能了。

代码

  1. enum {idle, write, read} cmd ;     //UART control write&read
  2. enum {set, Nset, alarm} settime ;         //预设时钟 闹铃
  3. enum {right, wrong} setformat ; //settime format flag
  4. int setcount = -1 ;             //用于设定时间闹铃计数
  5. enum {start, end} uartrtcflag ;     //串口设定时间闹铃数据开始结束标志
  6. typedef struct time
  7. {
  8.     char year ;
  9.     char mon ;
  10.     char date ;
  11.     char day ;    // day of week
  12.     char hour ;
  13.     char mini ;
  14.     char sec ;
  15. } RTC ;

  16. char RTCstr[17] = "00-00-00 00:00:00" ;
  17. /***********************************
  18. UART_int初始化led IO端口GPBCON5-8
  19. 初始化GPBHCON为串口通信
  20. 配置串口通信寄存器
  21. 配置中断寄存器
  22. ************************************/
  23. void UART_int_init(void)
  24. {
  25.     //configuration LED IO port
  26.     rGPBCON &= ~(0xff<<10) ;
  27.     rGPBCON |= 0x55<<10 ;
  28.     //configuration GPHCON to UART
  29.     rGPHCON &= ~(0xf<<4) ;
  30.     rGPHCON |= 0xa<<4 ;
  31.     //rGPHCON = 0x00faaa;
  32.     //rGPHUP = 0x7ff ;
  33.     //configuration UART0 communication register
  34.     //8-bits,1 stop bit, no parity
  35.     rULCON0 = 0x03 ;
  36.     rUCON0 = 0x05 ;
  37.     //configuration UART baudrate
  38.     rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;
  39.     //clean interrupt bit
  40.     rSUBSRCPND |= 0x1 ;
  41.     rSRCPND |= 1<<28 ;
  42.     rINTPND |= 1<<28 ;

  43.     //open UART interrupt
  44.     rINTSUBMSK &= ~(0x1) ;
  45.     rINTMSK &= ~(0x1<<28) ;    
  46. }

  47. void UART_send_byte(char Tx_data)
  48. {
  49.     while(!(rUTRSTAT0&0x2)) ;//wait Tx empty
  50.     if(Tx_data == '\n')        //Tx '\n'
  51.     {
  52.         rUTXH0 = 0x0d ;
  53.         while(!(rUTRSTAT0&0x2)) ;
  54.         rUTXH0 = 0x0a ;
  55.     }
  56.     else
  57.     {
  58.         rUTXH0 = Tx_data ;
  59.     }
  60. }

  61. void UART_send_string(const char *str)
  62. {
  63.     while(*str)
  64.     {
  65.         UART_send_byte(*str) ;
  66.         str++ ;
  67.     }
  68. }
  69. char UART_receive_byte(void)
  70. {
  71.     //char temp ;
  72.     
  73.     while(!(rUTRSTAT0&0x1)) ;    //wait RX ready
  74.     
  75.     //temp = rURXH0 ;
  76.     return rURXH0 ;
  77. }
  78. /*************read RTC***************
  79. read RTC data
  80. if secend is 0 re-read RTC data
  81. **************read RTC**************/
  82. void get_rtc(RTC *prtc)
  83. {
  84.     rRTCCON    = 1 ;
  85.     
  86.         prtc->year     = rBCDYEAR ;
  87.         prtc->mon     = rBCDMON ;
  88.         prtc->date     = rBCDDATE ;
  89.         prtc->day    = rBCDDAY ;
  90.         prtc->hour     = rBCDHOUR ;
  91.         prtc->mini     = rBCDMIN ;
  92.         prtc->sec     = rBCDSEC ;
  93.     
  94.     if(prtc->sec==0) //one secend diviation
  95.     {
  96.         prtc->year     = rBCDYEAR ;
  97.         prtc->mon     = rBCDMON ;
  98.         prtc->date     = rBCDDATE ;
  99.         prtc->day    = rBCDDAY ;
  100.         prtc->hour     = rBCDHOUR ;
  101.         prtc->mini     = rBCDMIN ;
  102.         prtc->sec     = rBCDSEC ;
  103.     }
  104.     
  105.     rRTCCON    = 0 ;
  106. }
  107. /******************************************************
  108. convent RTC data to string
  109. the form : xx-xx-xx xx:xx:xx
  110. *******************************************************/
  111. void rtc_to_str(char *str_time, RTC *rtctime)
  112. {    
  113.     //year
  114.     str_time[0] = (char)((rtctime->year >> 4) + 48 ) ;
  115.     str_time[1] = (char)((rtctime->year & 0x0f) + 48) ;
  116.     str_time[2] = '-' ;
  117.     //mon
  118.     str_time[3] = (char)((rtctime->mon >> 4) + 48 ) ;
  119.     str_time[4] = (char)((rtctime->mon & 0x0f) + 48) ;
  120.     str_time[5] = '-' ;
  121.     //date
  122.     str_time[6] = (char)((rtctime->date >> 4) + 48 ) ;
  123.     str_time[7] = (char)((rtctime->date & 0x0f) + 48) ;
  124.     str_time[8] = ' ' ;
  125.     //hour
  126.     str_time[9] = (char)((rtctime->hour >> 4) + 48 ) ;
  127.     str_time[10] = (char)((rtctime->hour & 0x0f) + 48) ;
  128.     str_time[11] = ':' ;
  129.     //mini
  130.     str_time[12] = (char)((rtctime->mini >> 4) + 48 ) ;
  131.     str_time[13] = (char)((rtctime->mini & 0x0f) + 48) ;
  132.     str_time[14] = ':' ;
  133.     //sec
  134.     str_time[15] = (char)((rtctime->sec >> 4) + 48 ) ;
  135.     str_time[16] = (char)((rtctime->sec & 0x0f) + 48) ;
  136.     str_time[17] = '\0' ;
  137. }

  138. void str_to_RTC(char *strtime, RTC *rtctime)
  139. {
  140.     rtctime->year    = ((strtime[0]-48)<<4) + (strtime[1]-48) ;
  141.     if(strtime[2] != '-')
  142.     {
  143.         setformat = wrong ;
  144.         UART_send_string("\n setting time form error please input 's' to re-set") ;
  145.         return ;
  146.     }

  147.     rtctime->mon    = ((strtime[3]-48)<<4) + (strtime[4]-48) ;
  148.     if(strtime[5] != '-')
  149.     {
  150.         setformat = wrong ;
  151.         UART_send_string("\n setting time form error please input 's' to re-set") ;
  152.         return ;
  153.     }
  154.     rtctime->date    = ((strtime[6]-48)<<4) + (strtime[7]-48) ;
  155.     if(strtime[8] != ' ')
  156.     {
  157.         setformat = wrong ;
  158.         UART_send_string("\n setting time form error please input 's' to re-set") ;
  159.         return ;
  160.     }

  161.     rtctime->hour    = ((strtime[9]-48)<<4) + (strtime[10]-48) ;
  162.     if(strtime[11] != ':')
  163.     {
  164.         setformat = wrong ;
  165.         UART_send_string("\n setting time form error please input 's' to re-set") ;
  166.         return ;
  167.     }

  168.     rtctime->mini    = ((strtime[12]-48)<<4) + (strtime[13]-48) ;
  169.     if(strtime[14] != ':')
  170.     {
  171.         setformat = wrong ;
  172.         UART_send_string("\n setting time form error please input 's' to re-set") ;
  173.         return ;
  174.     }

  175.     rtctime->sec    = ((strtime[15]-48)<<4) + (strtime[16]-48) ;
  176.     
  177.     setformat = right ; //set format right flag
  178. }

  179. void set_RTC(RTC *prtc)
  180. {
  181.     rRTCCON    = 1 ;
  182.     
  183.     rBCDYEAR    = prtc->year ;
  184.     rBCDMON        = prtc->mon ;
  185.     rBCDDATE    = prtc->date ;
  186.     rBCDDAY        = prtc->day ;
  187.     rBCDHOUR    = prtc->hour ;
  188.     rBCDMIN        = prtc->mini ;
  189.     rBCDSEC        = prtc->sec ;
  190.     
  191.     rRTCCON    = 0 ;
  192. }

  193. void alarm_init(void)
  194. {
  195.     /****clear RTC alarm interrupt pending****/
  196.     rSRCPND    |=    1<<30 ;
  197.     rINTPND    |=     1<<30 ;
  198.     rINTMSK    &=     ~(1<<30) ;    //open RTC alarm interrupt
  199.     
  200.     rRTCALM    = 0x41 ;        //all alarm Enable    
  201. }

  202. void set_alarm(RTC *prtc)
  203. {
  204.     rRTCCON    = 1 ;
  205.     
  206.     rALMYEAR    = prtc->year ;
  207.     rALMMON        = prtc->mon ;
  208.     rALMDATE    = prtc->date ;
  209.     rALMHOUR    = prtc->hour ;
  210.     rALMMIN        = prtc->mini ;
  211.     rALMSEC        = prtc->sec ;
  212.     
  213.     rRTCCON    = 0 ;
  214. }

  215. void __irq RTC_alarm_interrupt(void)
  216. {
  217.     /****clear RTC alarm interrupt pending****/
  218.     rSRCPND    |=    1<<30 ;
  219.     rINTPND    |=     1<<30 ;
  220.     rINTMSK    &=     ~(1<<30) ;    //open RTC alarm interrupt
  221.     
  222.     rGPBDAT &= ~(0xf<<5) ;    //lighten led
  223.     UART_send_string("\nRTC alarm") ;
  224. }
  225. //UART0 interrupt
  226. void __irq UART0_interrupt(void)
  227. {    
  228.     char value ;
  229.     /*********clean interrupt bit*********/
  230.     rSUBSRCPND |= 0x1 ;            //注意顺序
  231.     rSRCPND |= 1<<28 ;
  232.     rINTPND |= 1<<28 ;
  233.     
  234.     value = UART_receive_byte();
  235.     switch(value)
  236.     {
  237.         case 'w':                 //write    
  238.             cmd = write ;
  239.             break ;
  240.         case 'r':                 //read
  241.             cmd = read ;
  242.             break ;
  243.         case 's':                 //settime
  244.             settime = set;
  245.             UART_send_string("\n please input settime data bxx-xx-xx xx:xx:xxew") ;
  246.              break ;
  247.          case 'a':
  248.              settime = alarm ;    //set alarm
  249.              UART_send_string("\n please input set alarm data bxx-xx-xx xx:xx:xxew") ;
  250.              break ;
  251.          case 'b':                // data format bxx-xx-xx xx:xx:xxew
  252.              uartrtcflag = start ;// set alarm start flag
  253.              setcount = -1 ;
  254.              break ;
  255.          case 'e' :
  256.              uartrtcflag = end ;
  257.              setcount = -1 ;
  258.              break ;
  259.          case 't':                //turnoff alarm
  260.              rRTCALM    = 0 ;        //disable RTC alarm
  261.              rINTMSK    |= 1<<30 ;    //disable RTC alarm interrupt
  262.              break ;
  263.     }
  264.     if(uartrtcflag==start)
  265.     {
  266.         if(value != 'b')
  267.         {
  268.             RTCstr[setcount] = value ;
  269.         }    
  270.         setcount++ ;
  271.     }
  272. }

  273. int Main(void)
  274. {
  275.     RTC rtcdata ;

  276.     MMU_Init();
  277.     ChangeMPllValue(127,2,1);    //405MHZ
  278.     ChangeClockDivider(13,12); //1:3:6 PCLK 67.5M
  279.     
  280.     UART_int_init();    
  281.     cmd = idle ;         //idle model
  282.     settime = Nset ;     //NO settime
  283.     setformat = wrong ;    //NO right setformat
  284.     uartrtcflag = end ;    //NO set data transination
  285.     
  286.     pISR_UART0     = (U32)UART0_interrupt ;
  287.     pISR_RTC    = (U32)RTC_alarm_interrupt ;
  288.     
  289.     while(1)
  290.     {
  291.         if(cmd==write)
  292.         {
  293.             cmd = idle ;//clean write model to idle
  294.             str_to_RTC(RTCstr, &rtcdata) ;
  295.             if(settime==set)
  296.             {
  297.                 settime = Nset ;    //设置时间后清除设置标志,防止无意设置
  298.                 if(setformat==right)
  299.                 {
  300.                     setformat = wrong ;
  301.                     set_RTC(&rtcdata) ;    
  302.                     UART_send_string("\n set RTC time successful") ;
  303.                 }
  304.             }
  305.             if(settime==alarm)
  306.             {
  307.                 settime = Nset ;    //设置闹铃后清除设置标志,防止无意设置
  308.                 if(setformat==right)
  309.                 {
  310.                     setformat = wrong ;
  311.                     alarm_init() ;        //initial alarm register
  312.                     set_alarm(&rtcdata) ;
  313.                     UART_send_string("\n set RTC alarm successful") ;
  314.                 }
  315.             }
  316.         }
  317.         if(cmd==read)
  318.         {
  319.             cmd = idle ; //clean read model to idle
  320.             get_rtc(&rtcdata) ;
  321.             rtc_to_str(RTCstr, &rtcdata) ;
  322.             UART_send_string("\n The current time is \t") ;
  323.             UART_send_string(RTCstr) ;
  324.         }
  325.     }
  326.     return 0 ;    
  327. }

参考了赵老师的博客,这里表示感谢,博客地址

http://blog.csdn.net/zhaocj/archive/2010/04/05/5452541.aspx
阅读(1726) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~