qq_37870130
qq_37870130
采纳率100%
2017-07-21 08:59

如何通过串口修改时钟的时间

20

请问大神们如何在这个程序里添加串口来改变时钟啊
#include
#include
#define uchar unsigned char
#define uint unsigned int
/*七段共阴管显示定义*/
//此表为 LED 的字模, 共阴数码管 0-9 -
uchar code dispcode[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制
/*定义并初始化变量*/
uchar seconde=0;//秒
uchar minite=0;//分
uchar hour=12; //时
uchar mstcnt=0;//定时器计数,定时50ms,mstcnt满20,秒加1
uchar shi=0;//闹铃功能
uchar fen=0;
uchar bjcs;//报警次数
sbit P1_0=P1^0; //second 调整定义
sbit P1_1=P1^1; //minite调整定义
sbit P1_2=P1^2; //hour调整定义
sbit P1_5=P3^0; //整点报时
sbit P1_3=P1^3; //闹铃功能,调整时间
sbit P1_6=P1^6; //调整时
sbit P1_7=P1^7; //调整分
sbit P1_4=P1^4; //关闭闹铃

/*函数声明*/
void delay(uint k ); //延时子程序
void time_pro( ); //时间处理子程序
void display( ); //显示子程序
void keyscan( ); //键盘扫描子程序

/*延时子程序*/
void delay (uint k)
{
uchar j;
while((k--)!=0)
{
for(j=0;j<125;j++)
{;}
}
}

/*时间处理子程序*/
void time_pro(void)
{
if(seconde==60)
{
seconde=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
/*显示子程序*/
void display(void)
{
if(P1_3==1)
{
P2=0XFE;
P0=dispcode[seconde%10];//秒个位
delay(1);
P2=0XFD;
P0=dispcode[seconde/10];//秒十位
delay(1);
P2=0XFB;
P0=dispcode[10];//间隔符 -
delay(1);
P2=0XF7;
P0=dispcode[minite%10];//分个位
delay(1);
P2=0XEF;
P0=dispcode[minite/10];//分十位
delay(1);
P2=0XDF;
P0=dispcode[10];//间隔符 -
delay(1);
P2=0XBF;
P0=dispcode[hour%10];//时个位
delay(1);
P2=0X7F;
P0=dispcode[hour/10];//时十位
delay(1);
}
}
/*键盘扫描子程序*/
void keyscan(void)
{
if(P1_0==0)//秒位的调整
{
delay(30);
if(P1_0==0)
{
seconde++;
if(seconde==60)
{
seconde=0;
}
}
delay(250);
}
if(P1_1==0)//分位的调整
{
delay(30);
if(P1_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
}
delay(250);
}
if(P1_2==0)//时位的调整
{
delay(30);
if(P1_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
}
delay(250);
}
}
/*整点报警*/
void zhengdian (void)
{
if((seconde==0)&(minite==0))//整点报时
{
P1_5=0;
delay(1000);
P1_5=1;
}
}
/*定时闹钟*/
void dingshi(void)
{
if(P1_3==0)//按住P1_3BU不松,显示闹铃设置界面,分别按P1_6、P1_7设置闹铃时间。
{
P2=0XFE;
P0=dispcode[0];//秒个位
delay(1);
P2=0XFD;
P0=dispcode[0];//秒十位
delay(1);
P2=0XFB;
P0=dispcode[10];//间隔符 -
delay(1);
P2=0XF7;
P0=dispcode[fen%10];//分个位
delay(1);
P2=0XEF;
P0=dispcode[fen/10];//分十位
delay(1);

P2=0XDF;
P0=dispcode[10];//间隔符 -
delay(1);

P2=0XBF;
P0=dispcode[shi%10];//时个位
delay(1);
P2=0X7F;
P0=dispcode[shi/10];//时十位
delay(1);
}
if(P1_6==0)//设定时
{
delay(30);
if(P1_6==0)
{
shi++;
if(shi==24)
{
shi=0;
}
}
delay(250);
}
if(P1_7==0)//设定分
{
delay(30);
if(P1_7==0)
{
fen++;
if(fen==60)
{
fen=0;
}
}
delay(250);
}
if((hour==shi)&(minite==fen)&(seconde==0))//闹铃时间到,报警六十次。
{
for(bjcs=0;bjcs<60;bjcs++)
{
P1_5=0;
delay(500);
P1_5=1;
delay(500);
}
}
}
/*主函数*/
void main(void)
{
P1=0XFF;
TMOD = 0x11; //time0为定时器,方式1
TH0=0x3c; //预置计数初值,50ms
TL0=0xb0;
EA=1; //总中断开
ET0=1; //允许定时器0中断
TR0=1; //开启定时器0
while (1)
{

keyscan(); //按键扫描
dingshi();//定时闹钟
zhengdian();//整点报时
display(); //显示时间
}
}

void timer0(void) interrupt 1 //定时器0方式1,50ms中断一次
{
TH0=0x3c; //手动加载计数脉冲次数
TL0=0xb0;
TMOD=0x11;
mstcnt++; //用于计算时间,每隔50ms加1
if(mstcnt==20)//mstcnt满20即为一秒
{
seconde++;//秒+1
time_pro( ); //时间处理
mstcnt=0; //对计数单元的清零,重新开始计数
}

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • devmiao devmiao 4年前
  • qq_21193563 JasonHuo_ 4年前

    首先你这个一看就知道是51单片机的程序,你得要先考虑掉电保持这个功能,可以外接一个eeprom来保存数据(通常是i2c)保存数据,你可以通过。
    还有51单片机如果要用来做时钟的话,最后在外部家一个rtc时钟模块,这样连eeprom都不需要了。
    假如你都不想用,也是有办法的:
    可以将芯片内部rom空间开辟一些空间出来存储时钟数据。然后不断的更新那个地方的数据。你串口接受到的时钟数据修改运行时读取的内存数据便可

    点赞 评论 复制链接分享
  • tianxj001 tianxj001 4年前

    你定义了几个系统变量
    uchar seconde=0;//秒
    uchar minite=0;//分
    uchar hour=12; //时
    通过串口修改这些变量,就可以达到你要的目的。
    首先,你得编写串口初始化,使能串口,规定串口硬件协议内容如波特率、数据位停止位、奇偶校验,这个必须串口双方一致。
    其次,你得自己做一个数据传输协议,类似传统的串口AT命令集,比如规定字符串“ho”前缀为调整hour,“se”前缀为调整seconde----,并确定每次传输的字节数,这个可以通过你定义的前缀字符串和被调整目标单元字长确定。这里比如定义了前缀为2个char.目标单元为一个char,校验补数为一个char。那么每次约定的传输就是4个字节。
    为了保险,最好有一个约定的校验,比如校验和=0只有控制符+目标数据+校验补数的校验和=0,才是合法数据,等等。
    单片机打开串口接受中断,在收到字符串后,进行上述判断校验后,直接可以控制时分秒目标单位的值就可以了,

    点赞 1 评论 复制链接分享

为你推荐