打印
[LOOK]

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

[复制链接]
3024|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nixianmin|  楼主 | 2011-10-5 17:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
国庆过的差不多,今天发个基于LOOK的RTC程序,其实也没什么东西,就是写了个RTC类,并能在1602上显示年月日时分秒,能通过串口发送时分秒(每秒发一次),还能通过串口来修改RTC的时间。如果没有1602也能通过串口看到RTC的效果,就是和1602比少显示了年月日。

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


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

  #ifdef _LCD1602_
  int8_t x=10,y=1;
  #endif

  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;

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

        if(((u32timebuf>>12)&0x0f)!=last_mintue10)
        {
          last_mintue10=(u32timebuf>>12)&0x0f;

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

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

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

            if((u32timebuf>>20)!=last_hour10)
            {
              last_hour10=u32timebuf>>20;

              #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;

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

        if(((u32timebuf>>12)&0x0f)!=last_month10)
        {
          last_month10=(u32timebuf>>12)&0x0f;

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

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

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

            if((u32timebuf>>20)!=last_year10)
            {
              last_year10=u32timebuf>>20;

              #ifdef _LCD1602_
              lcd1.Lcd_WByte(x--,y,(last_year10+0x30));
              lcd1.Lcd_WByte(x--,y,'0');
              lcd1.Lcd_WByte(x--,y,'2');
              #endif
            }
          }
        }
      }
    }
  }
}




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

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

#ifdef LOOK_SCHEDULING_PRIORITY
instantiate::task<task1_main_t, LOOK_STACK_SIZE> task1_main(0);
instantiate::task<task2_uart0_c,LOOK_STACK_SIZE> task2_uart0(1);
#else
instantiate::task<task1_main_t, LOOK_STACK_SIZE> task1_main;
instantiate::task<task2_uart0_c,LOOK_STACK_SIZE> task2_uart0;
#endif


/*************************************
//task1任务类的任务函数
**************************************/
void task1_main_t::routine()
{
        #ifdef _LCD1602_ //初始化1602显示
  rtc1.Dis_Time();
  #endif
        // TODO: 在此编写 task1_main_t 例程的内容
        while (true) {
                 rtc1.Dis_Updata();  //更新RTC时间
     cnt=0;
     scheduler.yield();
                // TODO: 在此编写 task1_main_t 例程的内容
        }
}

/***************************************
//
***************************************/
void task2_uart0_c::routine()
{
  uint32_t rev_timebuf[7]={0};
  
  uart0.Uart0RxEnableInt();//接收中断使能
        while(true){
    rev_timebuf[cnt++]=task2_megs.get();

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

      rtc1.Dis_Time();
      cnt=0;
    }
      
        }
}




RTC.H
/*****************************************
//
//
******************************************/
#ifndef _rtc_h_
#define _rtc_h_
/*---------------------------------------------------------------------------------------------------------*/
/*  12-Hour / 24-Hour                                                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
#define DRVRTC_CLOCK_12                        0
#define DRVRTC_CLOCK_24                        1

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

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

  #ifdef _LCD1602_
  void Dis_Time(void);
  void Dis_Updata();
  #endif
protected:
  bool isr(int vector);
  void dsr(int vector,uintptr_t count);
  

private:
  uint32_t Rtc_Write_Enable();
  int8_t last_year10,last_year1;
  int8_t last_month10,last_month1;
  int8_t last_day10,last_day1;
  int8_t last_hour10,last_hour1;
  int8_t last_mintue10,last_mintue1;
  int8_t last_second10,last_second1;
  int8_t last_week;

};
#endif




RTC.CPP
/*****************************************
//
//
******************************************/
#include <NUC1xx.h>
#include"NUC1xxM051Seriescfg.h"
#include"main.h"
#include"rtc.h"

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

  write_enable=Rtc_Write_Enable();//15MS之后自动关闭
  if(write_enable)//判断是否写打开
  {
    RTCs.TSSR.Bits.HR24= ClockDisplay;//
    //写时分秒
    Rtc_Write_Enable();
    timer_buf=(hour<<16)|(mintue<<8)|(second);
    RTCs.TLR.Regs=timer_buf;
    //写年月日
    Rtc_Write_Enable();
    timer_buf=(year<<16)|(month<<8)|(day);
    RTCs.CLR.Regs=timer_buf;
    //写星期
    Rtc_Write_Enable();
    RTCs.DWR.Bits.DWR=week;

//   RTCs.TTR.Bits.TTR=0;//1s产生中断
//   RTCs.RIER.Bits.TIER=1;//使能节拍中断
   
    attach(RTC_IRQn);
    vector_t::enable(RTC_IRQn);
  }
  //将时间更新后,存起来,用来刷新判断用
  last_year10=year>>4;
  last_year1=year&0x0f;
  last_month10=month>>4;
  last_month1=month&0x0f;
  last_day10=day>>4;
  last_day1=day&0x0f;
  last_hour10=hour>>4;
  last_hour1=hour&0x0f;
  last_mintue10=mintue>>4;
  last_mintue1=mintue&0x0f;
  last_second10=second>>4;
  last_second1=second&0x0f;
  last_week=week;

}

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

    //写时分秒
  Rtc_Write_Enable();
  timer_buf=(hour<<16)|(mintue<<8)|(second);
  RTCs.TLR.Regs=timer_buf;
    //写年月日
  Rtc_Write_Enable();
  timer_buf=(year<<16)|(month<<8)|(day);
  RTCs.CLR.Regs=timer_buf;
    //写星期
  Rtc_Write_Enable();
  RTCs.DWR.Bits.DWR=week;

  //将时间更新后,存起来,用来刷新判断用
  last_year10=year>>4;
  last_year1=year&0x0f;
  last_month10=month>>4;
  last_month1=month&0x0f;
  last_day10=day>>4;
  last_day1=day&0x0f;
  last_hour10=hour>>4;
  last_hour1=hour&0x0f;
  last_mintue10=mintue>>4;
  last_mintue1=mintue&0x0f;
  last_second10=second>>4;
  last_second1=second&0x0f;
  last_week=week;        
  
      
}

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

  for(i=0;i<100;i++)
  {
    if(RTCs.AER.Bits.ENF==1)
    {
      break;
    }
    RTCs.AER.Bits.AER=0xA965;
  }

  if(i==100)
  {
    return 0;
  }

  return 1;
}#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));
  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');
}
void rtc_c::Dis_Updata() //更新时间{  uint32_t u32timebuf=0;  char time_array[10]={0};
  #ifdef _LCD1602_  int8_t x=10,y=1;  #endif
  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;
        #ifdef _LCD1602_        lcd1.Lcd_WByte(x--,y,(last_mintue1+0x30));        #endif
        if(((u32timebuf>>12)&0x0f)!=last_mintue10)        {          last_mintue10=(u32timebuf>>12)&0x0f;
          #ifdef _LCD1602_          lcd1.Lcd_WByte(x--,y,(last_mintue10+0x30));          lcd1.Lcd_WByte(x--,y,':');          #endif
          if(((u32timebuf>>16)&0x0f)!=last_hour1)   //hour          {            last_hour1=(u32timebuf>>16)&0x0f;
            #ifdef _LCD1602_            lcd1.Lcd_WByte(x--,y,(last_hour1+0x30));            #endif
            if((u32timebuf>>20)!=last_hour10)            {              last_hour10=u32timebuf>>20;
              #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;
        #ifdef _LCD1602_        lcd1.Lcd_WByte(x--,y,(last_month1+0x30));        #endif
        if(((u32timebuf>>12)&0x0f)!=last_month10)        {          last_month10=(u32timebuf>>12)&0x0f;
          #ifdef _LCD1602_          lcd1.Lcd_WByte(x--,y,(last_month10+0x30));          lcd1.Lcd_WByte(x--,y,':');          #endif
          if(((u32timebuf>>16)&0x0f)!=last_year1)   //year          {            last_year1=(u32timebuf>>16)&0x0f;
            #ifdef _LCD1602_            lcd1.Lcd_WByte(x--,y,(last_year1+0x30));            #endif
            if((u32timebuf>>20)!=last_year10)            {              last_year10=u32timebuf>>20;
              #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:,不过功能倒是能瞎玩玩了

LOOK_RTC.rar

1.06 MB

相关帖子

沙发
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

使用特权

评论回复
5
weshiluwei6| | 2011-10-10 20:21 | 只看该作者
bucuo 楼主很有实力啊

使用特权

评论回复
6
zhaor| | 2011-10-19 21:41 | 只看该作者
串口和RTC的确有冲突。我怎么也搞不好!

使用特权

评论回复
7
nixianmin|  楼主 | 2011-10-20 10:16 | 只看该作者
没什么冲突啊,注意串口数据的格式,和处理方式,最近忙着玩新手机了,好久没写了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

40

主题

431

帖子

6

粉丝