数显电子钟.docx
- 文档编号:27839958
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:18
- 大小:18.94KB
数显电子钟.docx
《数显电子钟.docx》由会员分享,可在线阅读,更多相关《数显电子钟.docx(18页珍藏版)》请在冰豆网上搜索。
数显电子钟
/*数显电子钟*/
/*12MHz*/
/*T0传统的12T方式*/
/*CPU:
stc12c5410ad系列*/
#include
#defineucharunsignedchar
#defineCOUNT11//定义接收缓冲区大小
#defineHANDSHAKE0xaa//数据包头常量定义
#definePSEG0x30/*P.的段码*/
/*数码管的控制引脚定义*/
sbitw4=P2^1;/*第4个数码管的共阳极控制*/
sbitw2=P3^7;
sbitw3=P2^7;
sbitw1=P2^6;
sbitdp=P2^0;/*小数点位*/
sbitS1=P2^5;/*设置键*/
sbitS2=P2^4;/*数字+1键*/
/*全局变量定义*/
ucharbuf[4];/*显示缓冲区*/
ucharhourh;/*BCD时钟各位*/
ucharhourl;
ucharminuh;
ucharminul;
ucharsecond;/*秒变量*/
ucharcount;/*溢出中断计数器*/
ucharbdatasetflag;/*设置用标志字节*/
ucharbdatauflag;/*通用标志字节*/
ucharbuffer[7];//定义缓冲区(全部接收,包括校验字节)
ucharpoint;//定义缓冲区当前位置指示
ucharrec;
ucharbdataflag;
//定义标志与输入输出引脚
sbittime_over_flag=flag^0;//接收超时标志
sbitrx_ok=flag^1;//串行接收完成标志
sbittx_ok=flag^2;//串行发送完成标志
sbitvb=flag^3;//位变量
/*位变量定义*/
/*以下4个位变量在setflag中,便于移位处理*/
sbithh=setflag^0;/*当前设置位标志*/
sbithl=setflag^1;
sbitmh=setflag^2;
sbitml=setflag^3;
/*以下位变量在uflag*/
sbitfresh=uflag^0;/*显示刷新标志*/
sbitss=uflag^1;/*位闪烁标志*/
sbitsec=uflag^2;/*秒指示标志*/
sbitwarning=uflag^3;/*闹铃标志*/
sbitdisp=uflag^4;/*定时器0的功能选项,=1:
显示,=0:
正常时钟走时*/
/*数码管的段码定义*/
/*
/*hcbfagde*/
/*P2.0P1.6P1.5P1.4P1.3P1.2P1.1P1.0*/
/*
10011111'1'0x9f
11010000'2'0xd0
10010001'3'0x91
10001011'4'0x8b
10100001'5'0xa1
10100000'6'0xa0
10010111'7'0x97
10000000'8'0x80
10000001'9'0x81
10000100'0'0x84
11000010'p'0xc2
*/
ucharseg[11]={0x84,0x9f,0xd0,0x91,0x8b,0xa1,0xa0,0x97,0x80,0x81,0xb2};
/*函数说明*/
voidsys_init(void);
voidt0_init(void);
voiddisplay(void);
voiddelay20ms(void);
voidsettime(void);
voidt0_init2(void);
voiddelay1ms(ints)
{
uchari,j,k;
for(i=0;i
for(j=0;j<15;j++)
for(k=0;k<250;k++);
}
//********************************************************************************
//串口初始化设置函数
//系统时钟为12M,串口波特率1200,串口接收中断允许,发送中断禁止
//********************************************************************************
voidUART_init(void)
{
SCON=0xd0;//选择串口工作方式3,接收允许,11010000,注意SM2=0
ET1=0;//定时器1中断禁止
TH1=0xe6;//拨特率1200
TR1=1;//启动定时器1
PS=1;//串口为高优先级
ES=1;//允许串口中断
}
//*****************************************************************************
//串口中断处理函数
//这里采用简单的定长数据包格式,数据长度为6字节
//*****************************************************************************
voidcom_interrupt(void)interrupt4using3
{
ucharRECEIVE_buffer;
if(RI)
{
RI=0;//清接收中断标志
RECEIVE_buffer=SBUF;//接收串口数据
if((!
vb)&&(RECEIVE_buffer!
=0xaa))//等待接收数据包头字节
{
point=0;
rx_ok=0;
vb=0;
}
else
{
if(!
vb)
{
point=0;
vb=1;//设置数据包开始标志
}
}
if(vb)
{
buffer[point++]=RECEIVE_buffer;
if(point==6)
{
rx_ok=1;//确保正确接收一帧数据,否则出现意想不到的错
point=0;
vb=0;
}
}
}
if(TI)
{
TI=0;//处理发送中断
tx_ok=1;//设置发送完成标志
}
}
/*****************************************************************
;时钟主函数:
main()
;定时器T0工作于中断方式,其余中断关闭
;一旦走时开始,无法进行设置。
如要重新设置,则必须复位
;本程序没有考虑走时误差
;本时钟没有设计定时闹钟功能
;12小时制
;
;如果某74LS164的1,2脚与其他74LS164的1,2脚错连了,则会出现同显示的状态
;
*****************************************************************/
voidmain(void)
{
sys_init();/*系统初始化*/
t0_init();/*定时器初始化*/
buf[0]=0x0a;/*"P."的段码送显示缓冲区*/
buf[1]=0x0b;
buf[2]=0x0b;
buf[3]=0x0b;
//display();/*显示待机符P.*/
//settime();/*等待设置当前时间*/
point=0;//接收缓冲区和指针清0
buffer[0]=0;//接收标志清0,为接收做好准备
rx_ok=0;
while(!
rx_ok);//等待接收来自PC机的对时数据
buf[0]=hourh=buffer[1];//数据为6字节:
aa时十位时个位分十位分个位
buf[1]=hourl=buffer[2];
buf[2]=minuh=buffer[3];
buf[3]=minul=buffer[4];
TR0=1;/*设置完后开始走时,启动定时器T0*/
ET0=1;/*允许T0溢出中断*/
while
(1)
{
if(fresh)/*判是否要刷新显示(分或时变化)*/
{
buf[0]=hourh;/*是,则新的时间送显示缓冲区*/
buf[1]=hourl;
buf[2]=minuh;
buf[3]=minul;
}
display();/*显示刷新*/
}
}
/*****************************************************************
;显示函数:
display()
;入口参数在全局变量buf中,BCD形式
;****************************************************************/
voiddisplay(void)
{
staticuchari=0;
P1=seg[buf[0]];
dp=1;//小数点灭
w1=0;w2=1;w3=1;w4=1;
delay1ms
(1);
P1=seg[buf[1]];
if(sec)
{
dp=0;//小数点亮
}
else
{
dp=1;//小数点灭
}
w1=1;w2=0;w3=1;w4=1;
delay1ms
(1);
P1=seg[buf[2]];
dp=1;//小数点灭
w1=1;w2=1;w3=0;w4=1;
delay1ms
(1);
P1=seg[buf[3]];
dp=1;//小数点灭
w1=1;w2=1;w3=1;w4=0;
delay1ms
(1);
i++;
}
/*****************************************************************
;T0定时中断函数:
timer0()
;定时时间为50ms,方式1的时间常数为3CB0H(12M)
;每中断1次,计数单元加1,20次为1s,到1s进行相应处理
;****************************************************************/
voidtimer0(void)interrupt1using1
{
fresh=0;/*清刷新标志*/
sec=0;/*清秒指示标志*/
TH0=0x3c;/*100ms定时常数*/
TL0=0xb0;
count++;/*中断次数加1*/
if(count!
=20)/*判到20次(1s)否,不到直接返回*/
return;
else/*到,则进行时间刷新处理*/
{
sec=1;
count=0;
second++;
if(second!
=60)/*到60秒,则分加1*/
return;
else
{
fresh=1;/*分加1后,必须刷新显示*/
second=0;/*秒回0*/
minul++;
if(minul!
=10)/*到分低位到10则高位加1*/
return;
else
{
minul=0;
minuh++;
if(minuh!
=6)
return;
else
{
minuh=0;
hourl++;
if(hourh==0)/*时高位为0,则小时低位可以到9,否则是0~2*/
{
if(hourl!
=10)
return;
else
{
hourl=0;
hourh++;
if(hourh!
=2)
return;
else
{
hourh=1;/*12小时制无0点*/
return;
}
}
}
else
{
if(hourl!
=3)
return;
else
{
hourl=0;
hourh++;
if(hourh!
=2)
return;
else
{
hourl=1;
hourh=0;
return;
}
}
}
}
}
}
}
}
/*****************************************************************
;T0定时初始化函数:
t0_int()
;定时时间为100ms,方式1的时间常数为3CB0H
;****************************************************************/
voidt0_init(void)
{
TH0=0x3c;
TL0=0xb0;
}
/*****************************************************************
;系统初始化函数:
sys_init()
;初始化各种变量包括标志等
;****************************************************************/
voidsys_init(void)
{
IE=0;/*关闭所有中断*/
PCON=PCON&0xfe;//正常工作模式(SMOD=0)
AUXR=AUXR&0x3f;//定时器T1和T0均为传统的12T方式(复位默认)
TMOD=0x21;//定时器1工作方式2,定时器0工作方式1
UART_init();//串口初始化
vb=0;
buf[0]=0;/*各变量初始化为0*/
buf[1]=0;
buf[2]=0;
buf[3]=0;
hourh=0;
hourl=0;
minuh=0;
minul=0;
second=0;
count=0;
setflag=0;/*标志所在字节清0*/
uflag=0;
EA=1;/*开放中断*/
}
/*****************************************************************
;当前时间设置函数:
settime()
;按S1键开始进入设置状态,S2键可以进行当前位的+1设置直至在次按S1键
;,结束当前位设置,进入下一位的设置.最低位设置完后,等待再按S1键结束
;设置.
;****************************************************************/
voidsettime(void)
{
uchari;
while(S1);/*等待S1键开始设置*/
for(i=0;i<4;i++)
delay20ms();/*延时去抖动*/
while(S1);
setflag=0;
hh=1;/*设置当前位标志*/
while
(1)
{
buf[0]=hourh;
buf[1]=hourl;
buf[2]=minuh;
buf[3]=minul;
//display();
if(S1)gotosett_1;
for(i=0;i<4;i++)
delay20ms();/*延时去抖动*/
if(S1)gotosett_1;
if(ml)return;/*如果当前编辑的份低位,则按S1键结束设定*/
setflag<<=1;/*当前位右移(标志左移1位)*/
continue;
sett_1:
if(S2)continue;
for(i=0;i<4;i++)
delay20ms();/*延时去抖动*/
if(S2)continue;
if(!
hh)gotosett_2;
{
hourh++;/*时高位加1处理*/
if(hourh!
=2)continue;
hourh=0;/*时高位只能是0,1*/
continue;
}
sett_2:
if(!
hl)gotosett_3;
{
hourl++;/*时低位加1处理,高位为0,可为0~9,否则,只能0~2*/
if(hourh)gotosett_20;
if(hourl==10)gotosett_21;
continue;
sett_21:
hourl=0;
continue;
sett_20:
if(hourl==3)gotosett_22;
continue;
sett_22:
hourl=0;
continue;
}
sett_3:
if(!
mh)gotosett_4;
{
minuh++;/*分高位加1处理,只能是0~5*/
if(minuh==6)gotosett_30;
continue;
sett_30:
minuh=0;
continue;
}
sett_4:
minul++;/*分低位加1处理,只能是0~9*/
if(minul==10)gotosett_40;
continue;
sett_40:
minul=0;
continue;
}
}
/*****************************************************************
;延时20ms函数:
delay20ms()
;对应主频为:
12MHz
;延时时间:
(j*255)*i*1
(单位:
M机器周期)
;****************************************************************/
voiddelay20ms(void)
{
delay1ms(6);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子钟