用51单片机编写数字钟出问题了,求高手解答
发布网友
发布时间:2022-05-24 07:32
我来回答
共3个回答
热心网友
时间:2023-10-08 20:49
你在程序里的"shi""fen""miao"寄存器是按全局变量用的,所以在display()子程序中不要在设置形参了,直接修改这三个寄存器就好了。
另外注意定义变量时候的类型uchar和char
...
//void display(char shi,char fen,char miao)
void display()
...
//display(shi,fen,miao);
display();
...
附件里有改的程序,试了一下24MHz晶振下时间跑得有些快!
我又改了改程序,附加了Proteus仿真电路,新程序在clock_.c中。
/* 因为用的仿真电路不一样,所以rs和en引脚改P2口了 */
/* 1602有个rw读写使能端,加了个引脚控制 */
/* 我不知道这la和wela两个引脚的作用,所以临时换到P3口了 */
/* 在write_cmd和write_date的时序中加了rw读写使能 */
/* data是数据的意思 date是日期的意思 */
/* 把时分秒的显示都挪到最后了,前面的if条件语句只做时分秒数据的修改,这样能保证数据变0时显示正常 */
/* 把初始化往后挪了,方便调用其他子程序 */
/* 每条write_cmd或write_data的最后都已将en=0,所以不用在其他位置设置en=0了 */
/* 初始化子程序的最后加了一条display指令,用来将显示刷新成既定时刻 */
/* 主程序中设置了时钟时间初始值,以观察时间能否正常变化 */
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=" 2013-11-10";
uchar code table1[]=" 00:00:00";
/* 因为用的仿真电路不一样,所以rs和en引脚改P2口了 */
//sbit rs=P3^5;
//sbit en=P3^4;
sbit rs=P2^5;
sbit en=P2^6;
/* 1602有个rw读写使能端,加了个引脚控制 */
sbit rw=P2^7;
/* 我不知道这两个引脚的作用,所以临时换到P3口了 */
sbit la=P3^6;
sbit wela=P3^7;
uchar num,i,temp,shi,fen,miao;
//延时
void delay()
{
uchar i,j;
for(i=10;i>0;i--)
for(j=110;j>0;j--);
}
//程序写指令
void write_cmd(uchar cmd)
{
rs=0;
/* 加了rw读写使能 */
rw=0;
en=0;
P0=cmd;
en=1;
delay();
en=0;
}
//数据写指令
void write_date(uchar date)/* data是数据的意思 date是日期的意思 */
{
rs=1;
/* 加了rw读写使能 */
rw=0;
en=0;
P0=date;
en=1;
delay();
en=0;
}
//时/分/秒按十进制显示
void sfm(char add,char dat)
{
char shi,ge;
shi=dat/10;
ge=dat%10;
write_cmd(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
//显示
//void display(char shi,char fen,char miao)
void display()
{
if(temp==20)
{
temp=0;
miao++;
//sfm(10,miao);
if(miao==60)
{
miao=0;
fen++;
//sfm(7,fen);
if(fen==60)
{
fen=0;
shi++;
//sfm(4,shi);
if(shi==24)
{
shi=0;
}
}
}
}
/* 把时分秒的显示都挪到最后了,前面的if条件语句只做时分秒数据的修改,这样能保证数据变0时显示正常 */
sfm(10,miao);
sfm(7,fen);/* 显示的相对位置改了一下 */
sfm(4,shi);/* 显示的相对位置改了一下 */
}
//定时器0中断
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
temp++;
}
//初始化
/* 把初始化往后挪了,方便调用其他子程序 */
void init()
{
la=0;
wela=0;
write_cmd(0x38);
write_cmd(0x06);
write_cmd(0x0c);
write_cmd(0x01);
//en=0;/* 每条write_cmd或write_data的最后都已将en=0,所以在此不用在设置en=0了 */
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
write_cmd(0x80);
for(num=0;num<13;num++)
{
write_date(table[num]);
delay();
}
write_cmd(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay();
}
/* 最后加了一条display指令,用来将显示刷新成既定时刻 */
display();
}
//主函数
void main()
{
/* 主程序中设置了时钟时间初始值,以观察时间能否正常变化 */
shi=23;
fen=59;
miao=55;
init();
while(1)
{
//display(shi,fen,miao);
display();
}
}
热心网友
时间:2023-10-08 20:49
您定义了全局变量shi,fen,miao, display函数定义 中的参数也是shi,fen,miao,计时动作是在display中做的,对函数内部的 shi,fen,miao的操作不会改变全局的shi,fen,miao,
下次用display(shi,fen,miao);调用display时,从未被改变过的全局变量的值又赋给display内部的局部变量,所以就没法计时了。
一种笨修改方法是去掉 display 的参数,定义那行改为
void display()// (char shi,char fen,char miao)
调用改为
void display()// (char shi,char fen,char miao)
这样就工作正常了,仿真效果如下:
热心网友
时间:2023-10-08 20:50
大致看了下,貌似你的1秒中断没有进去啊。。。。好久没整了 你可以单步调试看下,。哪个环节出问题了