- UID
- 736286
- 阅读权限
- 35
- 推广
-
- 幽默
-
- 注册时间
- 2015-3-22
- 最后登录
- 1970-1-1
|
注册家电维修技术论坛,与同行畅聊维修技术,享更多技术论坛功能。
您需要 登录 才可以下载或查看,没有帐号?快速注册
x
闲来无事,用单片机制作的小玩意,喜欢的收藏的。
加载到单片机89C52即可使用。
功能简介:
简单记录冰箱停机次数,以及停机时间。停机期间,LED闪烁及喇叭声音提示。
#include "REG52.H"
#define uchar unsigned char
#define uint unsigned int
#define const_key_time1 20 //按键去抖动延时的时间
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelaylong);
void T0_time(); //定时中断函数
void key_scan(); //按键扫描函数 放在定时中断里
void display_service();
void display_drive();
sbit beep_dr=P2^3; //蜂鸣器的驱动IO口
sbit key_sr1=P3^4;
sbit key_sr2=P3^5;
sbit key_sr3=P3^6;
sbit key_sr4=P3^7;
sbit dula=P2^6;
sbit wela=P2^7;
sbit led=P1^1;
unsigned char ucKeySec=0; //被触发的按键编号
unsigned int uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned char ucKeyFlag=0;
unsigned int temp;
unsigned int temp1;
uchar ucDigShow8;
uchar ucDigShow7;
uchar ucDigShow6;
uchar ucDigShow5;
uchar ucDigShow4;
uchar ucDigShow3;
uchar ucDigShow2;
uchar ucDigShow1;
uchar ucDigDot8;//数码管8的小数点是否显示的标志
uchar ucDigDot7;
uchar ucDigDot6;
uchar ucDigDot5;
uchar ucDigDot4;
uchar ucDigDot3;
uchar ucDigDot2;
uchar ucDigDot1;
uchar ucDigShowTemp=0; //临时中间变量
uchar ucDisplayDriveStep=1;//动态扫描数码数码管的步骤变量
uchar ucWd1Update=1; //窗口1更新显示标志
uchar ucWd=1; //本程序的核心变量
uchar ucPart=0;
uchar ucWd1Part1Update=0;
uchar ucWd1Part2Update=0;
uchar ucWd1Part3Update=0;
uchar ucWd1Part4Update=0;
uint uiSetData1=0; //本程序中需要被设置的参数
uint uiSetData2=0;
uint uiSetData3=0;
uint uiSetData4=0;
uchar ucTemp1=0; //中间过渡变量
uchar ucTemp2=0;
uchar ucTemp3=0;
uchar ucTemp4=0;
uchar ucTemp5=0;
uchar ucTemp6=0;
uchar ucTemp7=0;
uchar ucTemp8=0;
uint uiDpyTimeCnt=0;
uchar code table_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,
0x6F,0x00,0x40,0x73,};
uchar code table_we[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
display_service();
}
}
void key_scan()//按键扫描函数 放在定时中断里
{
if(key_sr1==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock1=0; //按键自锁标志清零
uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt1++; //累加定时中断次数
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //自锁按键置位,避免一直触发
uiSetData1++;
ucWd1Part1Update=1;
ucKeySec=1; //触发1号键
}
}
}
void display_drive()
{
P0=0xff;
dula=1;
dula=0;
wela=1;
wela=0;
switch(ucDisplayDriveStep)
{
case 1:
P0=table_du[ucDigShow1];
if(ucDigDot1==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
//delay_short(100);
P0=table_we[0];
wela=1;
wela=0;
delay_short(50);
break;
case 2:
P0=table_du[ucDigShow2];
if(ucDigDot2==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
//delay_short(100);
P0=table_we[1];
wela=1;
wela=0;
delay_short(50);
break;
case 3:
P0=table_du[ucDigShow3];
if(ucDigDot3==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
// delay_short(100);
P0=table_we[2];
wela=1;
wela=0;
delay_short(50);
break;
case 4:
P0=table_du[ucDigShow4];
if(ucDigDot4==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
// delay_short(100);
P0=table_we[3];
wela=1;
wela=0;
delay_short(50);
break;
case 5:
P0=table_du[ucDigShow5];
if(ucDigDot5==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
//delay_short(100);
P0=table_we[4];
wela=1;
wela=0;
delay_short(50);
break;
case 6:
P0=table_du[ucDigShow6];
if(ucDigDot6==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
// delay_short(100);
P0=table_we[5];
wela=1;
wela=0;
delay_short(50);
break;
case 7:
P0=table_du[ucDigShow7];
if(ucDigDot7==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
// delay_short(100);
P0=table_we[6];
wela=1;
wela=0;
delay_short(50);
break;
case 8:
P0=table_du[ucDigShow8];
if(ucDigDot8==1)
{
P0=P0|0x80;
}
dula=1;
dula=0;
// delay_short(100);
P0=table_we[7];
wela=1;
wela=0;
delay_short(50);
break;
}
ucDisplayDriveStep++;
if(ucDisplayDriveStep>8)
ucDisplayDriveStep=1;
}
void display_service()
{
switch(ucWd)
{
case 1:
if(ucWd1Part1Update==1)
{
ucWd1Part1Update=0;
ucTemp8=uiSetData1/10;
ucTemp7=uiSetData1%10;
if(uiSetData1<10)
{
ucDigShow8=10;
}
else
{
ucDigShow8=ucTemp8;
}
ucDigShow7=ucTemp7;
}
if(ucWd1Part2Update==1)
{
ucWd1Part2Update=0;
ucTemp6=uiSetData2/10;
ucTemp5=uiSetData2%10;
if(uiSetData2<10)
{
ucDigShow6=10;
}
else
{
ucDigShow6=ucTemp6;
}
ucDigShow5=ucTemp5;
}
if(ucWd1Part3Update==1)
{
ucWd1Part3Update=0;
ucTemp4=uiSetData3/10;
ucTemp3=uiSetData3%10;
if(uiSetData3<10)
{
ucDigShow4=10;
}
else
{
ucDigShow4=ucTemp4;
}
ucDigShow3=ucTemp3;
}
if(ucWd1Part4Update==1)
{
ucWd1Part4Update=0;
ucTemp2=uiSetData4/10;
ucTemp1=uiSetData4%10;
if(uiSetData4<10)
{
ucDigShow2=10;
}
else
{
ucDigShow2=ucTemp2;
}
ucDigShow1=ucTemp1;
}
if(ucWd1Update==1)
{
ucWd1Update=0;
ucTemp8=uiSetData1/10;
ucTemp7=uiSetData1%10;
ucTemp6=uiSetData2/10;
ucTemp5=uiSetData2%10;
ucTemp4=uiSetData3/10;
ucTemp3=uiSetData3%10;
ucTemp2=uiSetData4/10;
ucTemp1=uiSetData4%10;
if(uiSetData1<10)
{
ucDigShow8=10;
}
else
{
ucDigShow8=ucTemp8;
}
ucDigShow7=ucTemp7;
if(uiSetData2<10)
{
ucDigShow6=10;
}
else
{
ucDigShow6=ucTemp6;
}
ucDigShow5=ucTemp5;
if(uiSetData3<10)
{
ucDigShow4=10;
}
else
{
ucDigShow4=ucTemp4;
}
ucDigShow3=ucTemp3;
if(uiSetData4<10)
{
ucDigShow2=10;
}
else
{
ucDigShow2=ucTemp2;
}
ucDigShow1=ucTemp1;
}
switch(ucPart) //根据局部变量的值,使对应的参数产生闪烁的动态效果。
{
case 0: //4个参数都不闪烁
break;
case 1: //第1个参数闪烁
if(uiDpyTimeCnt==const_dpy_time_half)
{
if(uiSetData1<10) //数码管显示内容
{
ucDigShow8=10;
}
else
{
ucDigShow8=ucTemp8;
}
ucDigShow7=ucTemp7;
}
else if(uiDpyTimeCnt>const_dpy_time_all) //const_dpy_time_all一定要比const_dpy_time_half 大
{
uiDpyTimeCnt=0; //及时把闪烁记时器清零
ucDigShow8=10; //数码管显示空,什么都不显示
ucDigShow7=10;
}
break;
case 2: //第2个参数闪烁
if(uiDpyTimeCnt==const_dpy_time_half)
{
if(uiSetData2<10) //数码管显示内容
{
ucDigShow6=10;
}
else
{
ucDigShow6=ucTemp6;
}
ucDigShow5=ucTemp5;
}
else if(uiDpyTimeCnt>const_dpy_time_all) //const_dpy_time_all一定要比const_dpy_time_half 大
{
uiDpyTimeCnt=0; //及时把闪烁记时器清零
ucDigShow6=10; //数码管显示空,什么都不显示
ucDigShow5=10;
}
break;
case 3: //第3个参数闪烁
if(uiDpyTimeCnt==const_dpy_time_half)
{
if(uiSetData3<10) //数码管显示内容
{
ucDigShow4=10;
}
else
{
ucDigShow4=ucTemp4;
}
ucDigShow3=ucTemp3;
}
else if(uiDpyTimeCnt>const_dpy_time_all) //const_dpy_time_all一定要比const_dpy_time_half 大
{
uiDpyTimeCnt=0; //及时把闪烁记时器清零
ucDigShow4=10; //数码管显示空,什么都不显示
ucDigShow3=10;
}
break;
case 4: //第4个参数闪烁
if(uiDpyTimeCnt==const_dpy_time_half)
{
if(uiSetData4<10) //数码管显示内容
{
ucDigShow2=10;
}
else
{
ucDigShow2=ucTemp2;
}
ucDigShow1=ucTemp1;
}
else if(uiDpyTimeCnt>const_dpy_time_all) //const_dpy_time_all一定要比const_dpy_time_half 大
{
uiDpyTimeCnt=0; //及时把闪烁记时器清零
ucDigShow2=10; //数码管显示空,什么都不显示
ucDigShow1=10;
}
break;
}
break;
}
}
void T0_time() interrupt 1
{
TF0=0; //清除中断标志
TR0=0; //关中断
display_drive();
key_scan(); //按键扫描函数
if(ucKeyLock1==1)
{
temp++;
if(temp==350)
{
temp=0;
led=~led;
beep_dr=~beep_dr;
uiSetData4++;
ucWd1Part4Update=1;
if(uiSetData4==60)
{
uiSetData4=0;
uiSetData3++;
ucWd1Part3Update=1;
if(uiSetData3==60)
{
uiSetData3=0;
uiSetData2++;
ucWd1Part2Update=1;
}
if(uiSetData2==12)
{
uiSetData2=1;
}
}
}
}
else
{
led=1;
beep_dr=1;
}
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
TR0=1; //开中断
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i<uiDelayShort;i++)
{
; //一个分号相当于执行一条空语句
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
{
for(j=0;j<500;j++) //内嵌循环的空指令数量
{
; //一个分号相当于执行一条空语句
}
}
}
void initial_myself() //第一区 初始化单片机
{
TMOD=0x01; //设置定时器0为工作方式1
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
}
void initial_peripheral() //第二区 初始化外围
{
ucDigShow8=8; //第8位数码管要显示的内容
ucDigShow7=7; //第7位数码管要显示的内容
ucDigShow6=6; //第6位数码管要显示的内容
ucDigShow5=5; //第5位数码管要显示的内容
ucDigShow4=4; //第4位数码管要显示的内容
ucDigShow3=3; //第3位数码管要显示的内容
ucDigShow2=2; //第2位数码管要显示的内容
ucDigShow1=1; //第1位数码管要显示的内容
ucDigDot8=0;
ucDigDot7=1;
ucDigDot6=0;
ucDigDot5=0; //显示第5位的小数点
ucDigDot4=0;
ucDigDot3=0;
ucDigDot2=0;
ucDigDot1=0;
EA=1; //开总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}
|
|