📄 串口时钟最终显示(一位一位的传送).c
字号:
#include <reg51.h>
#define XTAL 11059200 // CUP 晶振频率
#define baudrate 9600 // 通信波特率
#define uchar unsigned char
#define uint unsigned int
sbit key0=P3^2;
sbit key1=P3^3;
sbit key2=P3^4;
sbit key3=P3^5;
sbit P0_7=P0^7;//控制冒号闪烁
//--------字表----------
uchar code dispcode[]=
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
//-------显示位置-------
uchar dispbitcode[]={0xa0,0x90,0x88,0x84,0x82,0x81};
uchar second=0; //秒
uchar minite=0; //分
uchar hour=12; //小时
uchar ms=0; //时间累加数
uchar time[3]; //串口数据存放
uchar i=0; //串口传送次数
uchar keynum=0; //按键次数
//-----延迟------
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//-------时间显示---------
void display()
{
uchar m;
for(m=0;m<6;m++)
{
delay(2);
P0=dispbitcode[m]; //控制显示位
switch(m) // 设置显示数
{
case 0: P1=dispcode[second%10]; break;
case 1: P1=dispcode[second/10]; break;
case 2: P1=dispcode[minite%10]; break;
case 3: P1=dispcode[minite/10]; break;
case 4: P1=dispcode[hour%10]; break;
case 5: P1=dispcode[hour/10]; break;
}
}
}
//---buzhidao -----
void sdisplay(uchar dw)
{
uchar cc,i;
cc=0x03; //buzhidao
cc=~(cc<<dw);
for(i=0;i<6;i++)
{
delay(2);
P0=dispbitcode[i]&cc;
switch(i)
{
case 0: P1=dispcode[second%10]; break;
case 1: P1=dispcode[second/10]; break;
case 2: P1=dispcode[minite%10]; break;
case 3: P1=dispcode[minite/10]; break;
case 4: P1=dispcode[hour%10]; break;
case 5: P1=dispcode[hour/10]; break;
}
}
}
//--------分秒时调节时的闪烁--------
void shan()
{
uchar i;
if(keynum==1)
{
for(i=0;i<4;i++)
{
display();
}
for(i=0;i<4;i++)
{
sdisplay(4);
}
}
if(keynum==2)
{
for(i=0;i<4;i++)
{
display();
}
for(i=0;i<4;i++)
{
sdisplay(2);
}
}
if(keynum==3)
{
for(i=0;i<4;i++)
{
display();
}
for(i=0;i<4;i++)
{
sdisplay(0);
}
}
}
//--------键盘扫描-----------
void skycon()
{
if(key0==0)
{
delay(5);
if(key0==0)
{
TR0=0;//接受终端位复位,不允许中断,也就是按键按下时,开始调时,秒钟不动
while(!key0)//按键按下时依然显示时间
{
display();
}
keynum++;
if(keynum==4) //退出时间调试
{
keynum=0;
TR0=1; //接受中断位打开,秒钟开始动
}
}
}
shan(); //被选位闪烁
if(keynum!=0)
{
if(key1==0 ) //加1
{
delay(5);
if(key1==0 )
{
if(keynum==1)
{
second++;
if(second==60)
{
second=0;
}
}
if(keynum==2)
{
minite++;
if(minite==60)
{
minite=0;
}
}
if(keynum==3)
{
hour++;
if(hour==24)
{
hour=0;
}
}
while(!key1) //去抖动,且一直显示时间
{
display();
}
}
}
if(key2==0 ) //减1
{
delay(5);
if(key2==0 )
{
if(keynum==1)
{
second--;
shan();
if(second==-1)
{
second=59;
}
}
if(keynum==2)
{
minite--;
shan();
if(minite==-1)
{
minite=59;
}
}
if(keynum==3)
{
hour--;
shan();
if(hour==-1)
{
hour=23;
}
}
while(!key2)
{
display();
}
}
}
}
if(key3==0) //退出时间调试
{
delay(5);
if(key3==0)
{
keynum=0;
TR0=1;
}
while(!key3)
{display();}
}
}
void main(void)
{
unsigned char c;
TMOD = 0x21; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // 器0赋初值
SCON = 0x50;
PCON = 0x00;
TR1 = 1;
TH0=(65535-50000)/256; //每50ms 一次中断
TL0=(65535-50000)%256;
TR0=1; //启动定时器0
ET0=1;
EA = 1;
while(1)
{
if(RI==1)
{
RI = 0;
c = SBUF; // 从缓冲区中把接收的字符放入c中
switch(i)
{
case 0: time[0]=c/0x10*10+c%0x10; break; //把SBUF转化成10进制数存入
case 1: time[1]=c/0x10*10+c%0x10; break;
case 2: time[2]=c/0x10*10+c%0x10; break;
}
i++;
while(i==3) //将SBUF 传送次数清零,以待下次的传送
{
i=0;
}
if(time[0]>=24) //小时不能大于24
{
time[0]=0;
}
if(time[1]>=60) //分钟不能大于60
{
time[1]=0;
}
if(time[2]>=60) //秒不能大于60
{
time[2]=0;
}
hour=time[0];
minite=time[1];
second=time[2];
SBUF = c; // 要发送的字符放入缓冲区
if(TI == 1)
TI = 0;
}
skycon();
display();
shan();
}
}
void time0() interrupt 1
{
TH0=(65535-50000)/256; //除中断2可以自动分配时间外,其余中断都得从新声明
TL0=(65535-50000)%256;
ms++;
if(ms==20) //50x20=1000ms=1s
{
ms=0;
P0_7=!P0_7;
second++;
if(second==60)
{
second=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -