找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2540|回复: 12
收起左侧

单片机定时器程序问题

[复制链接]
ID:688985 发表于 2020-2-10 19:08 | 显示全部楼层 |阅读模式
求教:定时器中这部分放在主函数中,程序不能正常运行。放在定时器函数中可以正常运行,请问是怎么回事?
void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        aa++;  
                     if (aa==20)
                         { aa=0;        
                           
                          if(temp==100)
                                   temp=0;        
                                temp++;
                         }
                                
                        bai=temp/100;
                        shi=temp%100/10;
                        ge=temp%10;
                        
}

回复

使用道具 举报

ID:332444 发表于 2020-2-10 19:58 | 显示全部楼层
从理论上来说描述的问题是不存在的,红色部分正确的代码放在主函数中一定是可以正常运行的,除非主函数中有其他的代码影响了这段代码的正确运行。
回复

使用道具 举报

ID:515682 发表于 2020-2-10 20:37 | 显示全部楼层
1. 增加定时器定时长度测试一下
回复

使用道具 举报

ID:515682 发表于 2020-2-10 20:38 | 显示全部楼层
2. 将 bai shi ge计算放到 temp++后面试试。
回复

使用道具 举报

ID:515682 发表于 2020-2-10 20:39 | 显示全部楼层
后面带了除法与取余计算,不知道你的这些变量是什么型的。
回复

使用道具 举报

ID:515682 发表于 2020-2-10 20:42 | 显示全部楼层
不知道你这些变量是什么 类型的,后面的bai shi ge 每次都要做除法与取余运算,这些都是比较耗时间的。
放在主函数里的话,也许你没算玩 aa已经加了好几次了,所以你没法切到aa==20

有3个方法可以测试
1. 加大定时器定时长度测试一下。
2. 将ge shi bai计算放到 temp++后面
3. 将aa==20改为 aa>=20



回复

使用道具 举报

ID:688985 发表于 2020-2-10 21:21 | 显示全部楼层
这是我的程序:
#include<reg51.h>
//#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar temp,bai,shi,ge;
uint aa,time;
void delay(uint z);
void display(uchar bai,uchar shi,uchar ge);
void init();
sbit wela=P2^7;
sbit dula=P2^6;
void main()
{
        init();
        time=60;

         while(1)
        {
                               
               
                display(bai,shi,ge);
                                             

        }
                         
         
}                                          
       

void display(uchar bai,uchar shi,uchar ge)
{
                                        dula=1;
                                        P0=table[bai];
                                        dula=0;
                                        P0=0x00;   
                                        wela=1;
                                        P0=0xf7;
                                        wela=0;
                                    delay(time) ;

                                        dula=1;
                                        P0=table[shi];
                                        dula=0;
                                        P0=0x00;   
                                        wela=1;
                                        P0=0xef;
                                        wela=0;
                                        delay(time) ;
                                       
                                        dula=1;
                                        P0=table[ge];
                                        dula=0;
                                        P0=0x00;   
                                        wela=1;
                                        P0=0xdf;
                                        wela=0;
                                        delay(time) ;

                                       
}

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

void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        aa++;  
                     if (aa==20)
                         { aa=0;       
                           
                          if(temp==100)
                                   temp=0;       
                                temp++;
                         }
                               
                        bai=temp/100;
                        shi=temp%100/10;
                        ge=temp%10;
                       
}

void init()
{
        temp=0;
        wela=0;
        dula=0;
        TMOD=0x01;//设置定时器0为工作方式1;
        TH0=(65536-50000)/256;//定时器高8位值;
        TL1=(65536-50000)%256;//定时器低8位值;
        EA=1;//开总中断;
        ET0=1;//打开定时器0中断;
        TR0=1;//启动定时器0;
}
回复

使用道具 举报

ID:275826 发表于 2020-2-10 21:43 | 显示全部楼层
应该是全局与局部变量设置问题
回复

使用道具 举报

ID:245004 发表于 2020-2-10 22:40 | 显示全部楼层
定时器时间短,中断太频繁了。一般这样写可以避免此类问题:
批注 2020-02-10 223801.png


回复

使用道具 举报

ID:691354 发表于 2020-2-10 22:54 | 显示全部楼层
aa是定义的全局变量吗?这个逻辑上是没错的,我以前也写过类似程序
回复

使用道具 举报

ID:213173 发表于 2020-2-11 07:37 | 显示全部楼层
1.红色部分代码放在主函数中可能是因为主函数查询aa周期大于中断周期,前一次查询aa<20,后一次查询aa>20,aa不能及时清0而出错。
2.如果在主函数中改变查询条件 if (aa>=20),虽然不会出错但有可能积累误差而计时不准。
3.比较好的方案是添加一个标志,在主函数中查询这个标志。
定义一个全局位变量
bit flag;

void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        aa++;  
        if(aa==20)
        {
                aa=0;        
                flag=1;
        }
}
主函数中查询
        if(flag==1)
        {
                flag=0;
                temp++;
                bai=temp/100;
                shi=temp%100/10;
                ge=temp%10;
    }                    
回复

使用道具 举报

ID:462827 发表于 2020-2-11 13:21 | 显示全部楼层
bai=temp/100;
shi=temp%100/10;
ge=temp%10;

这几个可放在主函数中,其它的仍放在中断里就行了。
回复

使用道具 举报

ID:688985 发表于 2020-2-11 15:59 | 显示全部楼层
感谢各位大师的指导
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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