找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2115|回复: 8
收起左侧

新人课程设计。单片机电子时钟问题。

[复制链接]
ID:348416 发表于 2018-6-9 21:13 | 显示全部楼层 |阅读模式
400黑币


本来已经完成了但是又加上一条串口直接设置定时时间,并实时显示剩余时间。理论本来就没弄太懂,跌跌撞撞完成了。但是加上又难弄了。

原来的仿真图

原来的仿真图

按键的效果

按键的效果



在这个的基础上可以修改吗?   3.1口修改时分秒,dp是选择的标志。3.2  3.3口是加和减  外部中断控制的。这是本来的电子时钟。现在还要加上新串口直接定时显示剩余时间,不知道怎么弄了。
下面是目前的程序         希望有人能帮助一下。




#include<reg51.h>

#define uchar unsigned char

#define uint  unsigned int

sbit k1=P3^1;  //第一个按键,选择设置

uchar code distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管段码表

uchar disbuf[8]; //声明显示缓冲区8个单元

uchar hour=12;   //声明小时变量,初值为12

uchar minute=59; //声明分变量,初值为59

uchar second;    //声明秒变量

uchar t0n;       //定时器T0中断计数,定时50ms,中断20次为1秒

uchar dis;       //调时状态下,显示小数点位

void delay()     //延时子程序,用于显示子程序

{

uint j;

for(j=300;j>0;j--);

}

//显示子程序,参数dis为显示小数点位

void display(uchar dis)

{

uchar j,disbit=0x01; //位码

for(j=0;j<8;j++)

{

P2=~disbit;       //P2口输出位码

if(dis>0&&dis==j) //调时状态下,显示小数点

P0=distab[disbuf[j]]+0x80; //在小时,分,秒位上显示小数点

else

P0=distab[disbuf[j]]; //其它位正常显示

disbit<<=1;           //取下一个位码

delay();              //延时

}

}

void main()

{

disbuf[2]=disbuf[5]=10;//数码管第3,6位显示-

TMOD=0x01;

TH0 =0x3C;    //单片机晶振频率=12M,定时50ms,时间常数=3CB0

TL0 =0xB0;

IE  =0x82;    //开定时器T0中断

TR0 =1;       //启动定时器T0

IT0 =1;       //设置外部中断为下降沿有效

IT1 =1;

while(1)

{

display(dis); //调显示子程序

if(k1==0)     //选择设置

{

dis++;    //停止计时,进入调时状态

EX0=1;    //调时状态下,允许外部INT0,INT1中断

EX1=1;    //用来调小时,分,秒

if(dis>7) //调小时,在小时位显示小数点

{

dis=0; //灭小数点

t0n=0; //调时结束,开始计时

TR0=1;

EX0=0; //关外部中断

EX1=0;

}

else if(dis==2)dis=4; //调分,在分位显示小数点

else if(dis==5)dis=7; //调秒,在秒位显示小数点

while(k1==0)display(dis); //等待按键释放

}

if(t0n>=20&&dis==0) //中断20次,1秒到,计时状态下时钟计时

{

t0n=0;

second++;      //秒加1

if(second>=60) //到60秒

{

second=0;

minute++;      //分加1

if(minute>=60) //到60分

{

minute=0;

hour++;    //小时加1

if(hour>=24)

hour=0;

}

}

}

disbuf[0]=hour/10;    //显示小时十位

disbuf[1]=hour%10;    //显示小时个位

disbuf[3]=minute/10;  //显示分十位

disbuf[4]=minute%10;  //显示分个位

disbuf[6]=second/10;  //显示秒十位

disbuf[7]=second%10;  //显示秒个位

}

}

//定时器T0中断服务子程序

void T0_isr() interrupt 1

{

TH0=0x3C;  //重写时间常数

TL0=0xb0;

t0n++;     //中断次加1

}

//外部中断INT0服务程序,调时状态下,加1

void INT0_ISR() interrupt 0

{

if(dis==1)     //调小时

{

hour++;    //小时加1

if(hour>=24)

hour=0;

}

if(dis==4)     //调分

{

minute++;  //分加1

if(minute>=60)

minute=0;

}

if(dis==7)     //调秒

{

second++;  //秒加1

if(second>=60)

second=0;

}

}

//外部中断INT1服务程序,调时状态下,减1

void INT1_ISR() interrupt 2

{

if(dis==1)   //调小时

{

hour--;  //小时减1

if(hour==0xff)

hour=23;

}

if(dis==4)    //调分

{

minute--; //分减1

if(minute==0xff)

minute=59;

}

if(dis==7)   //调秒

{

second--;//秒减1

if(second==0xff)

second=59;

}

}






评分

参与人数 1黑币 +5 收起 理由
hzy123 + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:303383 发表于 2018-6-9 22:56 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

ID:272269 发表于 2018-6-10 14:38 | 显示全部楼层
串口是什么串口是通讯还是什么?
你要的是倒计时在数码管上显示吗?
还是增加多一个模式?
回复

使用道具 举报

ID:348416 发表于 2018-6-10 16:46 | 显示全部楼层
jizi 发表于 2018-6-10 14:38
串口是什么串口是通讯还是什么?
你要的是倒计时在数码管上显示吗?
还是增加多一个模式?

多加一个模式,在数码管显示倒计时。  倒计时时间可以设置的。
回复

使用道具 举报

ID:336165 发表于 2018-6-13 13:43 | 显示全部楼层
你这个的具体功能是什么
回复

使用道具 举报

ID:193818 发表于 2018-6-13 14:17 | 显示全部楼层
1.我先提一点,楼主应该不打算做实物吧?因为做实物的画,你的数码管驱动电路需要重新设计下。
2.你现在是一般时钟,需要外加一个功能,我不清楚你说的串口是啥。姑且认为你是说按键,通过按键切换到这个模式,然后设计相应位置,再确定。这里应该还需要一个中断,然后用另一个定时器。当中断触发时数码管显示倒计时模式,然后你设置运行,当倒计时结束后,中断结束返回时钟画面。个人愚见

评分

参与人数 1黑币 +8 收起 理由
hedianzi + 8 绝世好帖!

查看全部评分

回复

使用道具 举报

ID:351040 发表于 2018-6-13 17:30 | 显示全部楼层
多加一个显示倒计时
回复

使用道具 举报

ID:324844 发表于 2018-6-27 09:32 | 显示全部楼层
在P3^4上加上一个按键命名为k2,k2锁死就会自动倒计时,k2打开就恢复,可以直接先用你的k1中断0中断1设置时间再锁死k2,也可以先锁死再用你的k1和中断0中断1调整
#include<reg51.h>

#define uchar unsigned char//宏替换

#define uint  unsigned int

sbit k1=P3^1;             //第一个按键,选择设置
sbit k2=P3^4;
bit c;
uchar code distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管段码表(0-9,-)

uchar disbuf[8];         //声明显示缓冲区8个单元
uchar hour=12;          //声明小时变量,初值为12

uchar minute=59;        //声明分变量,初值为59

uchar second;           //声明秒变量

uchar t0n;              //定时器T0中断计数,定时50ms,中断20次为1秒

uchar dis;             //调时状态下,显示小数点位

void delay()          //延时子程序,用于显示子程序

{

uint j;

for(j=300;j>0;j--);

}

                      //显示子程序,参数dis为显示小数点位

void display(uchar dis) // ????????????????????????????

{

uchar j,disbit=0x01;  //位码(未知)

for(j=0;j<8;j++)

{

P2=~disbit;       //P2口输出位码

if(dis>0&&dis==j) //调时状态下,显示小数点(看不懂)

P0=distab[disbuf[j]]+0x80; //在小时,分,秒位上显示小数点

else

P0=distab[disbuf[j]]; //其它位正常显示

disbit<<=1;           //取下一个位码

delay();              //延时

}

}

void main()//主函数

{

disbuf[2]=disbuf[5]=10;//数码管第3,6位显示-

TMOD=0x01;  //t0定时器方式1

TH0 =0x3C;    //单片机晶振频率=12M,定时50ms,时间常数=3CB0

TL0 =0xB0;

IE  =0x82;    //开定时器T0中断(EX1外部中断1没开)

TR0 =1;       //启动定时器T0

IT0 =1;       //设置外部中断为下降沿有效

IT1 =1;

while(1)

{

display(dis); //调显示子程序(未知)

if(k1==0)     //选择设置

{

dis++;    //停止计时,进入调时状态(暂停了秒计时)

EX0=1;    //调时状态下,允许外部INT0,INT1中断

EX1=1;    //用来调小时,分,秒

if(dis>7) //调小时,在小时位显示小数点

{

dis=0; //灭小数点

t0n=0; //调时结束,开始计时

TR0=1;

EX0=0; //关外部中断

EX1=0;

}

else if(dis==2)dis=4; //调分,在分位显示小数点

else if(dis==5)dis=7; //调秒,在秒位显示小数点

while(k1==0)display(dis); //等待按键释放

}
//这里做改动
if(c==0);
{
if(t0n>=20&&dis==0) //中断20次,1秒到,计时状态下时钟计时

{

t0n=0;

second++;      //秒加1

if(second>=60) //到60秒

{

second=0;

minute++;      //分加1

if(minute>=60) //到60分

{

minute=0;

hour++;    //小时加1

if(hour>=24)

hour=0;

}

}
}
}
if(k2==0)
{
c=~c;
ET0=~ET0;
while(k1==0)display(dis);
}
if(c==1)
{

second--;      //秒加1

if(second==0xff) //到60秒

{

second=59;

minute--;      //分加1

if(minute==0xff) //到60分

{

minute=59;

hour--;    //小时加1

if(hour==0xff)

hour=23;

}
}
}


disbuf[0]=hour/10;    //显示小时十位

disbuf[1]=hour%10;    //显示小时个位

disbuf[3]=minute/10;  //显示分十位

disbuf[4]=minute%10;  //显示分个位

disbuf[6]=second/10;  //显示秒十位

disbuf[7]=second%10;  //显示秒个位

}

}

//定时器T0中断服务子程序

void T0_isr() interrupt 1

{

TH0=0x3C;  //重写时间常数

TL0=0xb0;

t0n++;     //中断次加1

}

//外部中断INT0服务程序,调时状态下,加1

void INT0_ISR() interrupt 0

{

if(dis==1)     //调小时

{

hour++;    //小时加1

if(hour>=24)

hour=0;

}

if(dis==4)     //调分

{

minute++;  //分加1

if(minute>=60)

minute=0;

}

if(dis==7)     //调秒

{

second++;  //秒加1

if(second>=60)

second=0;

}

}

//外部中断INT1服务程序,调时状态下,减1

void INT1_ISR() interrupt 2

{

if(dis==1)   //调小时

{

hour--;  //小时减1

if(hour==0xff)

hour=23;

}

if(dis==4)    //调分

{

minute--; //分减1

if(minute==0xff)

minute=59;

}

if(dis==7)   //调秒

{

second--;//秒减1

if(second==0xff)

second=59;

}

}

]4FU{4{@BOYR16ES6]9K_US.png

时钟.rar

18.3 KB, 下载次数: 4

回复

使用道具 举报

ID:324844 发表于 2018-6-27 11:08 | 显示全部楼层
加P3^4一个按键定义为k2,该按键锁死则开始从当前时间倒计时,释放则恢复正常时钟。可以先用你的k1,中断0和1进行设置定时时间,再锁死,也可以锁死再实时设置
#include<reg51.h>

#define uchar unsigned char//宏替换

#define uint  unsigned int

sbit k1=P3^1;             //第一个按键,选择设置
sbit k2=P3^4;
bit c;
uchar code distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管段码表(0-9,-)

uchar disbuf[8];         //声明显示缓冲区8个单元
uchar hour=12;          //声明小时变量,初值为12

uchar minute=59;        //声明分变量,初值为59

uchar second;           //声明秒变量

uchar t0n;              //定时器T0中断计数,定时50ms,中断20次为1秒

uchar dis;             //调时状态下,显示小数点位

void delay()          //延时子程序,用于显示子程序

{

uint j;

for(j=300;j>0;j--);

}

                      //显示子程序,参数dis为显示小数点位

void display(uchar dis) // ????????????????????????????

{

uchar j,disbit=0x01;  //位码(未知)

for(j=0;j<8;j++)

{

P2=~disbit;       //P2口输出位码

if(dis>0&&dis==j) //调时状态下,显示小数点(看不懂)

P0=distab[disbuf[j]]+0x80; //在小时,分,秒位上显示小数点

else

P0=distab[disbuf[j]]; //其它位正常显示

disbit<<=1;           //取下一个位码

delay();              //延时

}

}

void main()//主函数

{

disbuf[2]=disbuf[5]=10;//数码管第3,6位显示-

TMOD=0x01;  //t0定时器方式1

TH0 =0x3C;    //单片机晶振频率=12M,定时50ms,时间常数=3CB0

TL0 =0xB0;

IE  =0x82;    //开定时器T0中断(EX1外部中断1没开)

TR0 =1;       //启动定时器T0

IT0 =1;       //设置外部中断为下降沿有效

IT1 =1;

while(1)

{

display(dis); //调显示子程序(未知)

if(k1==0)     //选择设置

{

dis++;    //停止计时,进入调时状态(暂停了秒计时)

EX0=1;    //调时状态下,允许外部INT0,INT1中断

EX1=1;    //用来调小时,分,秒

if(dis>7) //调小时,在小时位显示小数点

{

dis=0; //灭小数点

t0n=0; //调时结束,开始计时

TR0=1;

EX0=0; //关外部中断

EX1=0;

}

else if(dis==2)dis=4; //调分,在分位显示小数点

else if(dis==5)dis=7; //调秒,在秒位显示小数点

while(k1==0)display(dis); //等待按键释放

}
//这里做改动
if(c==0);
{
if(t0n>=20&&dis==0) //中断20次,1秒到,计时状态下时钟计时

{

t0n=0;

second++;      //秒加1

if(second>=60) //到60秒

{

second=0;

minute++;      //分加1

if(minute>=60) //到60分

{

minute=0;

hour++;    //小时加1

if(hour>=24)

hour=0;

}

}
}
}
if(k2==0)
{
c=~c;
ET0=~ET0;
while(k1==0)display(dis);
}
if(c==1)
{

second--;      //秒加1

if(second==0xff) //到60秒

{

second=59;

minute--;      //分加1

if(minute==0xff) //到60分

{

minute=59;

hour--;    //小时加1

if(hour==0xff)

hour=23;

}
}
}


disbuf[0]=hour/10;    //显示小时十位

disbuf[1]=hour%10;    //显示小时个位

disbuf[3]=minute/10;  //显示分十位

disbuf[4]=minute%10;  //显示分个位

disbuf[6]=second/10;  //显示秒十位

disbuf[7]=second%10;  //显示秒个位

}

}

//定时器T0中断服务子程序

void T0_isr() interrupt 1

{

TH0=0x3C;  //重写时间常数

TL0=0xb0;

t0n++;     //中断次加1

}

//外部中断INT0服务程序,调时状态下,加1

void INT0_ISR() interrupt 0

{

if(dis==1)     //调小时

{

hour++;    //小时加1

if(hour>=24)

hour=0;

}

if(dis==4)     //调分

{

minute++;  //分加1

if(minute>=60)

minute=0;

}

if(dis==7)     //调秒

{

second++;  //秒加1

if(second>=60)

second=0;

}

}

//外部中断INT1服务程序,调时状态下,减1

void INT1_ISR() interrupt 2

{

if(dis==1)   //调小时

{

hour--;  //小时减1

if(hour==0xff)

hour=23;

}

if(dis==4)    //调分

{

minute--; //分减1

if(minute==0xff)

minute=59;

}

if(dis==7)   //调秒

{

second--;//秒减1

if(second==0xff)

second=59;

}

}

]4FU{4{@BOYR16ES6]9K_US.png

时钟.rar

18.3 KB, 下载次数: 4

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表