找回密码
 立即注册

QQ登录

只需一步,快速开始

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

新手请教各位,为什么定时器时间不对?

[复制链接]
ID:217075 发表于 2017-7-4 13:40 | 显示全部楼层 |阅读模式
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit gewe=P1^3;        //个位选通               
sbit shwe=P1^2;
sbit bawe=P1^1;
sbit qiwe=P1^0;
sbit led1=P2^0;         //二极管
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
                                        0x92,0x82,0xf8,0x80,0x90};
void delayms(uint);
void display1(uchar,uchar);
void dispiay2(uchar,uchar);
uchar num1,num2,qian,bai,shi,ge;
uint num;

void display1(uchar qian,uchar bai)
{
        qiwe=0;                          //千位选通打开
        P0=table[qian];          //千位段选
        delayms(5);                  //延时
        qiwe=1;                          //千位选通关闭

        bawe=0;
        P0=table[bai];
        delayms(5);
        bawe=1;
}

void display2(uchar shi,uchar ge)
{
        shwe=0;
        P0=table[shi];
        delayms(5);
        shwe=1;

        gewe=0;
        P0=table[ge];
        delayms(5);
        gewe=1;       
}
void main()
{
        TMOD=0x11;                          //设置定时器0和1为工作方式1
        TH0=(65536-45872)/256;//装初值
        TL0=(65536-45872)%256;
        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        EA=1;                                   //开总中断
        ET0=1 ;                                   //开定时器0中断
        TR0=1;                                   // 启动定时器0
        ET1=1;                                  
        TR1=1;                                  
        while(1)
        {
                display2(shi,ge);
                display1(qian,bai);
        }
}

void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)                //延时函数约延时xms
                for(j=110;j>0;j--);
}

void TO_time() interrupt 1
{
        TH0=(65536-45872)/256;        //重装初值
        TL0=(65536-45872)%256;
        num1++;
        if(num1==4)                                //到了4次=200ms
        {
                num1=0;                                //把num1清零再计20次
                led1=~led1;
        }               
}

void T1_time() interrupt 3
{
        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        num2++;
        if(num2=20)                           //如果到了20次约为1秒
        {       
                num2=0;                           //把num2清零再计20次
                num++;
                if(num==3600)                //数码管计到3600后归零
                        num=0;
                qian=num/1000;
                bai=num%1000/100        ; //把一个四位数送数码管
                shi=num%1000%100/10;       
                ge=num%1000%100%10;               
        }       
}
       
回复

使用道具 举报

ID:217075 发表于 2017-7-4 13:47 | 显示全部楼层
搞了2天了,我不会了
回复

使用道具 举报

ID:164602 发表于 2017-7-4 16:59 | 显示全部楼层
你的程序,我在我的板子上试过了。
从计时来说,可能不是十分准,但效果还是在的。
计时一小时,我等不了,我通过赋值3580,过20下,是真的清了零,再计时的。LED灯也在闪。
没有问题啊。
你只发出来程序,不知道你的目标是什么,是否达到。
从标题来说,你说的时间不对,是指准确的时间吗?那个是不容易调到百分之百的,因为定时器中断发生后,执行了一些语句,那是要占时间的,当然不准了。
回复

使用道具 举报

ID:97438 发表于 2017-7-4 17:07 | 显示全部楼层
  if(num2=20)????这里错了
回复

使用道具 举报

ID:213173 发表于 2017-7-4 17:28 | 显示全部楼层
   if(num2=20)  //如果到了20次约为1秒....少一个=。 if(num2==20)
只要用一个定时器就可以完成,不必开T1。
void TO_time() interrupt 1
{
        TH0=(65536-45872)/256;        //重装初值
        TL0=(65536-45872)%256;
        num1++;
        num2++;
        if(num1>=4)                                //到了4次=200ms
        {
                num1=0;                                //把num1清零再计20次
                led1=~led1;
        }               
        if(num2>=20)                           //如果到了20次约为1秒
        {        
                num2=0;                           //把num2清零再计20次
                num++;
                if(num>=3600)                //数码管计到3600后归零
                num=0;
                qian=num/1000;
                bai=num%1000/100; //把一个四位数送数码管
                shi=num%1000%100/10;        
                ge=num%1000%100%10;               
        }        
}
两个显示程序也可以合并在一起
回复

使用道具 举报

ID:213173 发表于 2017-7-4 17:52 | 显示全部楼层
hsujinshan 发表于 2017-7-4 13:47
搞了2天了,我不会了

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit gewe=P1^3;        //个位选通               
sbit shwe=P1^2;
sbit bawe=P1^1;
sbit qiwe=P1^0;
sbit led1=P2^0;         //二极管
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
                   0x92,0x82,0xf8,0x80,0x90};
void delayms(uint);
void display1(uchar,uchar,uchar,uchar);
//void dispiay2(uchar,uchar);
uchar num1,num2,qian,bai,shi,ge;
uint num;

void display1(uchar qian,uchar bai,uchar shi,uchar ge)
{
        qiwe=0;                   //千位选通打开
        P0=table[qian];          //千位段选
        delayms(2);               //延时
        qiwe=1;                   //千位选通关闭
       
        bawe=0;
        P0=table[bai];
        delayms(2);
        bawe=1;

        shwe=0;
        P0=table[shi];
        delayms(2);
        shwe=1;
       
        gewe=0;
        P0=table[ge];
        delayms(2);
        gewe=1;        
}

void main()
{
        TMOD=0x01;                          //设置定时器0和1为工作方式1
        TH0=(65536-45872)/256;//装初值
        TL0=(65536-45872)%256;
//        TH1=(65536-45872)/256;
//        TL1=(65536-45872)%256;
        EA=1;                                   //开总中断
        ET0=1 ;                                   //开定时器0中断
        TR0=1;                                   // 启动定时器0
//        ET1=1;                                   
//        TR1=1;                                   
        while(1)
        {
                qian=table[num/1000];
                bai=table[num%1000/100]; //把一个四位数送数码管
                shi=table[num%1000%100/10];        
                ge=table[num%1000%100%10];               
//                display2(shi,ge);
                display1(qian,bai,shi,ge);
        }
}

void delayms(uint xms)
{
        uint i,j;
        for(i=xms;i>0;i--)                //延时函数约延时xms
                for(j=110;j>0;j--);
}

void TO_time() interrupt 1
{
        TH0=(65536-45872)/256;        //重装初值
        TL0=(65536-45872)%256;
        num1++;
        num2++;
        if(num1>=4)                                //到了4次=200ms
        {
                num1=0;                                //把num1清零再计20次
                led1=~led1;
        }               
        if(num2>=20)                           //如果到了20次约为1秒
        {        
                num2=0;                           //把num2清零再计20次
                num++;
                if(num>=3600)                //数码管计到3600后归零
                        num=0;
        }        
}
/*
void T1_time() interrupt 3
{
        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        num2++;
        if(num2=20)                           //如果到了20次约为1秒
        {        
                num2=0;                           //把num2清零再计20次
                num++;
                if(num==3600)                //数码管计到3600后归零
                num=0;
                qian=num/1000;
                bai=num%1000/100        ; //把一个四位数送数码管
                shi=num%1000%100/10;        
                ge=num%1000%100%10;               
        }        
}*/
回复

使用道具 举报

ID:7485 发表于 2017-7-4 20:55 | 显示全部楼层
(65536-45872)?是多少的晶振?
回复

使用道具 举报

ID:217075 发表于 2017-7-5 10:41 | 显示全部楼层
12M晶振
回复

使用道具 举报

ID:111634 发表于 2017-7-5 11:17 | 显示全部楼层
工作方式1需重装定时常数,就会产生误差。工作方式2不需重装定时常数,不会产生误差。
回复

使用道具 举报

ID:124330 发表于 2017-7-5 11:46 | 显示全部楼层
程序没什么问题,就是定时器1中断的里面的判断==你写成了赋值=
回复

使用道具 举报

ID:124330 发表于 2017-7-5 11:48 | 显示全部楼层
如果是12M晶振赋初值50000更精确一点
回复

使用道具 举报

ID:105206 发表于 2017-7-5 14:16 | 显示全部楼层
完全可以用1 个定时器就可以搞定的。
回复

使用道具 举报

ID:184970 发表于 2017-7-5 16:54 | 显示全部楼层
你现在算的这个是按11.0592M的晶振算的,12M的话直接-50000就可以了,相对会更准一些
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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