电子表功能程序.docx
《电子表功能程序.docx》由会员分享,可在线阅读,更多相关《电子表功能程序.docx(16页珍藏版)》请在冰豆网上搜索。
电子表功能程序
一电子表*//利用计时器实现电子表功能,可以通过四个按键对时间进行调整
//key1按下抬起后,进入调正状态,被调整的信息闪烁,同时按键key2、key3调加减,
//按下key4又抬起后,调整完毕,正常显示。
/******************************************************************************/
#include
#defineucharunsignedchar
codeucharseven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
codeucharseven_bit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
ucharkey1_down,key2_down,key3_down,key4_down,key1_mode;//key1_mode为调整模式标识
uchari=0,j=0,k,flash;
charsec,min,hou;
sbitkey1=P3^3;//进入和修改调整模式
sbitkey2=P3^4;//增加
sbitkey3=P3^5;//减小
sbitkey4=P3^6;//退出调整模式
sbitdop=P0^7;
voiddelay(ucharx)//延迟函数
{
while(x--);
}
voidkey_scan(void)//按键扫描函数
{
if(key1==0)//按键1按下,进入时间调整,key1_mode=1调秒,同时秒闪烁
{
key1=1;
delay(200);
if(key1==0)key1_down=1;
}
if(key1==1&&key1_down==1)
{
key1_mode++;
key1_down=0;
if(key1_mode==4)key1_mode=1;
}
if(key2==0)//按键2
{
key2=1;
delay(200);
if(key2==0)key2_down=1;
}
if(key2==1&&key2_down==1&&key1_mode==1)
{
key2_down=0;
sec++;
}
if(key2==1&&key2_down==1&&key1_mode==2)
{
key2_down=0;
min++;
}
if(key2==1&&key2_down==1&&key1_mode==3)
{
key2_down=0;
hou++;
}
if(key3==0)//按键3
{
key3=1;
delay(200);
if(key3==0)key3_down=1;
}
if(key3==1&&key3_down==1&&key1_mode==1)
{
key3_down=0;
sec--;
if(sec<0)
sec=59;
}
if(key3==1&&key3_down==1&&key1_mode==2)
{
key3_down=0;
min--;
if(min<0)
min=59;
}
if(key3==1&&key3_down==1&&key1_mode==3)
{
key3_down=0;
hou--;
if(hou<0)
sec=23;
}
if(key4==0)//按键4
{
key4=1;
delay(200);
if(key4==0)key4_down=1;
}
if(key4==1&&key4_down==1)
{
key4_down=0;
key1_mode=0;
}
}
voidtimer0_init(void)//初始化
{
TMOD=0x01;
TH0=0xf8;//(65536-2000)/256;
TL0=0x30;//(65536-2000)%256;
TR0=1;
EA=1;
ET0=1;
}
voidtimer0_isr(void)interrupt1//中断
{
TR0=0;
EA=0;
TH0=0xf8;//(65536-2000)/256;
TL0=0x30;//(65536-2000)%256;
TR0=1;
EA=1;
i++;
P0=0xff;//仿真时用,关闭所有数码管的显示,以防止发生串扰
if(i>=250)//半秒
{
flash=~flash;
if(key1_mode==0)k++;
i=0;
}
if(k>=2)//刚好1秒
{
k=0;
sec++;
}
if(sec>=60)
{
sec=0;
min++;
}
if(min>=60)
{
min=0;
hou++;
}
if(hou>=24)
hou=0;
if(key1_mode==0)//正常显示
{
switch(j)
{
case0:
P0=seven_seg[sec%10];break;
case1:
P0=seven_seg[sec/10];break;
case2:
P0=seven_seg[min%10];dop=flash;break;
case3:
P0=seven_seg[min/10];break;
case4:
P0=seven_seg[hou%10];dop=flash;break;
case5:
P0=seven_seg[hou/10];break;
}
}
if(key1_mode==1)//选定秒
{
switch(j)
{
case0:
P0=seven_seg[sec%10]|flash;break;
case1:
P0=seven_seg[sec/10]|flash;break;
case2:
P0=seven_seg[min%10]&0x7f;break;
case3:
P0=seven_seg[min/10];break;
case4:
P0=seven_seg[hou%10]&0x7f;break;
case5:
P0=seven_seg[hou/10];break;
}
}
if(key1_mode==2)//选定分
{
switch(j)
{
case0:
P0=seven_seg[sec%10];break;
case1:
P0=seven_seg[sec/10];break;
case2:
P0=seven_seg[min%10]&0x7f|flash;break;
case3:
P0=seven_seg[min/10]|flash;break;
case4:
P0=seven_seg[hou%10]&0x7f;break;
case5:
P0=seven_seg[hou/10];break;
}
}
if(key1_mode==3)//选定时
{
switch(j)
{
case0:
P0=seven_seg[sec%10];break;
case1:
P0=seven_seg[sec/10];break;
case2:
P0=seven_seg[min%10]&0x7f;break;
case3:
P0=seven_seg[min/10];break;
case4:
P0=seven_seg[hou%10]&0x7f|flash;break;
case5:
P0=seven_seg[hou/10]|flash;break;
}
}
P2=seven_bit[j];
j++;
if(j>=6)j=0;
}
voidmain(void)
{
sec=55;
min=59;
hou=10;
timer0_init();
while
(1)
key_scan();//扫描按键
}
二功能:
本程序是让P0^0口LED连续闪烁
/**********************************************************/
#include
sbitLED0=P0^0;//可寻址的位P0.0定义,同时P0.0端口输出位P0.0的电平值
voiddelay(unsignedinti)//延时函数
{
while(i--);
}
voidmain(void)
{
P0=0x00;
while
(1)
{
LED0=!
LED0;//LED0的状态改变一次
delay(30000);//调用延时函数,延时一段时间
}
}
三动态显示#ifndef__REG51_H__
#define__REG51_H__
/*BYTERegister*/
sfrP0=0x80;
sfrP1=0x90;
sfrP2=0xA0;
sfrP3=0xB0;
sfrPSW=0xD0;
sfrACC=0xE0;
sfrB=0xF0;
sfrSP=0x81;
sfrDPL=0x82;
sfrDPH=0x83;
sfrPCON=0x87;
sfrTCON=0x88;
sfrTMOD=0x89;
sfrTL0=0x8A;
sfrTL1=0x8B;
sfrTH0=0x8C;
sfrTH1=0x8D;
sfrIE=0xA8;
sfrIP=0xB8;
sfrSCON=0x98;
sfrSBUF=0x99;
/*BITRegister*/
/*PSW*/
sbitCY=0xD7;
sbitAC=0xD6;
sbitF0=0xD5;
sbitRS1=0xD4;
sbitRS0=0xD3;
sbitOV=0xD2;
sbitP=0xD0;
/*TCON*/
sbitTF1=0x8F;
sbitTR1=0x8E;
sbitTF0=0x8D;
sbitTR0=0x8C;
sbitIE1=0x8B;
sbitIT1=0x8A;
sbitIE0=0x89;
sbitIT0=0x88;
/*IE*/
sbitEA=0xAF;
sbitES=0xAC;
sbitET1=0xAB;
sbitEX1=0xAA;
sbitET0=0xA9;
sbitEX0=0xA8;
/*IP*/
sbitPS=0xBC;
sbitPT1=0xBB;
sbitPX1=0xBA;
sbitPT0=0xB9;
sbitPX0=0xB8;
/*P3*/
sbitRD=0xB7;
sbitWR=0xB6;
sbitT1=0xB5;
sbitT0=0xB4;
sbitINT1=0xB3;
sbitINT0=0xB2;
sbitTXD=0xB1;
sbitRXD=0xB0;
/*SCON*/
sbitSM0=0x9F;
sbitSM1=0x9E;
sbitSM2=0x9D;
sbitREN=0x9C;
sbitTB8=0x9B;
sbitRB8=0x9A;
sbitTI=0x99;
sbitRI=0x98;
#endif
四*********************************************************************/
//读取DS18B20温度,通过数码管显示,在温度超过35度时继电器吸合
/*********************************************************************/
#include
#include"18B20.c"
#defineucharunsignedchar
#defineuintunsignedint
codeucharseven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
codeucharseven_bit[]={0xfe,0xfd,0xfb,0xf7};
ucharcp;
uinttemp1,temp2;
sbitjdq=P2^6;
voidtimer0_init(void)//初始化
{
TMOD=0x01;
TH0=0xec;
TL0=0x78;
TR0=1;
EA=1;
ET0=1;
}
/*****************************************************************************/
voidtimer0_isr(void)interrupt1//中断
{
ucharj;
TR0=0;
EA=0;
TH0=0xec;
TL0=0x78;
TR0=1;
EA=1;
cp++;
if(cp>=200)//刚好1秒
{
cp=0;
temp1=Read_Temperature();//得到温度
if((temp1&0x80)==0x80)//如果温度为负值
{
temp2=0x7f&~temp1+(0x0f&~c)/15;//整数处理,需要加上小数来的借位
c=0x0f&~c+0x01;//小数处理
}
elsetemp2=temp1;//如果温度为正值,不用处理
}
P0=0xff;
switch(j)
{
case0:
P0=seven_seg[c*10/16];break;//显示小数
case1:
P0=0x7f&seven_seg[temp2%10];break;//显示个位并加上小数点
case2:
{
if((temp2<10)&&(temp1<0x80)){P0=0xff;break;}//如果温度小于10度,且为正值,十位0不显示
if((temp1>0x80)&&(temp2<10)){P0=0xbf;break;}//如果温度小于10度,且为负值,十位0不显示,只显示“-”
P0=seven_seg[temp2/10];break;//如果温度大于10度,10位正常显示
}
case3:
{
if((temp1>0x80)&&((temp2/10)>0))//如果温度为负值,且十位不为0,百位显示“-”
P0=0xbf;
break;
}
}
P2=seven_bit[j];
j++;
if(j>=4)
j=0;
}
voidmain(void)
{
timer0_init();
while
(1);
}
五//ds1302驱动
//2011年5月
/*********************************************************************************/
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharsec,min,hour,date,moon,year;
uchartime[6];
uchardatt[6];
sbitrst=P1^3;
sbitscl=P1^1;
sbitsd=P1^2;
/***********************************对DS1302初始化++******************************/
voidds1302_init(void)
{
rst=0;
scl=0;
rst=1;
}
/*********************************对DS1302写1字节函数*****************************/
voidwrite_ds1302_onebyte(uchardate)
{
uchari;
for(i=8;i>0;i--)
{
scl=0;
sd=(bit)(date&0x01);
scl=1;//上升沿
date=date>>1;
}
}
/*********************************从DS1302读一字节函数*****************************/
ucharread_ds1302_onebyte(void)
{
uchari,dat;
for(i=8;i>0;i--)
{
scl=1;
scl=0;//下降沿
dat=dat>>1;
if(sd)dat=dat|0x80;
}
return(dat);
}
/*****************************对DS1302的某一地址写一字节函数***********************/
voidwrite_ds1302_add_dat(ucharadd,uchardat)
{
ds1302_init();
write_ds1302_onebyte(add);
write_ds1302_onebyte(dat);
scl=1;
rst=0;
}
/*****************************从DS1302的某一地址读一字节函数***********************/
ucharread_ds1302_add(ucharadd)//读1302数据
{
uchardat_temp;
ds1302_init();
write_ds1302_onebyte(add);
dat_temp=read_ds1302_onebyte();
scl=1;
rst=0;
return(dat_temp);
}
/********************************8421BCD码到十进制转换*****************************/
ucharBCD_DEC_conv(ucharx)
{
uchardec;
dec=0x0f&x;
x=x>>4;
dec=dec+x*10;
return(dec);
}
ucharDEC_BCD_conv(ucharx)
{
ucharbcd;
bcd=x%10;
x=x/10;
x=x<<4;
bcd=bcd|x;
return(bcd);
}
voidget_ds1302_time(void)//获取1302的时间数据(时、分、秒),存入time1数组中
{
uchard;
d=read_ds1302_add(0x81);//读秒
sec=BCD_DEC_conv(d);//得到秒
d=read_ds1302_add(0x83);//读分
min=BCD_DEC_conv(d);//得到分
d=read_ds1302_add(0x85);//读小时
hour=BCD_DEC_conv(d);//得到小时
d=read_ds1302_add(0x87);//读日
date=BCD_DEC_conv(d);//得到日
d=read_ds1302_add(0x89);//读月
moon=BCD_DEC_conv(d);//得到月
d=read_ds1302_add(0x8d);//读年
year=BCD_DEC_conv(d);//得到年
}