标题:
想做一个时间累加,到60后,清零的单片机程序,两位数时候出错
[打印本页]
作者:
shuai帅
时间:
2019-3-18 21:09
标题:
想做一个时间累加,到60后,清零的单片机程序,两位数时候出错
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit LED1=P1^0;
sbit wela=P2^6;
sbit dula=P2^7;
//void delayms(uint);
uchar num,shi,num,ge,num1;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71}; //显示0~F的十六进制的数;0 1 2 3 4 5 6 7 8 9
void delayms(uint xms) //延时函数
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void display(uchar shi, uchar ge)
{
dula=1;
P1=0xfe;
dula=0;
wela=1;
P0=table[shi]; //位选
wela=0;
delayms(5);
dula=1;
P1=0xfd;
dula=0;
wela=1;
P0=table[ge];
wela=0;
}
void main()
{
TMOD=0x01;
TH0=(65535-45872)/256; //付初值
TL0=(65535-45872)%256;
EA=1; //打开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0中断
while(1) //等待中断开启
{
display(shi,ge);
}
}
void T0_time() interrupt 1 //方式1
{
TH0=(65535-45872)/256; //付初值
TL0=(65535-45872)%256;
num++;
if(num==20)
{
num=0;
num1++;
if(num1==9)
{
num1=0;
}
shi=num1/10;
ge=shi;
}
}
作者:
shuai帅
时间:
2019-3-18 21:12
代码可以实现一位累加,但是两位数时候,累加总出现显示错误,不知道什么原因,求解答
作者:
niehaitao
时间:
2019-3-19 09:57
这是我学中断时候写的,你参考一下,这个程序在51HEL开发板验证过的,数码管从0到59累加后归零,归零的时候蜂鸣器响一声,希望可以帮到您
#include<reg52.h> //52系列单片机头文件
#include<math.h>
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
sbit DUAN=P2^6; //74HC573的LE端 U1 数码管LED的段选端
sbit WEI=P2^7; //74HC573的LE端 U1 数码管LED的位选端
sbit LED8=P2^4;
sbit FG=P2^2; //蜂鸣器和继电器的控制端
uchar num,num2,shi,ge;
uint num1;
void delayms(uint); //声明延时子函数
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}; //共阴显示字库
void display(uchar,uchar);
void main() //主函数
{
TMOD=0x11; //设置定时器0和1为工作方式1(0001 0001)
TH0=(65536-45872)/256; //装初值
TL0=(65536-45872)%256;
TH1=(65536-45872)/256; //装初值
TL1=(65536-45872)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
ET1=1; //开定时器1中断
TR0=1; //启动定时器0
TR1=1; //启动定时器1
while(1) //程序在这里不停的对数码管动态扫描同时等待中断发生
{
display(shi,ge);
}
}
void display(uchar shi,uchar ge) //显示子函数
{
DUAN=1; //打开段选
P0=table[shi]; //送段选数据
DUAN=0; //段选锁定
P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱
WEI=1; //打开位选
P0=0xfe; //送位选数据
WEI=0; //位选锁定
delayms(5); //延时
DUAN=1; //打开段选
P0=table[ge]; //送段选数据
DUAN=0; //段选锁定
P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过位选锁存器造成混乱
WEI=1; //打开位选
P0=0xfd; //送位选数据
WEI=0; //位选锁定
delayms(5); //延时
}
void delayms(uint xms) //延时子函数
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--); //i=xms即延时约xms毫秒
}
void T0_time()interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256; //重装初值
num1++;
if(num1==1200) //如果到了1200次,说明60秒时间到
{
num1=0; //然后把num1清0重新再计1200次
FG=~FG; //让蜂鸣器状态取反
delayms(100);
FG=~FG;
}
}
void T1_time() interrupt 3
{
TH1=(65536-45872)/256;
TL1=(65536-45872)%256; //重装初值
num2++;
if(num2==20) //如果到了20次,说明1秒时间到
{
num2=0; //然后把num2清0重新再计20次
num++;
if(num==60) //这个数用来送数码管显示,到60后归0
num=0;
shi=num/10; //把一个二位数分离后分别送数码管显示
ge=num%10; //十位和个位
}
}
作者:
zhb2004xp
时间:
2019-3-19 11:11
你的程序应该是50ms中断累加,1S计数每秒+1,你的程序
if(num1==9)
{
num1=0;
}
shi=num1/10;
ge=shi;
}
这里不对的,你要显示的是num1的值,按照你的设想就应该num1到60再进行清零,你这里到9就清零了。应该是if(num1==60),这样才能显示0~59
作者:
wulin
时间:
2019-3-19 12:54
你的中断程序和显示程序都有问题,给你改好了,你试试。
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
sbit LED1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
uchar num,num1,shi,ge;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71}; //显示0~F的十六进制的数;0 1 2 3 4 5 6 7 8 9
void delayms(uint xms) //延时函数
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void display(uchar i)
{
P0=0xfe;//送十位位码
wela=1;
wela=0;
P0=table[i/10];//送十位段码
dula=1;
dula=0;
delayms(2);
P0=0xfd;//送十位段码
wela=1;
wela=0;
P0=table[i%10];//送个位段码
dula=1;
dula=0;
delayms(2);
}
void main()
{
TMOD=0x01;
TH0=(65536-45872)/256; //赋初值
TL0=(65536-45872)%256;
EA=1; //打开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器0中断
while(1) //等待中断开启
{
display(num1);
}
}
void T0_time() interrupt 1 //方式1
{
TH0=(65536-45872)/256; //赋初值
TL0=(65536-45872)%256;
num++;
if(num==20)
{
num=0;
LED1=~LED1;//LED闪烁
num1++;
if(num1==60)
{
num1=0;
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1