本帖最后由 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[12] ; //rtc时间数据
- bit Rec_OK = 0; //rtc时间获取完成标志
复制代码
在添加几个关键的变量,用来保存和记录当前的串口数据
- void UART1_int (void) interrupt 4
- {
- u8 dat;
- if(RI)
- {
- RI = 0;
- <font color="#ff0000"> dat = SBUF;</font>
- // RX1_Buffer[RX1_Cnt] = 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[length-1]=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[indexrtc] == '\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[TX1_Cnt];
- // B_TX1_Busy = 1;
- // if(++TX1_Cnt >= UART1_BUF_LENGTH) TX1_Cnt = 0;
- // }
- if( Rec_OK==1 )
- {
- <font color="#00ff00">// INIYEAR = rtctime[1]; //Y:2021 //单片机内部rtc时钟初始化的办法
- // INIMONTH = rtctime[2]; //M:12
- // INIDAY = rtctime[3]; //D:31
- // INIHOUR = rtctime[5]; //H:23
- // INIMIN =rtctime[6]; //M:59
- // INISEC = rtctime[7]; //S:50
- // INISSEC = rtctime[8]; //S/128:0
- // RTCCFG |= 0x01; //触发RTC寄存器初始化</font>
-
- Rec_OK = 0;
- printf("%02d%02d年%d月%d日\t",(int)rtctime[0],(int)rtctime[1],(int)rtctime[2],(int)rtctime[3]);
- printf("%d:%d:%d.%d\t",(int)rtctime[5],(int)rtctime[6],(int)rtctime[7],(int)((u16)(rtctime[9]*256)|(u8)rtctime[10]));
- printf("%d\r\n",(int)rtctime[8]);
-
- }
- }
复制代码
最后实物演示:
因为这里为了最快的验证,直接用串口模拟了我们下发的命令,这样我们就可以用串口直接获取到接收到的命令了,因为下发的命令和串口模拟的命令格式是一样的,这里这样测试比较方便,可以看到下发的事件数据就是:
40 53 54 43 52 54 43 23 14 17 05 04 04 09 24 13 03 01 F8
这串命令的时间我们刚刚解析过了,可以看到串口发出来的数据和我们解析的时间是一样的,然后就可以把这些关键数据写入能掉电走时的设备里了。
所以这个就没有问题了!是不是使用起来非常简单,祝大家使用愉快!
|