本帖最后由 _行者_ 于 2019-1-3 00:22 编辑
这次试用串口更新数码管时钟功能。
时钟使用单片机内部定时器作为时钟基础,然后用 8 位数码管显示;再用串口与电脑通信,串口获取到的时间传给单片机,再通过8位数码管显示
程序可以拆分为三个部分:1、数码管扫描部分 2、时钟处理部分 3、串口通讯部分。
1.数码管扫描部分
采用的是2片74HC573控制8位数码管
74HC573 是锁存器,在扩展RAM或者ROM时候常用。从上述电路图看芯片的结构,左边8 位是输入信号,右边8 位是输出信号,还有1 根控制信号。如果芯片处于直通状态,右边的输出信号等于左边的输入信号,是实时变化的,相当于没有这个芯片,线路直接短接。如果提供锁存信号,右边的输出信号就不会改变了,一直持续锁存之前的信号,不管输入信号如何变化,输出都不变,利用这种特性,可以让端口复用,比如端口通过锁存器连接8 位LED,然后直接连接另外8 个LED,再通过1 条控制线控制锁存输出,这样只用9 根线就可以控制16 位LED。
// 数据处理,把需要处理的byte数据写到对应的引脚端口。
void deal(unsigned char value){
for(int i=0;i<8;i++)
digitalWrite(ledPins,bitRead(value,i));
// !bitRead(value,i),这里前面加!(非运算符号),取决于使用的是共阴还是共阳数码管。
}
2.串口通信部分
使用自带的库函数
if (Serial.available()) {
Serial.readBytes(serialtmp,16);
hour= (serialtmp[8]-'0')*10+(serialtmp[9]-'0');
minute= (serialtmp[10]-'0')*10+(serialtmp[11]-'0');
second= (serialtmp[12]-'0')*10+(serialtmp[13]-'0');
}
3.时钟处理部分
这一步主要是时间的换算,年月日时分秒的处理
if (millis() - lastTime >= 1000) {
lastTime = millis();
second++;
}
if (second > 59) {
minute++;
second = 0; // reset seconds to zero
}
// move forward one hour every 60 minutes
if (minute > 59) {
hour++;
minute = 0; // reset minutes to zero
}
// move forward one weekday every 24 hours
if (hour > 23) {
weekday++;
hour = 0; // reset hours to zero
}
// reset weekdays on Saturday
if (weekday > 7) {
weekday = 1;
}
displayTemp[0]=dofly_DuanMa[hour/10];
displayTemp[1]=dofly_DuanMa[hour%10];
displayTemp[2]=0x40;
displayTemp[3]=dofly_DuanMa[minute/10];
displayTemp[4]=dofly_DuanMa[minute%10];
displayTemp[5]=0x40;
displayTemp[6]=dofly_DuanMa[second/10];
displayTemp[7]=dofly_DuanMa[second%10];
看一下接线图
然后,打开串口调试助手,输入一个指定的时间。
最后,就能够在数码管上实时显示出来
使用串口更新时间就完成了,当然也可以用串口显示出其他的图案或文字。