目录
自己实现有问题的部分:
①跑马管(左到右依次点亮数码管的所有段码(怎么实现数码管全亮?),再依次从左? 到右熄灭)
②独立按键:按下按键,灯没反应、数码管暂停?(松开正常)
③串口(没写)
代码(除去串口):
设计程序,用于本地和远程控制现场灯光的开关,并能通过串口远程读取工厂的系统运行时间。
①设计系统初始化函数,关闭蜂鸣器和继电器等无关设备。
②设计设备检测函数,首先检测LED指示灯,从L1~L8依次逐个点亮,再依次逐个熄灭;然后检查数码管,从左到右依次点亮数码管的所有段码,再依次从左到右熄灭。
③系统从上电开始显示系统运行时间,从00时00分00秒开始,显示格式:
④八个LED指示灯分为2组:L1~L4为远程控制组,L7~L8为本地控制组。
? ? 远程控制组的指示灯由上位机通过串口发送命令控制开关,本地控制组的指示灯由独立按? ? ? 键控制开关。按键检测需做去抖动处理,松开有效,按键S5控制L7,按键S4控制L8。
??
0000 0001? ?
0000 0011
0000 0111
自己实现有问题的部分:
①跑马管(左到右依次点亮数码管的所有段码(怎么实现数码管全亮?),再依次从左? 到右熄灭)
②独立按键:按下按键,灯没反应、数码管暂停?(松开正常)
P0口是复用的,即用P0口控制灯光,又用P0口控制数码管,而P0口在不断更新数码管状态
将LED当前状态读取出来,
③串口(没写)
代码(除去串口):
#include "reg52.h"
sfr AUXR = 0x8e;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
sbit L6 = P0^5;
sbit L7 = P0^6;
sbit L8 = P0^7;
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned char code SMG_duanma[18] = {
// 0 1 2 3 4 5 6 7
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
// 8 9 A10 B11 C12 D13 E14 F15
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
// -16 .17
0xbf,0x7f}; //共阳数码管
unsigned char stat_led = 0xff;//定义LED灯当前开关状态(全灭)
void InitHC138(unsigned char n)//选Y
{
switch(n)
{
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;
}
}
//*****①系统初始化函数,关闭蜂鸣器和继电器等无关设备******************
void InitSystem()
{
InitHC138(5);
P0 = 0x00;//关闭蜂鸣器和继电器
InitHC138(4);
P0 = stat_led;//***保存LED初始状态***
InitHC138(0);
}
//******************************************************************
//*****②设备检测****************************************************
void Delay(unsigned int t)
{
while(t--);
while(t--);
}
void CheckLED()
{
//检测LED指示灯,从L1~L8依次逐个点亮,再依次逐个熄灭
unsigned char i;
InitHC138(4);
for (i = 1; i <= 8; i++)
{
P0 = 0xff << i;
Delay(60000);
}
for (i = 1; i <= 8; i++)
{
P0 = ~(0xff << i);
Delay(60000);
}
}
void CheckSMG()
{
//检查数码管,从左到右依次点亮数码管的所有段码,再依次从左到右熄灭
unsigned char i;
InitHC138(7);
P0 = 0x00; //点亮数码管的所有段码
for (i = 0; i < 8; i++)
{
InitHC138(6);
P0 = ~(0xfe << i);//逐个点亮数码管(熄灭取反)
Delay(60000);
}
for (i = 0; i < 8; i++)
{
InitHC138(6);
P0 = 0xfe << i; //逐个熄灭数码管 1111 1110
Delay(60000);
}
InitHC138(0);
}
//******************************************************************
//*****③系统从上电开始显示系统运行时间,从00时00分00秒开始************
unsigned char count = 0;
unsigned char t_shi = 0;
unsigned char t_fen = 0;
unsigned char t_miao = 0;
void InitTimer0()//定时器0中断函数(每50ms产生一次中断)
{
TMOD = 0x01;
TH0 = (65535 - 50000) / 256;//1s = 1000ms = 100 0000us = 20*50000us
TL0 = (65535 - 50000) % 256;//每50ms产生一次中断(1s = 20*50ms)
ET0 = 1;
EA = 1;
TR0 = 1;//打开定时器
}
void ServiceTimer0() interrupt 1 //中断服务函数
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
count++;
if (count == 20)
{
t_miao++;
count = 0;
if (t_miao == 60)
{
t_fen++;
t_miao = 0;
if (t_fen == 60)
{
t_shi++;
t_fen = 0;
if (t_shi == 99)
{
t_shi = 0;
}
}
}
}
}
void SMG_bit(unsigned pos, unsigned char dat)//数码管位置、数据
{
InitHC138(6);
P0 = 0x01 << pos;
InitHC138(7);
P0 = dat;
}
void DelaySMG(unsigned char t)
{
while(t--);
}
void SystemTime()//上电开始显示系统运行时间
{
SMG_bit(0, SMG_duanma[t_shi/10]);
DelaySMG(100);
SMG_bit(1, SMG_duanma[t_shi%10]);
DelaySMG(100);
SMG_bit(2, SMG_duanma[16]);
DelaySMG(100);
SMG_bit(3, SMG_duanma[t_fen/10]);
DelaySMG(100);
SMG_bit(4, SMG_duanma[t_fen%10]);
DelaySMG(100);
SMG_bit(5, SMG_duanma[16]);
DelaySMG(100);
SMG_bit(6, SMG_duanma[t_miao/10]);
DelaySMG(100);
SMG_bit(7, SMG_duanma[t_miao%10]);
DelaySMG(100);
}
void DelayS(unsigned char t)
{
while(t--)
{
SystemTime();
}
}
//******************************************************************
//*****④八个LED分为2组:L1~L4为远程控制组,L7~L8为本地控制组**********
void InitUart()//串口中断函数
{
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
SCON = 0x50;
AUXR = 0x00;
ES = 1;
EA = 1;
}
void ServiceUart() interrupt 4 //中断服务函数
{
}
void ScanKeys()//L1~L4为远程控制组,L7~L8为本地控制组
{
//去抖动处理,松开有效
if (S5 == 0)//按键S5控制L7
{
DelaySMG(100);
if (S5 == 0)
{
while(S5 == 0) //等待按键S5松开(没有结束,不能空等待)
{
SystemTime();//等待的同时不断刷新数码管,否则数码管就会停在这里
}
InitHC138(4);
stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
P0 = stat_led;// (1111 1111 | 0100 000)&(0000 0000 | 1011 1111)
InitHC138(0); // 1011 1111 & 1011 1111 = 1011 1111(S7亮)
}
}
if (S4 == 0)//按键S4控制L8
{
DelaySMG(100);
if (S4 == 0)
{
while(S4 == 0) //等待按键S4松开(没有结束,不能空等待)
{
SystemTime();//等待的同时不断刷新数码管,否则数码管就会停在这里
}
InitHC138(4);
stat_led = (stat_led | 0x80) & (~stat_led | 0x7f);
P0 = stat_led;// (1111 1111 | 1000 000)&(0000 0000 | 0111 1111)
InitHC138(0); // 0111 1111 & 0111 1111 = 0111 1111(S8亮)
}
}
}
//******************************************************************
void main()
{
InitSystem();
CheckLED();
CheckSMG();
InitTimer0();
while(1)
{
SystemTime();
ScanKeys();
}
}
|