标题:
求帮忙分析这个电子钟程序每一部分是干嘛的,比如哪一部分是秒表,哪一部分是干嘛
[打印本页]
作者:
kxg9701
时间:
2017-6-11 17:58
标题:
求帮忙分析这个电子钟程序每一部分是干嘛的,比如哪一部分是秒表,哪一部分是干嘛
#include<reg51.h>
#define uchar unsigned char
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit beep=P1^5;
unsigned char j,k,a1,a0,b1,b0,c1,c0,s,f,m,r1,r0,t1,t0,y1,y0,q,w,e,key=10,temp,qq=0,mb=5;
uchar shi20,shi10,fen20,fen10,miao20,miao10,new,ok=1,wei=1;
unsigned int pp,ppp;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(int i)
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar shi2,uchar shi1,uchar fen2,uchar fen1,uchar miao2,uchar miao1)
{
LSA=0;LSB=0;LSC=0;
P0=table[shi2];
delay(5);
LSA=1;LSB=0;LSC=0;
P0=table[shi1]|0x80;
delay(5);
LSA=1;LSB=1;LSC=0;
P0=table[fen2];
delay(5);
LSA=0;LSB=0;LSC=1;
P0=table[fen1]|0x80;
delay(5);
LSA=0;LSB=1;LSC=1;
P0=table[miao2];
delay(5);
LSA=1;LSB=1;LSC=1;
P0=table[miao1];
delay(5);
}
void keyscan0()
{
P1=0xff;
temp=P1;
if(temp!=0xff)
{
delay(10);
if(temp!=0xff)
{
temp=P1;
if(temp==0xfe)
{
ok++;
if (ok==3)
ok=0;
}
}
}
}
void keyscan()
{
{
P3=0xff;
temp=P3;
if(temp!=0xff)
{
delay(10);
if(temp!=0xff)
{
temp=P3;
switch(temp)
{case 0xfb :
key=3;
wei++;
if (wei==7)
wei=1;
break;
case 0xf7:
key=4;
break;
case 0xfd:
mb++;
if(mb==8)
mb=5;
break;
}
}
}
}
}
void main()
{
TMOD=0x01;
TH0=0xdc;
TL0=0x00;
ET0=1;
EA=1;
while(1)
{ keyscan0();
while(P1!=0xff);
if(ok==1)
{ TR0=1;
if(pp>=100)
{ pp=0;
m++;
if(m==60)
{
m=0;
f++;
if(f==60)
{
f=0;
s++;
if(s==24)
{
s=0;
}
}
}
}
a0=s%10;
a1=s/10;
b0=f%10;
b1=f/10;
c0=m%10;
c1=m/10;
display(a1,a0,b1,b0,c1,c0);
}
else if(ok==2)
{
TR0=1;
keyscan();
while(P3!=0xff);
if(mb==5)
{
q=0;
w=0;
e=0;
mb=6;
pp=0;
}
if(mb==6)
{
if(qq!=pp)
{
e++;
if(e==100)
{
e=0;
w++;
if(w==60)
{
w=0;
q++;
if(q==60)
{
q=0;
}
}
}
}
}
r0=q%10;
r1=q/10;
t0=w%10;
t1=w/10;
y0=e%10;
y1=e/10;
display(r1,r0,t1,t0,y1,y0);
if(pp>=100)
{ pp=0;
m++;
if(m==60)
{
m=0;
f++;
if(f==60)
{
f=0;
s++;
if(s==24)
{
s=0;
}
}
}
}
a0=s%10;
a1=s/10;
b0=f%10;
b1=f/10;
c0=m%10;
c1=m/10;
}
else
{ TR0=0;
keyscan();
while(P3!=0xff);
if(key==3)
{key=0;
switch(wei)
{
case 1:
LSA=0;LSB=0;LSC=0;
P0=table[a1];
break;
case 2:
LSA=1;LSB=0;LSC=0;
P0=table[a0]|0x80;
break;
case 3:
LSA=1;LSB=1;LSC=0;
P0=table[b1];
break;
case 4: LSA=0;LSB=0;LSC=1;
P0=table[b0]|0x80;
break;
case 5:
LSA=0;LSB=1;LSC=1;
P0=table[c1];
break;
case 6:
LSA=1;LSB=1;LSC=1;
P0=table[c0];
break;
}
}
if(key==4)
{
key=0;
switch(wei)
{
case 1: //±×2
a1++;
if(a1==3)
a1=0;
LSA=0;LSB=0;LSC=0;
P0=table[a1];
break;
case 2:
a0++;
if (a1==2)
{
if(a0==4)
a0=0;}
else if (a0==10)
a0=0;
LSA=1;LSB=0;LSC=0;
P0=table[a0]|0x80;
break;
case 3: //·×6
b1++;
if(b1==6)
b1=0;
LSA=1;LSB=1;LSC=0;
P0=table[b1];
break;
case 4:
b0++;
if(b0==10)
b0=0;
LSA=0;LSB=0;LSC=1;
P0=table[b0]|0x80;
break;
case 5: //×6
c1++;
if(c1==6)
c1=0;
LSA=0;LSB=1;LSC=1;
P0=table[c1];
break;
case 6:
c0++;
if(c0==10)
c0=0;
LSA=1;LSB=1;LSC=1;
P0=table[c0];
break;
}
// while(P3!=0xff);
}
m=c1*10+c0;
f=b1*10+b0;
s=a1*10+a0;
}
}
}
void time0() interrupt 1
{ TH0=0xdc;
TL0=0x00;
qq=pp;
pp++;
}
作者:
zl2168
时间:
2017-6-12 18:11
从哪儿来,问哪儿去。这么冗长的程序,会有人解释吗?
作者:
zl2168
时间:
2017-6-12 18:12
读别人的程序,是最烦人的事。
作者:
何鹏飞
时间:
2017-6-12 19:21
这是带解释的时钟程序,你看行不
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit LCD1602_E=P2^7;
sbit LCD1602_RS=P2^6;
sbit LCD1602_RW=P2^5;
sbit RST=P3^5;
sbit SCLK=P3^6;
sbit DSIO=P3^4;
sbit set=P1^0;
sbit add=P1^1;
sbit dec=P1^2;
sbit buzzer=P1^3;
bit keyflag=0;
uchar keynum,ge,shi;
uchar S1num,flag,second,minute,hour,week,day,month,year;
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
uchar TIME[7] = {0x00, 0x23, 0x17, 0x13, 0x05, 0x06, 0x17};
void keyScan();
void delay(uchar z);
void LcdInit();
void Ds1302Init();
void Ds1302Write(uchar addr, uchar dat);
void Ds1302ReadTime();
void LcdDisplay();
uchar Ds1302Read(uchar addr);
void LcdWriteCom(uchar com) //LCD写入命令函数
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 0; //选择写入命令
LCD1602_RW = 0; //选择写入
P0=com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
delay(5);
LCD1602_E = 1; //写入时序
delay(5);
LCD1602_E = 0;
}
void LcdWriteData(uchar dat) //LCD写入数据函数
{
LCD1602_E = 0; //使能清零
LCD1602_RS = 1; //选择写入数据
LCD1602_RW = 0; //选择写入
P0 = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
delay(5);
LCD1602_E = 1; //写入时序
delay(5);
LCD1602_E = 0;
}
void main() //进入主函数
{
LcdInit();
Ds1302Init();
while(1)
{
keyScan();
if(keyflag==0)
{
Ds1302ReadTime();
LcdDisplay();
}
}
}
void LcdDisplay() //LCD要显示的数据
{
LcdWriteCom(0x80+0X40);
LcdWriteData('0'+TIME[2]/16); //时
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[1]/16); //分
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[0]/16); //秒
LcdWriteData('0'+(TIME[0]&0x0f));
LcdWriteCom(0x80);
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0'+TIME[6]/16); //年
LcdWriteData('0'+(TIME[6]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[4]/16); //月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16); //日
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteCom(0x8D);
LcdWriteData('0'+(TIME[5]&0x07)); //星期
}
void LcdInit() //LCD初始化子程序
{
LcdWriteCom(0x38); //开显示
LcdWriteCom(0x0c); //开显示不显示光标
LcdWriteCom(0x06); //写一个指针加1
LcdWriteCom(0x01); //清屏
LcdWriteCom(0x80); //设置数据指针起点
}
void Ds1302Init() //DS1302初始化子程序
{
uchar n;
Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能
for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
void Ds1302Write(uchar addr, uchar dat) //DS1302被写入数据
{
uchar n;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1; //然后将RST(CE)置高电平。
_nop_();
for (n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//写入8位数据
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//传送数据结束
_nop_();
}
uchar Ds1302Read(uchar addr) //读出DS1302的数据
{
uchar n,dat,dat1;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1;//然后将RST(CE)置高电平。
_nop_();
for(n=0; n<8; n++)//开始传送八位地址命令
{
DSIO = addr & 0x01;//数据从低位开始传送
addr >>= 1;
SCLK = 1;//数据在上升沿时,DS1302读取数据
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}
_nop_();
for(n=0; n<8; n++)//读取8位数据
{
dat1 = DSIO;//从最低位开始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;//DS1302下降沿时,放置数据
_nop_();
}
RST = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
void Ds1302ReadTime() //DS1302发送数据
{
uchar n;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
}
}
void delay(uchar z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyScan()
{
if(set==0)
{
delay(5);
if(set==0)
{
buzzer=0;
delay(30);
buzzer=1;
while(!set);
keynum++;
switch(keynum)
{
case 1:
keyflag=1;
LcdWriteCom(0x80+0x40+7);
LcdWriteCom(0x0f);
break;
case 2:
Ds1302Write(0x8e,0x00);//?????
Ds1302Write(0x82,0x80);
LcdWriteCom(0x80+0x40+4);
LcdWriteCom(0x0f);
break;
case 3:
Ds1302Write(0x8e,0x00);
Ds1302Write(0x84,0x80);
LcdWriteCom(0x80+0x40+1);
LcdWriteCom(0x0f);
break;
case 4:
Ds1302Write(0x8e,0x00);
Ds1302Write(0x8a,0x80);
LcdWriteCom(0x80+13);
LcdWriteCom(0x0f);
break;
case 5:
Ds1302Write(0x8e,0x00);
Ds1302Write(0x86,0x80);
LcdWriteCom(0x80+9);
LcdWriteCom(0x0f);
break;
case 6:
Ds1302Write(0x8e,0x00);
Ds1302Write(0x88,0x80);
LcdWriteCom(0x80+6);
LcdWriteCom(0x0f);
break;
case 7:
Ds1302Write(0x8e,0x00);
Ds1302Write(0x8c,0x80);
LcdWriteCom(0x80+3);
LcdWriteCom(0x0f);
break;
}
if(keynum==8)
{
keynum=0;
keyflag=0;
LcdWriteCom(0x0c);
Ds1302Write(0x80,0x00);
Ds1302Write(0x80,(second/10)<<4|second%10);
Ds1302Write(0x82,(minute/10)<<4|minute%10);
Ds1302Write(0x84,(hour/10)<<4|hour%10);
Ds1302Write(0x8a,(week/10)<<4|week%10);
Ds1302Write(0x86,(day/10)<<4|day%10);
Ds1302Write(0x88,(month/10)<<4|month%10);
Ds1302Write(0x8c,(year/10)<<4|year%10);
Ds1302Write(0x8e,0x80);
}
}
}
if(keynum!=0)
{
if(add==0)
{
delay(5);
while(!add);
switch(keynum)
{
case 1: second++;
if(second==59)second=0;
shi=second/10;
ge=second%10;
TIME[0] = Ds1302Read(READ_RTC_ADDR[0]);
LcdWriteCom(0x80+0x40+7);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40+6);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+7);
break;
case 2:
minute++;
if(minute==59)minute=0;
shi=minute/10;
ge=minute%10;
TIME[1] = Ds1302Read(READ_RTC_ADDR[1]);
LcdWriteCom(0x80+0x40+4);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40+3);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+4);
break;
case 3:
hour++;
if(hour==24)hour=0;
shi=hour/10;
ge=hour%10;
TIME[2] = Ds1302Read(READ_RTC_ADDR[2]);
LcdWriteCom(0x80+0x40+1);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+1);
break;
case 4:
week++;
if(week==8)week=1;
TIME[5] = Ds1302Read(READ_RTC_ADDR[5]);
LcdWriteCom(0x80+13);
LcdWriteData(0x30+week);
LcdWriteCom(0x80+13);
break;
case 5:
day++;
shi=day/10;
ge=day%10;
TIME[3] = Ds1302Read(READ_RTC_ADDR[3]);
LcdWriteCom(0x80+9);
LcdWriteData(0x30+ge);
LcdWriteCom(0x80+8);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+9);
break;
case 6:
month++;
shi=month/10;
ge=month%10;
TIME[4] = Ds1302Read(READ_RTC_ADDR[4]);
LcdWriteCom(0x80+6);
LcdWriteData(0x30+ge);
LcdWriteCom(0x80+5);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+6);
break;
case 7:
year++;
shi=year/10;
ge=year%10;
TIME[6] = Ds1302Read(READ_RTC_ADDR[6]);
LcdWriteCom(0x80+3);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+2);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+3);
break;
}
}
}
if(keynum!=0)
{
if(dec==0)
{
delay(5);
while(!dec);
switch(keynum)
{
case 1: second--;
if(second==0)second=59;
shi=second/10;
ge=second%10;
TIME[0] = Ds1302Read(READ_RTC_ADDR[0]);
LcdWriteCom(0x80+0x40+7);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40+6);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+7);
break;
case 2:
minute--;
if(minute==0)minute=59;
shi=minute/10;
ge=minute%10;
TIME[1] = Ds1302Read(READ_RTC_ADDR[1]);
LcdWriteCom(0x80+0x40+4);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40+3);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+4);
break;
case 3:
hour--;
if(hour==0)hour=23;
shi=hour/10;
ge=hour%10;
TIME[2] = Ds1302Read(READ_RTC_ADDR[2]);
LcdWriteCom(0x80+0x40+1);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+0x40);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+0x40+1);
break;
case 4:
week--;
if(week==0)week=7;
TIME[5] = Ds1302Read(READ_RTC_ADDR[5]);
LcdWriteCom(0x80+13);
LcdWriteData(0x30+week);
LcdWriteCom(0x80+13);
break;
case 5:
day--;
shi=day/10;
ge=day%10;
TIME[3] = Ds1302Read(READ_RTC_ADDR[3]);
LcdWriteCom(0x80+9);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+8);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+9);
break;
case 6:
month--;
shi=month/10;
ge=month%10;
TIME[4] = Ds1302Read(READ_RTC_ADDR[4]);
LcdWriteCom(0x80+6);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+5);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+6);
break;
case 7:
year--;
shi=year/10;
ge=year%10;
TIME[6] = Ds1302Read(READ_RTC_ADDR[6]);
LcdWriteCom(0x80+3);
LcdWriteData(0x30+ge) ;
LcdWriteCom(0x80+2);
LcdWriteData(0x30+shi);
LcdWriteCom(0x80+3);
break;
}
}
}
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1