一、要求
在CT107D单片机综合训练平台上,设计程序,实现实时显示开机系统运行时间和按键控制灯光。
1.设计系统初始化函数,关闭蜂鸣器和继电器等无关设备。
2.设计设备检测函数,首先检测LED灯,从L1~L8依次逐个点亮,再依次逐个熄灭;然后检查数码管,从左到右依次点亮数码管所有段码,再依次从左到右熄灭。
3.系统从上电就开始显示系统运行时间,从00时00分00秒开始,显示格式是“02-03-08”,该代表2小时3分钟8秒。
4.LED控制:S5控制L7,S4控制L8,按键松开有效。
二、程序
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
sbit s5 = P3^2;
sbit s4 = P3^3;
uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0xff};//共阳段码表
uchar state_led = 0xff; //定义LED灯当前开关状态
void delay_ms(uchar xms) //@11.0592MHz
{
uchar i,j;
while(xms)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
xms--;
}
}
//********************通道选择**************************/
void channel_select(uchar channel)
{
switch(channel)
{
case 0 :
P2 = (P2 & 0x1f) | 0x00;
break;
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;
}
}
//********************数码管每位显示函数************************/
void SMG_show_bit(uchar i,uchar num)
{
channel_select(6);
P0 = 0x01 << i;
channel_select(7);
P0 = num;
}
//***********************************时间显示*********************************/
/*
说明:“02-03-08”表示2小时3分8秒
*/
uchar h = 0,m = 0,s = 0; //定义时分秒
uchar count = 0; //计数
void timer0_init() //定时器初始化
{
TMOD = 0x21; //初始化定时器0和定时器1(定时器0用于时钟,定时器1用于串口)
TH0 = (65536 - 50000)/256; //重装初值
TL0 = (65536 - 50000)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void service_timer0() interrupt 1
{
TH0 = (65536 - 50000)/256; //重装初值
TL0 = (65536 - 50000)%256;
count++;
if(count == 20) //1秒钟
{
count = 0;
s++;
if(s == 60) //1分钟
{
s = 0;
m++;
if(m == 60) //1小时
{
m = 0;
h++;
if(h == 24) //24小时
{
h = 0;
}
}
}
}
}
void time_show() //时间显示
{
//显示秒
SMG_show_bit(6,table[s/10]);
delay_ms(2);
SMG_show_bit(7,table[s%10]);
delay_ms(2);
SMG_show_bit(5,table[16]);
delay_ms(2);
//显示分
SMG_show_bit(3,table[m/10]);
delay_ms(2);
SMG_show_bit(4,table[m%10]);
delay_ms(2);
SMG_show_bit(2,table[16]);
delay_ms(2);
//显示时
SMG_show_bit(0,table[h/10]);
delay_ms(2);
SMG_show_bit(1,table[h%10]);
delay_ms(2);
}
//*****************************按键控制LED*****************************/
/*
说明:S5控制L7,S4控制L6
*/
void key_scanf()
{
if(s5 == 0)
{
delay_ms(50);
if(s5 == 0)
{
while(s5 == 0)
{
time_show();
}
channel_select(4);
state_led = (state_led | 0x40) & (~state_led | 0xbf);
P0 = state_led;
channel_select(0);
}
}
if(s4 == 0)
{
delay_ms(50);
if(s4 == 0)
{
while(s4 == 0) //等待按键松开
{
time_show();
}
channel_select(4);
state_led = (state_led | 0x80) & (~state_led | 0x7f);
P0 = state_led;
channel_select(0);
}
}
}
//********************系统初始化***********************/
void system_init()
{
channel_select(4); //关闭LED
P0 = 0xff;
channel_select(5); //关闭蜂鸣器和继电器
P0 = 0x00;
}
//********************设备检测函数**********************/
void system_test()
{
uchar i,j;
//*******检测LED*********/
channel_select(4);
for(i = 0;i < 8;i++) //从左往右依次点亮
{
P0 = 0xfe << i;
delay_ms(100);
}
for(j = 0;j < 9;j++) //从左往右依次熄灭
{
P0 = ~(0xfe << j);
delay_ms(100);
}
//*******检测数码管**********/
for(i = 0;i < 8;i++) //从左往右依次点亮
{
channel_select(6);
P0 = ~(0xfe << i);
channel_select(7);
P0 = table[8];
delay_ms(100);
}
for(j = 0;j < 8;j++)
{
channel_select(6); //从左往右依次熄灭
P0 = 0xfe << j;
delay_ms(100);
}
}
void main()
{
system_init();
system_test();
timer0_init();
while(1)
{
time_show();
key_scanf();
}
}