找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1341|回复: 4
打印 上一主题 下一主题
收起左侧

想做一个时间累加,到60后,清零的单片机程序,两位数时候出错

[复制链接]
跳转到指定楼层
楼主
ID:384605 发表于 2019-3-18 21:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#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;
}

}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:384605 发表于 2019-3-18 21:12 | 只看该作者
代码可以实现一位累加,但是两位数时候,累加总出现显示错误,不知道什么原因,求解答
回复

使用道具 举报

板凳
ID:46220 发表于 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;                //十位和个位
                        }                       
}
回复

使用道具 举报

地板
ID:234075 发表于 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
回复

使用道具 举报

5#
ID:213173 发表于 2019-3-19 12:54 | 只看该作者
你的中断程序和显示程序都有问题,给你改好了,你试试。
  1. #include <reg52.h>
  2. typedef unsigned int uint;
  3. typedef unsigned char uchar;
  4. sbit LED1=P1^0;
  5. sbit dula=P2^6;
  6. sbit wela=P2^7;
  7. uchar num,num1,shi,ge;
  8. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
  9.      0x6d,0x7d,0x07,0x7f,0x6f,
  10.      0x77,0x7c,0x39,0x5e,0x79,0x71};  //显示0~F的十六进制的数;0 1 2 3 4 5 6 7 8 9

  11. void delayms(uint xms)   //延时函数
  12. {
  13.         uint i,j;
  14.         for(i=xms;i>0;i--)
  15.                 for(j=110;j>0;j--);
  16. }
  17. void display(uchar i)
  18. {
  19.         P0=0xfe;//送十位位码
  20.         wela=1;
  21.         wela=0;
  22.         P0=table[i/10];//送十位段码
  23.         dula=1;
  24.         dula=0;
  25.         delayms(2);
  26.        
  27.         P0=0xfd;//送十位段码
  28.         wela=1;
  29.         wela=0;
  30.         P0=table[i%10];//送个位段码
  31.         dula=1;
  32.         dula=0;
  33.         delayms(2);
  34. }

  35. void main()
  36. {
  37.         TMOD=0x01;
  38.         TH0=(65536-45872)/256;  //赋初值
  39.         TL0=(65536-45872)%256;
  40.         EA=1;      //打开总中断
  41.         ET0=1;      //开定时器0中断
  42.         TR0=1;      //启动定时器0中断
  43.         while(1)     //等待中断开启
  44.         {
  45.                 display(num1);
  46.         }     
  47. }
  48. void T0_time() interrupt 1     //方式1
  49. {
  50.         TH0=(65536-45872)/256;  //赋初值
  51.         TL0=(65536-45872)%256;
  52.         num++;
  53.         if(num==20)
  54.         {
  55.                 num=0;
  56.                 LED1=~LED1;//LED闪烁
  57.                 num1++;
  58.                 if(num1==60)
  59.                 {
  60.                         num1=0;
  61.                 }
  62.         }
  63. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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