找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3997|回复: 5
收起左侧

51单片机如何用定时中断代替延时

[复制链接]
ID:765181 发表于 2020-5-30 17:30 | 显示全部楼层 |阅读模式
//用计数器统计的数量,用定时器在数码管上显示数量,用外部中断清空
//师傅的意思是想让我们把显示函数丢到中断里边好从delay中解脱出来,可楼主太菜了,悟不到555
#include<reg51.h>
#include<stdio.h>
unsigned char dis;
//sbit relay = P1^0;
unsigned char code nondis[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9
//延时
void delay(unsigned int n)
{
        unsigned int i=0,j=0;
for(i=0;i<n;i++)
        {
        for(j=0;j<120;j++);
        }
}
//显示函数
        void display()
        {
        unsigned char gewei,shiwei,baiwei;
//        num1=256-TL0;
//        num=9-num1;
        baiwei=TL0/100;
        gewei=TL0%10;
        shiwei=(TL0/10)%10;
        P2=nondis[gewei];//个位
        P0=0x80;
        delay(10);
        P2=0xff;
        P2=nondis[shiwei];//十位
        P0=0x40;
        delay(10);
        P2=0xff;
        P2=nondis[baiwei];//百位
        P0=0x20;
        delay(10);
        P2=0xff;
        }
                       
                        void main(void)
                        {
                                        P0=0x80;
                                        EA = 1;
                                        ET0 = 1;
                                        EX0 = 1;
                                        IT0 = 1;
                                        ET0 = 0;
                                        TMOD = 0x06;
                                        TH0 = 0;//9
                                        TL0 = 0;//9
                                        TR0 = 1;
                                while(1)
                                {
                        display();//显示函数
                                }
                        }

void int0() interrupt 0        // 清空
                        {
                        TL0 = 0 ;
                        }

//void counter1() interrupt 1
//{
//        relay = ~relay;
//}

回复

使用道具 举报

ID:765181 发表于 2020-5-30 17:33 | 显示全部楼层
这是仿真的图哥哥们

图是这样一个开关按一下加一,一个清空

图是这样一个开关按一下加一,一个清空
回复

使用道具 举报

ID:765181 发表于 2020-5-30 18:41 | 显示全部楼层
//按普中的视频改了改不知道行不行
#include<reg51.h>
#include<stdio.h>
unsigned char dis;
//sbit relay = P1^0;
unsigned char code nondis[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9

                //定时器1初始化
                void timerinit()
                {
                TMOD|=0X10;
                TH1=0xFC;
                TL1=0x18;
                ET1=1;
                EA=1;
                TR1=1;
                }
                       
                        void main(void)
                        {
                                        P0=0x80;
                                        EA = 1;
                                        ET0 = 1;
                                        EX0 = 1;
                                        IT0 = 1;
                                        ET0 = 0;
                                        TMOD = 0x06;
                                        TH0 = 0;//9
                                        TL0 = 0;//9
                                        TR0 = 1;
                        timerinit();
                                while(1);
                       
                        }

void int0() interrupt 0        // 清空
                        {
                        TL0 = 0 ;
                        }

//void counter1() interrupt 1
//{
//        relay = ~relay;
//}
void Time1() interrupt 3        // 清空
                        {
                        static unsigned short i;
                        unsigned char gewei,shiwei,baiwei;
                          
                                baiwei=TL0/100;
                                gewei=TL0%10;
                                shiwei=(TL0/10)%10;
                       
                        TH1=0xFC;
                        TL1=0x18;
                        i++;
                        if(i==10)
                        {
                          
                                  P2=0xff;       
                          P2=nondis[gewei];//个位
                          P0=0x80;

                        }
                                                if(i==20)
                        {
                          
                                  P2=0xff;
                          P2=nondis[shiwei];//十位
                                P0=0x40;

                        }
                                                if(i==30)
                        {         i=0;
                                P2=0xff;
                                  P2=nondis[baiwei];//百位
                                P0=0x20;

                        }
                        }

回复

使用道具 举报

ID:162664 发表于 2020-5-30 22:07 | 显示全部楼层
很久项目不用io口扫数码管了。有点不知道怎么说。
简单说:
1:io口扫描数码管要注意是扫描的时间间隔。
满足扫描间隔的前提下,如果主循环里有ALU占用时间过长的函数,那么数码管扫描的程序放到中断里扫描来满足扫描时间的间隔。(假设在突发情况下,一个模拟iic的流程可能会占用5ms时间,那么,有可能就会因为这个导致数码管亮度异常或者闪烁)
2:看了一眼程序,改进的程序中放在中断中的程序已经把每一位的扫描分时出来了。如果时序没问题是可以的。修改意见:定时器的时间注释出来;if 改成 siwtch 语句(我觉得相对直观);电路有问题,一般不这么设计,至于为什么自己去看看三极管一般怎么用。
回复

使用道具 举报

ID:213173 发表于 2020-5-30 22:43 | 显示全部楼层
BilibiliGiao 发表于 2020-5-30 17:33
这是仿真的图哥哥们

没有必要把显示程序放在中断,稍微改一下即可不用delay。 无标题.jpg

  1. #include<reg51.h>
  2. #include<stdio.h>
  3. unsigned char i;
  4. //sbit relay = P1^0;
  5. unsigned char code nondis[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9
  6. //延时
  7. /*
  8. void delay(unsigned int n)
  9. {
  10.         unsigned int i=0,j=0;
  11.         for(i=0;i<n;i++)
  12.                 for(j=0;j<120;j++);
  13. }*/
  14. //显示函数
  15. void display()
  16. {
  17.         P2=0xff;//消隐
  18.         if(i==0)
  19.         {
  20.                 P0=0x20;
  21.                 P2=nondis[TL0/100%10];//百位
  22.         }
  23.         if(i==1)
  24.         {
  25.                 P0=0x40;
  26.                 P2=nondis[TL0/10%10];//十位
  27.         }
  28.         if(i==2)
  29.         {
  30.                 P2=nondis[TL0%10];//个位
  31.                 P0=0x80;
  32.         }
  33.         i++;
  34.         i%=3;
  35. }

  36. void main(void)
  37. {
  38. //        P0=0x80;
  39.         TMOD = 0x06;
  40.         TH0 = 0;//9
  41.         TL0 = 0;//9
  42.         TR0 = 1;
  43.         EA = 1;
  44. //        ET0 = 1;
  45.         EX0 = 1;
  46.         IT0 = 1;
  47.         ET0 = 0;
  48.         while(1)
  49.         {
  50.                 display();//显示函数
  51.         }
  52. }

  53. void int0() interrupt 0 // 清空
  54. {
  55.         TL0=0;
  56. }

  57. //void counter1() interrupt 1
  58. //{
  59. //        relay = ~relay;
  60. //}

复制代码



回复

使用道具 举报

ID:765181 发表于 2020-5-31 19:06 | 显示全部楼层
gxslxxm 发表于 2020-5-30 22:07
很久项目不用io口扫数码管了。有点不知道怎么说。
简单说:
1:io口扫描数码管要注意是扫描的时间间隔。
...

谢谢您的回复,我另一个pwm可调占空比的程序数码管确实有闪烁。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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