电子DIY小家 发表于 2023-5-4 10:37:54

关于ISP的“RTC对时”功能详解

本帖最后由 32位8051-STCAI 于 2023-5-4 11:27 编辑


可以看到从STC-ISP V6.91N的版本开始,软件增加了RTC对时的功能,有需要做实时时钟的应用的话(手表啊,闹钟等等),这个功能就非常的实用。但是前两天看到有小伙伴这个功能还是不会用,这里发个帖子简单描述一下使用方法。



首先第一步,得了解软件上这个功能的一些注意事项:(RTC对时界面如下图所示)


1.在串口选择的那一行里,必须选择COMx的选项,用LINK1D的小伙伴一定要选择对应的串口的那一行,切勿选择LINK1的那行,否则会导致对时失败



2.软件中的串口助手那一页不能同时打开这个需要对时的串口,否则会提示串口打开失败(这里需要先把右边的串口助手里的串口先关闭)



3.RTC发送时间的命令格式不知道的话,只要鼠标左键碰着那个按钮就可以自动提示,如下图所示:



4.由于RTC对时这个是用户功能,所以单片机端需要编写用户程序才能正常的接收时间的数据!!!切记。

上面是一些基础知识,那我们现在来编写个程序演示一下,这里使用屠龙刀+LINK1D来进行试验!
1.首先在STC32G的试验箱里复制出这个文件和他对应的头文件:(当然如果使用别的单片机的话自行准备好一个串口通信的代码即可)



2.修改下这个工程的头文件路径等,然后编译通过:



3.准备编写用户代码来接收串口发过来的这个数据,先获取一下这个时间的命令是否正确,这里我喜欢给这种没有命令长度和校验和的数据加个命令头“@STCRTC#”,接收到这个命令就开始保存数据:


可以看到这里串口发出的数据是:40 53 54 43 52 54 43 23 14 17 05 04 04 09 24 13 03 01 F8
对照着我们这个命令行看一下,其中16进制数 和 内容换算对应下表

HEX数据 含义
40 53 54 43 52 54 43 23 命令头,这里就是@STCRTC#的意思

14 10进制数20

17
10进制数23,和上面的组合在一起就是2023年

05 10进制数5,代表5月

04 10进制数4,代表4日
04
10进制数4,代表星期4
09
10进制数9,代表9时
24
10进制数36,代表36分
13 10进制数19,代表19秒
03
10进制数3,代表3/128秒
01 F8
10进制数504,代表504毫秒


4.这样数据就和命令对上了,开始正式编写代码
char code *STCRTC= "@STCRTC#";//= "@STCRTC#";命令头   先添加这个命令头,串口接收到这数据就开始保存时间数据

char indexrtc=0;                  //当前的命令头索引
char length =0;                     //长度
char rtctime ;               //rtc时间数据
bitRec_OK = 0;                  //rtc时间获取完成标志在添加几个关键的变量,用来保存和记录当前的串口数据

void UART1_int (void) interrupt 4
{
    u8 dat;
    if(RI)
    {
      RI = 0;
<font color="#ff0000">      dat = SBUF;</font>
//      RX1_Buffer = SBUF;
//      if(++RX1_Cnt >= UART1_BUF_LENGTH)   RX1_Cnt = 0;
//-------------------------------串口RTC对时 -------------------------------   
<font color="#ff0000">      if( length>0 )</font>
<font color="#ff0000">      {   </font>
<font color="#ff0000">            rtctime=dat;</font>
<font color="#ff0000">            length++;</font>
<font color="#ff0000">            if( length>=12 )</font>
<font color="#ff0000">            {</font>
<font color="#ff0000">                length = 0;</font>
<font color="#ff0000">                Rec_OK = 1;</font>
<font color="#ff0000">                indexrtc=0;</font>
<font color="#ff0000">            }</font>
<font color="#ff0000">      }      </font>
<font color="#ff0000">      if (dat == STCRTC[ indexrtc])</font>
<font color="#ff0000">      {</font>
<font color="#ff0000">            indexrtc++;</font>
<font color="#ff0000">            if(STCRTC == '\0')</font>
<font color="#ff0000">            {</font>
<font color="#ff0000">                length = 1;   //开启接收</font>
<font color="#ff0000">                indexrtc=0;</font>
<font color="#ff0000">            }</font>
<font color="#ff0000">      }</font>
<font color="#ff0000">      else</font>
<font color="#ff0000">      {</font>
<font color="#ff0000">            indexrtc = 0;</font>
<font color="#ff0000">            if (dat ==STCRTC[ indexrtc])</font>
<font color="#ff0000">                indexrtc++;</font>
<font color="#ff0000">      }         </font>
<font color="#000000">    }</font>

    if(TI)
    {
      TI = 0;
      B_TX1_Busy = 0;
    }
}
在上述外部中断中添加如上红色部分的代码,就可把接收到的时间数据保存到数组里。这里需要留意一下串口初始化里的端口是不是选择在了3.0和3.1引脚,因为我现在的串口接在了这两个引脚上,所以引脚要对上。



其次为了使用printf打印出我们的时间数据进行验证,这里增加一个printf的重定向函数

char putchar(char dat)
{
      B_TX1_Busy = 1;                        //标志发送忙
      SBUF = dat;                                        //发一个字节
      while(B_TX1_Busy);      //等待发送完成
    return dat;
}   

最后在我们的while循环里编写如下代码,就可以把接收到的时间书库打印出来了,如果使用了单片机内部的RTC功能,可以使用绿色的部分直接把时间数据写入RTC的寄存器!
    while (1)
    {
//      if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy))   //收到数据, 发送空闲
//      {
//            SBUF = RX1_Buffer;
//            B_TX1_Busy = 1;
//            if(++TX1_Cnt >= UART1_BUF_LENGTH)   TX1_Cnt = 0;
//      }
      if( Rec_OK==1 )
      {
<font color="#00ff00">//            INIYEAR = rtctime;   //Y:2021            //单片机内部rtc时钟初始化的办法
//            INIMONTH = rtctime;    //M:12
//            INIDAY = rtctime;      //D:31
//            INIHOUR = rtctime;   //H:23
//            INIMIN =rtctime;      //M:59
//            INISEC = rtctime;      //S:50
//            INISSEC = rtctime;      //S/128:0
//            RTCCFG |= 0x01;   //触发RTC寄存器初始化</font>
            
            Rec_OK = 0;
            printf("%02d%02d年%d月%d日\t",(int)rtctime,(int)rtctime,(int)rtctime,(int)rtctime);
            printf("%d:%d:%d.%d\t",(int)rtctime,(int)rtctime,(int)rtctime,(int)((u16)(rtctime*256)|(u8)rtctime));
            printf("%d\r\n",(int)rtctime);
            
      }      
    }

最后实物演示:


因为这里为了最快的验证,直接用串口模拟了我们下发的命令,这样我们就可以用串口直接获取到接收到的命令了,因为下发的命令和串口模拟的命令格式是一样的,这里这样测试比较方便,可以看到下发的事件数据就是:
40 53 54 43 52 54 43 23 14 17 05 04 04 09 24 13 03 01 F8

这串命令的时间我们刚刚解析过了,可以看到串口发出来的数据和我们解析的时间是一样的,然后就可以把这些关键数据写入能掉电走时的设备里了。


所以这个就没有问题了!是不是使用起来非常简单,祝大家使用愉快!


hu_jia168 发表于 2023-5-4 10:58:25

有意思的实验

神农鼎 发表于 2023-5-5 15:43:12

冲哥威武,学习{:4_196:}

vg2023 发表于 2023-5-18 12:47:53

STC功能和应用越来越强了!谢谢!

WHX 发表于 2023-5-18 13:19:21

太厉害了,学习学习,感谢!{:4_250:}

乐此不疲 发表于 2023-6-5 20:08:20

有用的功能&详细的讲解,多谢!

windman 发表于 2023-6-27 22:16:10

楼主威武!非常感谢!如果能提供一下完整的例程供小白下载学习就更好了{:4_250:}

电子DIY小家 发表于 2023-6-28 01:49:45

windman 发表于 2023-6-27 22:16
楼主威武!非常感谢!如果能提供一下完整的例程供小白下载学习就更好了 ...

群文件自行下载哈~

jackfangxq 发表于 2024-2-15 17:03:11

非常感谢!

jackfangxq 发表于 2024-2-15 18:03:21

请帮我看看问题怎么解决?谢谢
页: [1] 2
查看完整版本: 关于ISP的“RTC对时”功能详解