- #include
-
- sfr AUXR = 0x8e; //定义辅助寄存器
-
- sbit S5 = P3^2; //定义S5按键引脚
- sbit S4 = P3^3; //定义S4按键引脚
-
- unsigned char led_stat = 0xff; //定义LED当前状态
- unsigned char count = 0; //定义50ms定时中断累计变量
- unsigned char t_h = 0; //定义运行时间的时变量
- unsigned char t_m = 0; //定义运行时间的分变量
- unsigned char t_s = 0; //定义运行时间的秒变量
- unsigned char command = 0; //定义串口命令字接受变量
-
- //========共阳极数码管的段码表============
- unsigned char code SMG_duanma[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
- 0x82,0xf8,0x80,0x90,0x88,0x80,
- 0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
- //=======================================
-
- //============锁存器选择函数==============
- /**
- * @brief 选择要打通的锁存器
- * @param channel——要选择的通道
- * @retval 无
- **/
- void SelectHC573(unsigned char channel)
- {
- switch(channel)
- {
- case 4:
- 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;
- }
- }
- //=======================================
-
- //=================延时函数==============
- /**
- * @brief 延时
- * @param t--延时长度
- * @retval 无
- **/
- void Delay(unsigned int t)
- {
- while(t--);
- }
- //=======================================
-
- //===========系统初始化函数==============
- /**
- * @brief 将蜂鸣器、继电器等无关设备关闭
- * @param 无
- * @retval 无
- **/
- void InitSystem()
- {
- SelectHC573(5);
- P0 = 0x00;
- SelectHC573(4);
- P0 = led_stat;
- SelectHC573(0);
- }
- //=======================================
-
- //===========设备检测函数================
- /**
- * @brief 逐个检测工厂灯光的工作状态
- * @param 无
- * @retval 无
- **/
- void CheckLED()
- {
- unsigned int i;
- SelectHC573(4);
- for(i = 0;i < 8; i++)
- {
- led_stat = 0xfe << i;
- P0 = led_stat;
- Delay(60000);
- Delay(60000);
- }
- for(i = 0;i < 8; i++)
- {
- led_stat = ~(0xfe << i);
- P0 = led_stat;
- Delay(60000);
- Delay(60000);
- }
- }
-
- /**
- * @brief 逐个检测数码管的工作状态
- * @param 无
- * @retval 无
- **/
- void CheckSMG()
- {
- unsigned int i;
- for(i = 0;i < 8; i++)
- {
- SelectHC573(6);
- P0 = ~(0xfe << i);
- SelectHC573(7);
- P0 = 0x00;
- Delay(60000);
- Delay(60000);
- }
- for(i = 0;i < 8; i++)
- {
- SelectHC573(6);
- P0 = 0xfe << i;
- SelectHC573(7);
- P0 = 0x00;
- Delay(60000);
- Delay(60000);
- }
- SelectHC573(0);
- }
- //=======================================
-
- //=========数码管显示函数================
- /**
- * @brief 在数码管指定位置上显示指定内容
- * @param pos——数码管选位
- value——数码管显示内容
- * @retval 无
- **/
- void DisplaySMG(unsigned char pos,unsigned char value)
- {
- P0 = 0xff;
- SelectHC573(6);
- P0 = 0x01 << pos;
- SelectHC573(7);
- P0 = value;
- }
-
- /**
- * @brief 在数码管上显示系统运行时间
- * @param 无
- * @retval 无
- **/
- void DisplayTime()
- {
- DisplaySMG(7,SMG_duanma[t_s % 10]); //秒的个位
- Delay(500);
- DisplaySMG(6,SMG_duanma[t_s / 10]); //秒的十位
- Delay(500);
- DisplaySMG(5,SMG_duanma[16]); //分隔符
- Delay(500);
-
- DisplaySMG(4,SMG_duanma[t_m % 10]); //分的个位
- Delay(500);
- DisplaySMG(3,SMG_duanma[t_m / 10]); //分的十位
- Delay(500);
- DisplaySMG(2,SMG_duanma[16]); //分隔符
- Delay(500);
-
- DisplaySMG(1,SMG_duanma[t_h % 10]); //时的个位
- Delay(500);
- DisplaySMG(0,SMG_duanma[t_h / 10]); //时的十位
- Delay(500);
- }
- //=======================================
-
- //===========定时器函数==================
- /**
- * @brief 将定时器T0设置为16位模式,计数初值为50ms
- * @param 无
- * @retval 无
- **/
- void InitTimer0()
- {
- TMOD = 0x21; //T0和T1定时器工作模式同时赋值
- TH0 = (65535 - 50000) / 256;
- TL0 = (65535 - 50000) % 256;
-
- ET0 = 1; //使能定时器T0
- EA = 1; //使能总中断
- TR0 = 1; //启动定时器T0
- }
-
- /**
- * @brief 进行系统运行时间的处理
- * @param 无
- * @retval 无
- **/
- void Timer0() interrupt 1
- {
- TH0 = (65535 - 50000) / 256;
- TL0 = (65535 - 50000) % 256;
- count ++;
- if(count == 20)
- {
- count = 0;
- t_s ++;
- }
- if(t_s == 60)
- {
- t_s = 0;
- t_m ++;
- if(t_m == 60)
- {
- t_m = 0;
- t_h++;
- }
- }
- }
- //=======================================
-
- //==============串口函数=================
- /**
- * @brief 将串口初始化为模式一,波特率为9600,允许接收
- * @param 无
- * @retval 无
- **/
- void InitUart()
- {
- TMOD = 0x21; //T0和T1定时器工作模式同时赋值
- TH1 = 0xfd; //设置9600波特率的参数
- TL1 = 0xfd;
- TR1 = 1; //启动定时器T1
-
- SCON = 0x50; //8为UART模式,允许接收
- AUXR = 0x00; //辅助寄存器设置
- ES = 1; //使能串口中断
- EA = 1; //使能总中断
- }
-
- /**
- * @brief 接收上位机的数据并保存在command变量中
- * @param 无
- * @retval 无
- **/
- void Uart() interrupt 4
- {
- if(RI == 1)
- {
- command = SBUF; //将接收到的数据保存到command中
- RI = 0; //接收完成后,将接收标志位RI清0
- }
- }
-
- /**
- * @brief 串口给上位机发送一个字节
- * @param dat——串口发送的内容
- * @retval 无
- **/
- void SendByte(unsigned char dat)
- {
- SBUF = dat; //把dat中的内容发送给上位机
- while(TI == 0);
- TI = 0; //发送完成后,将发送标志位RI清0
- }
- //=======================================
-
- //========上位机命令解析执行函数=========
- /**
- * @brief 接收上位机的数据并保存在command变量中
- * @param 无
- * @retval 无
- **/
- void ExecuteCommand()
- {
- if(command != 0x00) //接收到上位机命令
- {
- switch(command & 0xf0) //将命令类型取出来
- {
- case 0xa0: //远程控制灯光
- SelectHC573(4);
- led_stat = (led_stat | 0x0f) & (~command | 0xf0);
- P0 = led_stat;
- SelectHC573(0);
- command = 0x00;
- break;
- case 0xb0: //读取现场系统运行时间
- SendByte((t_h / 10 << 4) | (t_h % 10));
- SendByte((t_m / 10 << 4) | (t_m % 10));
- SendByte((t_s / 10 << 4) | (t_s % 10));
- command = 0x00;
- break;
- }
- }
- }
- //=======================================
-
- //==========按键扫描函数=================
- /**
- * @brief 扫描S4与S5按键并执行现场灯光控制
- * @param 无
- * @retval 无
- **/
- void ScanKeys()
- {
- if(S4 == 0)
- {
- Delay(500); //按键消抖
- if(S4 == 0) //确认按键按下
- {
- while(S4 == 0) //等待按键松开
- {
- DisplayTime();
- }
- SelectHC573(4);
- led_stat = (led_stat | 0x80) & (~led_stat | 0x7f);
- P0 = led_stat; //执行现场灯光控制
- SelectHC573(0);
- }
- }
- if(S5 == 0)
- {
- Delay(500); //按键消抖
- if(S5 == 0) //确认按键按下
- {
- while(S5 == 0) //等待按键松开
- {
- DisplayTime();
- }
- SelectHC573(4);
- led_stat = (led_stat | 0x40) & (~led_stat | 0xbf);
- P0 = led_stat; //执行现场灯光控制
- SelectHC573(0);
- }
- }
- }
- //=======================================
-
- //===============主函数==================
- void main()
- {
- InitSystem();
- CheckLED();
- CheckSMG();
- InitTimer0();
- InitUart();
- while(1)
- {
- ExecuteCommand();
- DisplayTime();
- ScanKeys();
- }
- }
- //=======================================