找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机定时器内无法调用数码管子程序吗?

[复制链接]
跳转到指定楼层
楼主
ID:1055885 发表于 2023-2-16 22:00 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
数码管延时我用的定时器1,程序是每隔一秒数码管加一,LED亮灭一次,如果在主程序内调用数码管就能正常工作,放到任意一个定时器内调用都不行,有没有大神能解解惑,或者我想让数码管全程显示,后期主程序内会有其他循环程序,如果一次次调用太麻烦,有没有什么别的办法让数码管全程显示而不影响主程序的方法?(文化水平不高,代码编的有点菜,望见谅)

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit wei=P2^7;//位选,第几个数码管亮
sbit duan=P2^6;
sbit D1=P1^1;
uint xianshu,shi,ge,bai,qian,wan;
uint aa,s,bb;
uchar y;
uchar code smb[]={  //数码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void xshu(uint ge,uint shi,uint bai,uint qian,uint wan);
void delay(uint);//延时子程序声明
void chushi();//初始化子程序声明
void main()
{
        chushi();
delay(10);
        while(1)
        {
//                xshu(ge,shi,bai,qian,wan);//调用显示子程序

                if(aa>=10)//定时器进入10次中断
                {
                        D1=1;
                        if(aa>=19)//定时器进入19次中断
                        {
                                D1=0;//点亮LED
                                aa=0;//定时器进入中断数清零
                                s++;//数码管显示的数字
                        }

                }
        }
}

void chushi()//初始化子程序
{
        xianshu=0;
        TMOD=0x01;
        EA=1;//全局中断总开关
        TH0=(65536-46072)/256;//装入初值
        TL0=(65536-46072)%256;
        TR0=1;//打开定时器0
        ET0=1;//定时器0允许中断开关
        TH1=(65536-5072)/256;//装入初值
        TL1=(65536-5072)%256;
        TR1=1;//打开定时器1
        ET1=1;//定时器0允许中断开关

}

void timer0() interrupt 1 //定时器0中断服务程序
{
        TH0=(65536-46072)/256;//进入定时器服务函数后,需要重新装入初值
        TL0=(65536-46072)%256;
        aa++;

                xshu(ge,shi,bai,qian,wan);//调用数码管子程序
}

void timer1() interrupt 3 //定时器1中断服务程序
{
        TH1=(65536-5072)/256;//进入定时器服务函数后,需要重新装入初值
        TL1=(65536-5072)%256;
        y++;

}

void Delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}

void xshu(uint ge,uint shi,uint bai,uint qian,uint wan)//数码管显示子程序
{
        if(s==65000)//最大65535
        {
                s=0;//数码管显示清零
        }
        xianshu=s;//让数码管显示脉冲s的数量

        wan=xianshu/10000;
        qian=xianshu%10000/1000;
        bai=xianshu%10000%1000/100;
        shi=xianshu%10000%1000%100/10;
        ge=xianshu%10;

        if(s>=10000)
                {
                        wei=1;
                        P0=0xfd;
                        wei=0;
               
                        duan=1;
                        P0=smb[wan];
                        duan=0;       
                        y=0;//进中断数清零
                        while(y<=10);//延时
                        P0=0xff;   //消影

                }       
        if(s>=1000)
                {
                        wei=1;
                        P0=0xfb;
                        wei=0;
               
               
                        duan=1;
                        P0=smb[qian];
                        duan=0;               
                        y=0;//进中断数清零
                        while(y<=10);//延时
                        P0=0xff;   //消影
                }
       
        if(s>=100)
                {
                        wei=1;
                        P0=0xf7;
                        wei=0;
               
                        duan=1;
                        P0=smb[bai];
                        duan=0;               
                        y=0;//进
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1055885 发表于 2023-2-16 22:14 来自手机 | 只看该作者
用的单片机为89c52rc
回复

使用道具 举报

板凳
ID:86926 发表于 2023-2-17 08:15 | 只看该作者
注意定时器优先级问题,y在T1,显示在T0,T0内while循环y,T1不能中断T0,所以y一直是0跑不下去了
回复

使用道具 举报

地板
ID:459275 发表于 2023-2-17 08:30 | 只看该作者
TMOD=0x01;    ???
回复

使用道具 举报

5#
ID:213173 发表于 2023-2-17 09:05 | 只看该作者

只要掌握时间和逻辑关系,显示函数放在那里都可以。给你改了你试试。

  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit wei=P2^7;//位选,第几个数码管亮
  5. sbit duan=P2^6;
  6. sbit D1=P1^1;
  7. //uint xianshu,shi,ge,bai,qian,wan;
  8. uint aa,s,bb;
  9. uchar y;
  10. uchar code smb[]={  //数码表
  11. 0x3f,0x06,0x5b,0x4f,
  12. 0x66,0x6d,0x7d,0x07,
  13. 0x7f,0x6f,0x77,0x7c,
  14. 0x39,0x5e,0x79,0x71};
  15. uchar data buf[5];

  16. void xshu();
  17. void delay(uint);//延时子程序声明
  18. void chushi();//初始化子程序声明
  19. void main()
  20. {
  21.         chushi();
  22.         delay(10);
  23.         while(1)
  24.         {
  25.                 //xshu(ge,shi,bai,qian,wan);//调用显示子程序
  26.                 if(aa<125)//定时器进入125次中断
  27.                 {
  28.                         D1=0;
  29.                 }
  30.                 else D1=1;

  31.                 if(aa>=250)//定时器进入250次中断
  32.                 {
  33.                         aa=0;
  34.                         s++;//数码管显示的数字
  35.                 }
  36.                 if(s==65000)//最大65535
  37.                 {
  38.                         s=0;//数码管显示清零
  39.                 }
  40. //                xianshu=s;//让数码管显示脉冲s的数量       
  41.                 buf[0]=smb[s/10000%10];//按10进制数位分解
  42.                 buf[1]=smb[s/1000%10];
  43.                 buf[2]=smb[s/100%10];
  44.                 buf[3]=smb[s/10%10];
  45.                 buf[4]=smb[s%10];       
  46.         }
  47. }

  48. void chushi()//初始化子程序
  49. {
  50. //        xianshu=0;
  51.         TMOD=0x01;
  52.         EA=1;//全局中断总开关
  53. //        TH0=(65536-46072)/256;//装入初值
  54. //        TL0=(65536-46072)%256;
  55.         TH0=(65536-3686)/256;//装入初值4ms
  56.         TL0=(65536-3686)%256;
  57.         TR0=1;//打开定时器0
  58.         ET0=1;//定时器0允许中断开关
  59. //        TH1=(65536-5072)/256;//装入初值
  60. //        TL1=(65536-5072)%256;
  61. //        TR1=1;//打开定时器1
  62. //        ET1=1;//定时器0允许中断开关
  63. }

  64. void timer0() interrupt 1 //定时器0中断服务程序
  65. {
  66.         TH0=(65536-3686)/256;//装入初值4ms
  67.         TL0=(65536-3686)%256;
  68.         xshu();//调用数码管子程序
  69.         aa++;
  70. }
  71. /*
  72. void timer1() interrupt 3 //定时器1中断服务程序
  73. {
  74.         TH1=(65536-5072)/256;//进入定时器服务函数后,需要重新装入初值
  75.         TL1=(65536-5072)%256;
  76.         y++;
  77. }
  78. */
  79. void Delay(uint z)
  80. {
  81.         uint x,y;
  82.         for(x=z;x>0;x--)
  83.         for(y=110;y>0;y--);
  84. }

  85. void xshu()//数码管显示子程序
  86. {
  87.         duan=1;
  88.         P0=0x00;//段消隐
  89.         duan=0;      
  90.        
  91.         wei=1;
  92.         P0=~(0x01<<y);//传送位码
  93.         wei=0;
  94.        
  95.         duan=1;
  96.         P0=buf[y];//传送段码
  97.         duan=0;      
  98.             
  99.         y++;
  100.         if(y==5)//5次中断循环计数
  101.                 y=0;
  102. }
复制代码
回复

使用道具 举报

6#
ID:1055885 发表于 2023-2-17 10:10 来自手机 | 只看该作者
nj周宏达 发表于 2023-2-17 08:30
TMOD=0x01;    ???

这个本来是单定时器的,临时改成双定时器,忘了改,不过改了也还是不显示
回复

使用道具 举报

7#
ID:1055885 发表于 2023-2-17 10:13 来自手机 | 只看该作者
蓝魄 发表于 2023-2-17 08:15
注意定时器优先级问题,y在T1,显示在T0,T0内while循环y,T1不能中断T0,所以y一直是0跑不下去了

如果都放在T1,可行吗,因为T0要放其他更优先的程序
回复

使用道具 举报

8#
ID:1055885 发表于 2023-2-17 10:13 来自手机 | 只看该作者
wulin 发表于 2023-2-17 09:05
只要掌握时间和逻辑关系,显示函数放在那里都可以。给你改了你试试。

感谢,晚上回去试试
回复

使用道具 举报

9#
ID:1034262 发表于 2023-2-17 16:20 | 只看该作者
先在中断里取反一个IO确定中断已正常。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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