[LOOK] 【M0第6帖||LOOK第4帖】实现RTC显示和通过串口更改RTC设置

[复制链接]
 楼主| nixianmin 发表于 2011-10-5 17:59 | 显示全部楼层 |阅读模式
国庆过的差不多,今天发个基于LOOK的RTC程序,其实也没什么东西,就是写了个RTC类,并能在1602上显示年月日时分秒,能通过串口发送时分秒(每秒发一次),还能通过串口来修改RTC的时间。如果没有1602也能通过串口看到RTC的效果,就是和1602比少显示了年月日。

    在写程序的过程中倒也发现了几个问题,并解决了。在调试RTC时发现,如果我使用RTC的节拍中断,当我串口发一串数据的时候,就不能正确处理,RTC设置也就无法使用,还nulink调试就会不怎么好使,不是进不到中断,就是经常进到中断,到后来,我干脆把中断给去掉了,免得搞得烦,可能像RTC的节拍中断时间太短,又频繁,肯定是不怎么好处理的。如果不用串口设置RTC的话,用节拍中断也是可以的,还有闹钟我还没弄,反正寄存器设置都差不多,设置下TAR和CAR,开中断,时间到就产生中断。


    现在我就是直接在任务里读取时间值,下面是我更新显示的程序,在RTC类中记录了上次的时间,如果读的时间和上次不同则刷新显示,本来想全部嵌套的,由于嵌套太深就把其分为2部分判断,因为只有秒先变才可能分会变,分变了时才可能变,根据这样嵌套就不用全部刷新了,只要将变的值刷新了就好。
  1. void rtc_c::Dis_Updata() //更新时间
  2. {
  3.   uint32_t u32timebuf=0;
  4.   char time_array[10]={0};

  5.   #ifdef _LCD1602_
  6.   int8_t x=10,y=1;
  7.   #endif

  8.   u32timebuf=RTCs.TLR.Regs;//时分秒
  9.   if((u32timebuf&0x0f)!=last_second1) //time updata
  10.   {
  11.     last_second1=u32timebuf&0x0f;
  12.     #ifdef _LCD1602_
  13.     lcd1.Lcd_WByte(x--,y,(last_second1+0x30));
  14.     #endif
  15.     if(((u32timebuf>>4)&0x0f)!=last_second10) //sec
  16.     {
  17.       last_second10=(u32timebuf>>4)&0x0f;
  18.       #ifdef _LCD1602_
  19.       lcd1.Lcd_WByte(x--,y,(last_second10+0x30));
  20.       lcd1.Lcd_WByte(x--,y,':');
  21.       #endif
  22.       if(((u32timebuf>>8)&0x0f)!=last_mintue1) //mintue
  23.       {
  24.         last_mintue1=(u32timebuf>>8)&0x0f;

  25.         #ifdef _LCD1602_
  26.         lcd1.Lcd_WByte(x--,y,(last_mintue1+0x30));
  27.         #endif

  28.         if(((u32timebuf>>12)&0x0f)!=last_mintue10)
  29.         {
  30.           last_mintue10=(u32timebuf>>12)&0x0f;

  31.           #ifdef _LCD1602_
  32.           lcd1.Lcd_WByte(x--,y,(last_mintue10+0x30));
  33.           lcd1.Lcd_WByte(x--,y,':');
  34.           #endif

  35.           if(((u32timebuf>>16)&0x0f)!=last_hour1)   //hour
  36.           {
  37.             last_hour1=(u32timebuf>>16)&0x0f;

  38.             #ifdef _LCD1602_
  39.             lcd1.Lcd_WByte(x--,y,(last_hour1+0x30));
  40.             #endif

  41.             if((u32timebuf>>20)!=last_hour10)
  42.             {
  43.               last_hour10=u32timebuf>>20;

  44.               #ifdef _LCD1602_
  45.               lcd1.Lcd_WByte(x--,y,(last_hour10+0x30));
  46.               #endif
  47.             }
  48.           }
  49.         }
  50.       }
  51.     }
  52.     //当时间改变时通过串口查看
  53.     time_array[0]=last_hour10+0x30;
  54.     time_array[1]=last_hour1+0x30;
  55.     time_array[2]=':';
  56.     time_array[3]=last_mintue10+0x30;
  57.     time_array[4]=last_mintue1+0x30;
  58.     time_array[5]=':';
  59.     time_array[6]=last_second10+0x30;
  60.     time_array[7]=last_second1+0x30;
  61.     time_array[8]='\0';
  62.     uart0.Wstr(time_array);
  63.     uart0.Wstr("     ");         
  64.   }
  65.   
  66.   u32timebuf=RTCs.CLR.Regs;//年月日
  67.   x=12;y=0;
  68.   if((u32timebuf&0x0f)!=last_day1) //time updata
  69.   {
  70.     last_day1=u32timebuf&0x0f;
  71.     #ifdef _LCD1602_
  72.     lcd1.Lcd_WByte(x--,y,(last_day1+0x30));
  73.     #endif
  74.     if(((u32timebuf>>4)&0x0f)!=last_day10) //day
  75.     {
  76.       last_day10=(u32timebuf>>4)&0x0f;
  77.       #ifdef _LCD1602_
  78.       lcd1.Lcd_WByte(x--,y,(last_day10+0x30));
  79.       lcd1.Lcd_WByte(x--,y,' ');
  80.       #endif
  81.       if(((u32timebuf>>8)&0x0f)!=last_month1) //month
  82.       {
  83.         last_month1=(u32timebuf>>8)&0x0f;

  84.         #ifdef _LCD1602_
  85.         lcd1.Lcd_WByte(x--,y,(last_month1+0x30));
  86.         #endif

  87.         if(((u32timebuf>>12)&0x0f)!=last_month10)
  88.         {
  89.           last_month10=(u32timebuf>>12)&0x0f;

  90.           #ifdef _LCD1602_
  91.           lcd1.Lcd_WByte(x--,y,(last_month10+0x30));
  92.           lcd1.Lcd_WByte(x--,y,':');
  93.           #endif

  94.           if(((u32timebuf>>16)&0x0f)!=last_year1)   //year
  95.           {
  96.             last_year1=(u32timebuf>>16)&0x0f;

  97.             #ifdef _LCD1602_
  98.             lcd1.Lcd_WByte(x--,y,(last_year1+0x30));
  99.             #endif

  100.             if((u32timebuf>>20)!=last_year10)
  101.             {
  102.               last_year10=u32timebuf>>20;

  103.               #ifdef _LCD1602_
  104.               lcd1.Lcd_WByte(x--,y,(last_year10+0x30));
  105.               lcd1.Lcd_WByte(x--,y,'0');
  106.               lcd1.Lcd_WByte(x--,y,'2');
  107.               #endif
  108.             }
  109.           }
  110.         }
  111.       }
  112.     }
  113.   }
  114. }
复制代码




下面把主要的任务函数和RTC类发上来
  1. /******************************************/
  2. //声明对象
  3. ///////////////////////////////////////////
  4. #ifdef _LCD1602_
  5. lcd1602_c lcd1;
  6. #endif

  7. rtc_c rtc1(0x11,0x10,0x05,0x03,0x12,0x51,0x00);//RTC初始化时间
  8. uint8_t cnt=0;
  9. uart0_int_c uart0; //串口

  10. #ifdef LOOK_SCHEDULING_PRIORITY
  11. instantiate::task<task1_main_t, LOOK_STACK_SIZE> task1_main(0);
  12. instantiate::task<task2_uart0_c,LOOK_STACK_SIZE> task2_uart0(1);
  13. #else
  14. instantiate::task<task1_main_t, LOOK_STACK_SIZE> task1_main;
  15. instantiate::task<task2_uart0_c,LOOK_STACK_SIZE> task2_uart0;
  16. #endif


  17. /*************************************
  18. //task1任务类的任务函数
  19. **************************************/
  20. void task1_main_t::routine()
  21. {
  22.         #ifdef _LCD1602_ //初始化1602显示
  23.   rtc1.Dis_Time();
  24.   #endif
  25.         // TODO: 在此编写 task1_main_t 例程的内容
  26.         while (true) {
  27.                  rtc1.Dis_Updata();  //更新RTC时间
  28.      cnt=0;
  29.      scheduler.yield();
  30.                 // TODO: 在此编写 task1_main_t 例程的内容
  31.         }
  32. }

  33. /***************************************
  34. //
  35. ***************************************/
  36. void task2_uart0_c::routine()
  37. {
  38.   uint32_t rev_timebuf[7]={0};
  39.   
  40.   uart0.Uart0RxEnableInt();//接收中断使能
  41.         while(true){
  42.     rev_timebuf[cnt++]=task2_megs.get();

  43.     if(cnt==7)
  44.     {
  45.       rtc1.Rtc_Updata(rev_timebuf[0],rev_timebuf[1],rev_timebuf[2],rev_timebuf[3],\
  46.                     rev_timebuf[4],rev_timebuf[5],rev_timebuf[6]);   //更新寄存器时间

  47.       rtc1.Dis_Time();
  48.       cnt=0;
  49.     }
  50.       
  51.         }
  52. }
复制代码




RTC.H
  1. /*****************************************
  2. //
  3. //
  4. ******************************************/
  5. #ifndef _rtc_h_
  6. #define _rtc_h_
  7. /*---------------------------------------------------------------------------------------------------------*/
  8. /*  12-Hour / 24-Hour                                                                                                                          */
  9. /*---------------------------------------------------------------------------------------------------------*/
  10. #define DRVRTC_CLOCK_12                        0
  11. #define DRVRTC_CLOCK_24                        1

  12. class rtc_c: public interrupt_t {
  13. public:
  14.   rtc_c(uint32_t year =1,uint32_t month =1,uint32_t day =1,uint32_t week =0,\
  15.              uint32_t hour=0,uint32_t mintue =0,uint32_t second =0,uint8_t ClockDisplay =1);

  16.   void Rtc_Updata(uint32_t year,uint32_t month,uint32_t day,uint32_t week,\
  17.              uint32_t hour,uint32_t mintue ,uint32_t second );//更新寄存器时间

  18.   #ifdef _LCD1602_
  19.   void Dis_Time(void);
  20.   void Dis_Updata();
  21.   #endif
  22. protected:
  23.   bool isr(int vector);
  24.   void dsr(int vector,uintptr_t count);
  25.   

  26. private:
  27.   uint32_t Rtc_Write_Enable();
  28.   int8_t last_year10,last_year1;
  29.   int8_t last_month10,last_month1;
  30.   int8_t last_day10,last_day1;
  31.   int8_t last_hour10,last_hour1;
  32.   int8_t last_mintue10,last_mintue1;
  33.   int8_t last_second10,last_second1;
  34.   int8_t last_week;

  35. };
  36. #endif
复制代码




RTC.CPP
  1. /*****************************************
  2. //
  3. //
  4. ******************************************/
  5. #include <NUC1xx.h>
  6. #include"NUC1xxM051Seriescfg.h"
  7. #include"main.h"
  8. #include"rtc.h"

  9. /********************************************************************************
  10. //RTC的构造函数
  11. //参数:年、月、日、星期、时、分、秒、12或24显示
  12. //      要确保年月日时分秒为BCD码
  13. ********************************************************************************/
  14. rtc_c::rtc_c(uint32_t year,uint32_t month,uint32_t day,uint32_t week,\
  15.              uint32_t hour,uint32_t mintue,uint32_t second,uint8_t ClockDisplay)
  16. {
  17.   uint32_t write_enable=0,timer_buf=0;;
  18.   
  19.   RTCs.INIR.Regs=0xa5eb1357; //唤醒RTC
  20.   for(uint8_t i=0;i<200;i++)
  21.   {
  22.     if(RTCs.INIR.Bits.Bit0==1) //判断是否正常运行
  23.     {
  24.       break;
  25.     }
  26.   }

  27.   write_enable=Rtc_Write_Enable();//15MS之后自动关闭
  28.   if(write_enable)//判断是否写打开
  29.   {
  30.     RTCs.TSSR.Bits.HR24= ClockDisplay;//
  31.     //写时分秒
  32.     Rtc_Write_Enable();
  33.     timer_buf=(hour<<16)|(mintue<<8)|(second);
  34.     RTCs.TLR.Regs=timer_buf;
  35.     //写年月日
  36.     Rtc_Write_Enable();
  37.     timer_buf=(year<<16)|(month<<8)|(day);
  38.     RTCs.CLR.Regs=timer_buf;
  39.     //写星期
  40.     Rtc_Write_Enable();
  41.     RTCs.DWR.Bits.DWR=week;

  42. //   RTCs.TTR.Bits.TTR=0;//1s产生中断
  43. //   RTCs.RIER.Bits.TIER=1;//使能节拍中断
  44.    
  45.     attach(RTC_IRQn);
  46.     vector_t::enable(RTC_IRQn);
  47.   }
  48.   //将时间更新后,存起来,用来刷新判断用
  49.   last_year10=year>>4;
  50.   last_year1=year&0x0f;
  51.   last_month10=month>>4;
  52.   last_month1=month&0x0f;
  53.   last_day10=day>>4;
  54.   last_day1=day&0x0f;
  55.   last_hour10=hour>>4;
  56.   last_hour1=hour&0x0f;
  57.   last_mintue10=mintue>>4;
  58.   last_mintue1=mintue&0x0f;
  59.   last_second10=second>>4;
  60.   last_second1=second&0x0f;
  61.   last_week=week;

  62. }

  63. void rtc_c::Rtc_Updata(uint32_t year,uint32_t month,uint32_t day,uint32_t week,\
  64.              uint32_t hour,uint32_t mintue ,uint32_t second )
  65. {
  66.   uint32_t timer_buf=0;

  67.     //写时分秒
  68.   Rtc_Write_Enable();
  69.   timer_buf=(hour<<16)|(mintue<<8)|(second);
  70.   RTCs.TLR.Regs=timer_buf;
  71.     //写年月日
  72.   Rtc_Write_Enable();
  73.   timer_buf=(year<<16)|(month<<8)|(day);
  74.   RTCs.CLR.Regs=timer_buf;
  75.     //写星期
  76.   Rtc_Write_Enable();
  77.   RTCs.DWR.Bits.DWR=week;

  78.   //将时间更新后,存起来,用来刷新判断用
  79.   last_year10=year>>4;
  80.   last_year1=year&0x0f;
  81.   last_month10=month>>4;
  82.   last_month1=month&0x0f;
  83.   last_day10=day>>4;
  84.   last_day1=day&0x0f;
  85.   last_hour10=hour>>4;
  86.   last_hour1=hour&0x0f;
  87.   last_mintue10=mintue>>4;
  88.   last_mintue1=mintue&0x0f;
  89.   last_second10=second>>4;
  90.   last_second1=second&0x0f;
  91.   last_week=week;        
  92.   
  93.       
  94. }

  95. //使能RTC写寄存器
  96. uint32_t rtc_c::Rtc_Write_Enable()
  97. {
  98.   uint8_t i=0;
  99.   RTCs.AER.Bits.AER=0xA965;

  100.   for(i=0;i<100;i++)
  101.   {
  102.     if(RTCs.AER.Bits.ENF==1)
  103.     {
  104.       break;
  105.     }
  106.     RTCs.AER.Bits.AER=0xA965;
  107.   }

  108.   if(i==100)
  109.   {
  110.     return 0;
  111.   }

  112.   return 1;
  113. }#ifdef _LCD1602_void rtc_c::Dis_Time(void){  int8_t x=10,y=1;  lcd1.Lcd_WByte(x--,y,(last_second1+0x30));  lcd1.Lcd_WByte(x--,y,(last_second10+0x30));  lcd1.Lcd_WByte(x--,y,':');  lcd1.Lcd_WByte(x--,y,(last_mintue1+0x30));  lcd1.Lcd_WByte(x--,y,(last_mintue10+0x30));  lcd1.Lcd_WByte(x--,y,':');  lcd1.Lcd_WByte(x--,y,(last_hour1+0x30));  lcd1.Lcd_WByte(x--,y,(last_hour10+0x30));
  114.   x=12;y=0;  lcd1.Lcd_WByte(x--,y,(last_day1+0x30));  lcd1.Lcd_WByte(x--,y,(last_day10+0x30));  lcd1.Lcd_WByte(x--,y,' ');  lcd1.Lcd_WByte(x--,y,(last_month1+0x30));  lcd1.Lcd_WByte(x--,y,(last_month10+0x30));  lcd1.Lcd_WByte(x--,y,' ');  lcd1.Lcd_WByte(x--,y,(last_year1+0x30));  lcd1.Lcd_WByte(x--,y,(last_year10+0x30));  lcd1.Lcd_WByte(x--,y,'0');  lcd1.Lcd_WByte(x--,y,'2');
  115. }
  116. void rtc_c::Dis_Updata() //更新时间{  uint32_t u32timebuf=0;  char time_array[10]={0};
  117.   #ifdef _LCD1602_  int8_t x=10,y=1;  #endif
  118.   u32timebuf=RTCs.TLR.Regs;//时分秒  if((u32timebuf&0x0f)!=last_second1) //time updata  {    last_second1=u32timebuf&0x0f;    #ifdef _LCD1602_    lcd1.Lcd_WByte(x--,y,(last_second1+0x30));    #endif    if(((u32timebuf>>4)&0x0f)!=last_second10) //sec    {      last_second10=(u32timebuf>>4)&0x0f;      #ifdef _LCD1602_      lcd1.Lcd_WByte(x--,y,(last_second10+0x30));      lcd1.Lcd_WByte(x--,y,':');      #endif      if(((u32timebuf>>8)&0x0f)!=last_mintue1) //mintue      {        last_mintue1=(u32timebuf>>8)&0x0f;
  119.         #ifdef _LCD1602_        lcd1.Lcd_WByte(x--,y,(last_mintue1+0x30));        #endif
  120.         if(((u32timebuf>>12)&0x0f)!=last_mintue10)        {          last_mintue10=(u32timebuf>>12)&0x0f;
  121.           #ifdef _LCD1602_          lcd1.Lcd_WByte(x--,y,(last_mintue10+0x30));          lcd1.Lcd_WByte(x--,y,':');          #endif
  122.           if(((u32timebuf>>16)&0x0f)!=last_hour1)   //hour          {            last_hour1=(u32timebuf>>16)&0x0f;
  123.             #ifdef _LCD1602_            lcd1.Lcd_WByte(x--,y,(last_hour1+0x30));            #endif
  124.             if((u32timebuf>>20)!=last_hour10)            {              last_hour10=u32timebuf>>20;
  125.               #ifdef _LCD1602_              lcd1.Lcd_WByte(x--,y,(last_hour10+0x30));              #endif            }           }         }      }    }     //当时间改变时通过串口查看    time_array[0]=last_hour10+0x30;    time_array[1]=last_hour1+0x30;    time_array[2]=':';    time_array[3]=last_mintue10+0x30;    time_array[4]=last_mintue1+0x30;    time_array[5]=':';    time_array[6]=last_second10+0x30;    time_array[7]=last_second1+0x30;    time_array[8]='\0';    uart0.Wstr(time_array);     uart0.Wstr("     ");           }    u32timebuf=RTCs.CLR.Regs;//年月日  x=12;y=0;  if((u32timebuf&0x0f)!=last_day1) //time updata  {    last_day1=u32timebuf&0x0f;    #ifdef _LCD1602_    lcd1.Lcd_WByte(x--,y,(last_day1+0x30));    #endif    if(((u32timebuf>>4)&0x0f)!=last_day10) //day    {      last_day10=(u32timebuf>>4)&0x0f;      #ifdef _LCD1602_      lcd1.Lcd_WByte(x--,y,(last_day10+0x30));      lcd1.Lcd_WByte(x--,y,' ');      #endif      if(((u32timebuf>>8)&0x0f)!=last_month1) //month      {        last_month1=(u32timebuf>>8)&0x0f;
  126.         #ifdef _LCD1602_        lcd1.Lcd_WByte(x--,y,(last_month1+0x30));        #endif
  127.         if(((u32timebuf>>12)&0x0f)!=last_month10)        {          last_month10=(u32timebuf>>12)&0x0f;
  128.           #ifdef _LCD1602_          lcd1.Lcd_WByte(x--,y,(last_month10+0x30));          lcd1.Lcd_WByte(x--,y,':');          #endif
  129.           if(((u32timebuf>>16)&0x0f)!=last_year1)   //year          {            last_year1=(u32timebuf>>16)&0x0f;
  130.             #ifdef _LCD1602_            lcd1.Lcd_WByte(x--,y,(last_year1+0x30));            #endif
  131.             if((u32timebuf>>20)!=last_year10)            {              last_year10=u32timebuf>>20;
  132.               #ifdef _LCD1602_              lcd1.Lcd_WByte(x--,y,(last_year10+0x30));              lcd1.Lcd_WByte(x--,y,'0');              lcd1.Lcd_WByte(x--,y,'2');              #endif            }           }         }      }    }   }}#endif
复制代码



好了,串口发送命令没什么格式只要按照BCD码并根据【年/月/日/星期/时/分/秒】的顺序发送7个字节数据,中间不能有0,要想有零只能用偏移方式,像我这串:11 10 05 03 17 20 12(HEX格式)代表2011年10月05号 星期三 17点20分12秒

希望大家一起交流,还有点问题想问老师,mmbox邮箱是不是只能通过get来一条条读消息,能不能实现清空邮箱,不然数据格式出现错误那么以后发的也就会出现错误,只能复位,本来任务中想连续读取消息的,不过感觉用for怪怪的就用来现在这个,用一个计数变量来计数,反正这次程序写的有点怪:dizzy:,不过功能倒是能瞎玩玩了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
hotpower 发表于 2011-10-5 20:12 | 显示全部楼层
用cpp还是感觉好。
 楼主| nixianmin 发表于 2011-10-5 20:30 | 显示全部楼层
2# hotpower 写起来感觉确实不错,LOOK也不错,不过LOOK类的一些功能觉得不完整,像邮箱是不是要带个在一些情况下清空邮箱的功能呢。下面得多看看别人用CPP写程序的例子,学学经验和写法,还有嵌入式系统,学习下实现的具体编码
gagmeng 发表于 2011-10-7 08:04 | 显示全部楼层
绝对好帖,有时间也研究下LOOK
weshiluwei6 发表于 2011-10-10 20:21 | 显示全部楼层
bucuo 楼主很有实力啊
zhaor 发表于 2011-10-19 21:41 | 显示全部楼层
串口和RTC的确有冲突。我怎么也搞不好!
 楼主| nixianmin 发表于 2011-10-20 10:16 | 显示全部楼层
没什么冲突啊,注意串口数据的格式,和处理方式,最近忙着玩新手机了,好久没写了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:电机控制,TI InstaSpin Foc交流群:335663930

40

主题

431

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部