一、训练任务
在CT107D单片机综合训练平台上,设计程序,用于本地和远程控制现场灯光的开关,并能通过串口远程读取工厂的系统运行时间。
二、训练要求
1.设计系统初始化函数,关闭蜂鸣器和继电器等无关设备。
2.设计设备检测函数,首先检测LED指示灯,从L1~L8依次逐个点亮,再依次逐个熄灭;然后检查数码管,从左到右依次点亮数码管的所有段码,再依次从左到右熄灭。
3.系统从上电开始显示系统运行时间,从00时00分00秒开始,显示格式:
4.八个LED指示灯分为2组: L1-L4为远程控制组,L7-L8为本地控制组。远程控制组的指示灯由上位机通过串口发送命令控制开关,本地控制组的指示灯由独立按键控制开关。按键检测需做去抖动处理,松开有效,按键S5控制L7,按键S4控制L8。
三、通信规约
串口工作在8位UART模式,波特率为9600BPS
上位机通过串口控制下位机的L1~L4指示灯和读取系统运行时间。
控制命令为一一个字节, 高4位为命令类型,低4位为执行参数。
控制灯光开关命令中,低4位每1位控制一个LED灯 的开关,无返回值。
读取运行时间命令中,低4位保留,各位为0,返回3个字节的时间数据,用16进制的BCD码表示,先发时,再发分,后发秒。如果系统运行的时间为12时24分16秒,收到读取时间命令字后,返回: 0x12 0x24 0x16。
代码展示
#include <reg52.h> typedef unsigned int uint; typedef unsigned char uchar; sfr AUXR = 0X8e; sbit S5 = P3^2; sbit S4 = P3^3; sbit L7 = P0^6; sbit L8 = P0^7; uchar code SMG_duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x88,0x80,0xc6,0xc0,0x86,0x8e, 0xbf,0x7f};//分别是0-9(对应下标),A-F,“-”,“.” uchar time_005s = 0; uchar time_s = 0; uchar time_m = 0; uchar time_h = 0; void SMGDisplay(); //配置HC138 void SelectHC138(uchar channel) { switch(channel) { case 4: //LED P2 = (P2 & 0X1F) | 0X80; break; case 5: //蜂鸣器和继电器 P2 = (P2 & 0X1F) | 0Xa0; break; case 6: //位码 P2 = (P2 & 0X1F) | 0Xc0; break; case 7: //段码 P2 = (P2 & 0X1F) | 0Xe0; break; case 0: //锁住所有寄存器 P2 = (P2 & 0X1F) | 0X00; break; } } //在pos位码上,显示value段码 void DisplaySMG_Bit(uchar pos, uchar value) { SelectHC138(6); P0 = 0X01 << pos; SelectHC138(7); P0 = value; } void Initsys() { SelectHC138(5); P0 = 0X00;//关闭蜂鸣器和继电器 SelectHC138(4); P0 = 0XFF;//关闭LED } void Delay_CL_CSMG(uint t) { while(t--); while(t--); } void CheckSys() { //检测LED uchar i; SelectHC138(4); for(i = 1; i <= 8; i++) { P0 = 0XFF << i; Delay_CL_CSMG(60000); Delay_CL_CSMG(60000); } for(i = 1; i <= 8; i++) { P0 = ~(0XFF << i); Delay_CL_CSMG(60000); Delay_CL_CSMG(60000); } //检测数码管 for(i = 0; i < 8; i++) { DisplaySMG_Bit(i, 0X00); Delay_CL_CSMG(60000); Delay_CL_CSMG(60000); } P0 = 0XFF; } //********************************* //本地控制 void Delay_K(uint t) { while(t--); } void LocalCheck() { SelectHC138(4); if(S4 == 0) { Delay_K(100); if(S4 == 0) { L8 = 0; } while(S4 == 0) { SMGDisplay(); } L8 = 1; } if(S5 == 0) { Delay_K(100); if(S5 == 0) { L7 = 0; } while(S5 == 0) { SMGDisplay(); } L7 = 1; } } //********************************* //********************************* //定时器 void InitTimer0() { TMOD = 0X01; TH0 = (65535 - 50000) / 256; TL0 = (65535 - 50000) % 256; ET0 = 1; EA = 1; TR0 = 1; } void ServiceTimer0() interrupt 1 { TH0 = (65535 - 50000) / 256; TL0 = (65535 - 50000) % 256; time_005s++; if(time_005s == 20) { time_005s = 0; time_s++; if(time_s == 60) { time_s = 0; time_m++; } if(time_m == 60) { time_m = 0; time_h++; } if(time_h == 99) { time_h = 0; } } } //********************************* //数码管显示 void Delay_SMG(uint t) { while(t--); } void SMGDisplay() { DisplaySMG_Bit(0, SMG_duanma[time_h / 10]); Delay_SMG(500); DisplaySMG_Bit(1, SMG_duanma[time_h % 10]); Delay_SMG(500); DisplaySMG_Bit(2, SMG_duanma[16]); Delay_SMG(500); DisplaySMG_Bit(3, SMG_duanma[time_m / 10]); Delay_SMG(500); DisplaySMG_Bit(4, SMG_duanma[time_m % 10]); Delay_SMG(500); DisplaySMG_Bit(5, SMG_duanma[16]); Delay_SMG(500); DisplaySMG_Bit(6, SMG_duanma[time_s / 10]); Delay_SMG(500); DisplaySMG_Bit(7, SMG_duanma[time_s % 10]); Delay_SMG(500); P0 = 0XFF; } //************************************ //串口通信 uchar command = 0; void InitUart() { TMOD = 0X20; TH1 = 0XFD; TL1 = 0XFD; TR1 = 1; SCON = 0X50; //模式1 AUXR = 0X00; ES = 1; EA = 1; } void ServiceUart() interrupt 4 { if(RI == 1) { command = SBUF; RI = 0; } } void SendByteUart(uchar dat) { SBUF = dat; while(TI == 0); TI = 0; } void UartWorking() { if(command != 0) { SelectHC138(4); switch(command & 0XF0) { case 0xA0: P0 = (P0 | 0X0F) & (~command | 0XF0); //保留高4位,反转低四位 command = 0X00; break; case 0xB0: SendByteUart((time_h / 10 << 4) | (time_h % 10)); SendByteUart((time_m / 10 << 4) | (time_m % 10)); SendByteUart((time_s / 10 << 4) | (time_s % 10)); command = 0X00; break; } } } //************************************ void main() { Initsys(); CheckSys(); InitTimer0(); InitUart(); InitUart(); while(1) { LocalCheck(); SMGDisplay(); UartWorking(); } }