8051 单片机入门 定时器与中断 寄存器 数码管显示

2019-07-15 10:10发布

请问有朋友看过宋雪松老师的51单片机教程吗?STC8051单片机

下面的程序是一个从999999开始  秒倒计时  的程序,并且是用 定时器 T1 的中断来完成。一开始我自己选的定时器模式是模式1(TMOD=0x01),但这种情况下数码管变化非常快,肯定是小于1秒的。后来改为模式2(TMOD=0x10),即八位自动重装模式,就可以正常的每秒倒计时了。新手入门不是很懂,请问有朋友能解释一下是为什么吗?

#include<reg52.h>
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char code led[]={   0xC0,  //"0"    0xF9,  //"1"     0xA4,  //"2"     0xB0,  //"3"       0x99,  //"4"                                                        0x92,  //"5"    0x82,  //"6"     0xF8,  //"7"      0x80,  //"8"       0x90,  //"9"    };         unsigned char ledbuff[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char flag = 0;
unsigned long int sec = 0;
unsigned int cnt = 0;
unsigned char  i = 0;

void main()
{
    ENLED = 0;
    ADDR3 = 1;

    TMOD = 0x10;   //为什么要用模式2呢???
    TH1 = 0xFC;
    TL1 = 0x67;
    TR1 = 1;

    EA = 1;
    ET1 = 1;
    while(1)
    {
        if(flag == 1)
        {
            flag = 0;
            sec++;
            ledbuff[0]=led[9-sec%10];
            ledbuff[1]=led[9-sec/10%10];
            ledbuff[2]=led[9-sec/100%10];
            ledbuff[3]=led[9-sec/1000%10];
            ledbuff[4]=led[9-sec/10000%10];
            ledbuff[5]=led[9-sec/100000%10];
        }
    }
}
void Iterruptedtimer() interrupt 3
{   
    TH1 = 0xFC;
    TL1 = 0x67;
    cnt++;
    if(cnt >= 1000)
    {
        cnt = 0;
        flag = 1;
   }
    P0 = 0xFF;
    switch(i)
    {
        case 0:ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=ledbuff[0];break;
        case 1:ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=ledbuff[1];break;
        case 2:ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=ledbuff[2];break;
        case 3:ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=ledbuff[3];break;
        case 4:ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=ledbuff[4];break;
        case 5:ADDR2=1;ADDR1=0;ADDR0=1;i=0;P0=ledbuff[5];break;
        default:break;
    }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
wulinwl
1楼-- · 2019-07-15 17:19
这才是定时器1的8位自动重装模式,12MHz 250us
TMOD = 0x20;
TH1 = 0x06;                //设置定时重载值
TL1 = 0x06;                //设置定时初值
8位自动重装模式最大只能定时256us

你这是定时器1的模式1(16位模式),11.0592MHz,1ms定时
TMOD = 0x10;
TH1 = 0xFC;
TL1 = 0x67;    //多了1,应该是66
_sam
2楼-- · 2019-07-15 18:57
小晓薪TM 发表于 2017-7-21 14:19
TMOD寄存器工作模式1是16位的计时计数器最大值为65536,模式2是八位,最大值为256。你设置的TH1和TL1的初值决定你计数器计时的时间。公式可查。

模式不同,初始值设置定时的时间不同,这个我是知道的,我想问的问题是,
        TMOD = 0x01;   //用T1定时器时, 模式 1(TMOD=0x01) 下 数码管变化非常快,不能达到每秒变化的要求,为了解决这个问题,我自己做了尝试:1.T1不变,把模式1改为模式2,即TMOD=0x10;2.把T1定时器改为T0定时器,仍用模式1。以上两种方法能够达到目的。但是为什么???
        TH1 = 0xFC;
        TL1 = 0x67;
        TR1 = 1;
_sam
3楼-- · 2019-07-15 20:42
 精彩回答 2  元偷偷看……
_sam
4楼-- · 2019-07-16 00:52
wulinwl 发表于 2017-7-21 16:03
这才是定时器1的8位自动重装模式,12MHz 250us
TMOD = 0x20;
TH1 = 0x06;                //设置定时重载值

书上说的8位自动重装模式(模式2)确实是
TMOD = 0x10;
(没有提到TMOD = 0x20)
难道对于不同的定时器来说,两个模式1和2功能不同?
求解释啊。。。


wulinwl
5楼-- · 2019-07-16 06:24
_sam 发表于 2017-7-21 21:10
书上说的8位自动重装模式(模式2)确实是
TMOD = 0x10;
(没有提到TMOD = 0x20)

51核心的定时器0和定时器1的设置都是一样的,TMOD寄存器的低4位控制T0,高4位控制T1,可能是你理解错了或者书印错了。
_sam
6楼-- · 2019-07-16 09:26
wulinwl 发表于 2017-7-21 21:40
51核心的定时器0和定时器1的设置都是一样的,TMOD寄存器的低4位控制T0,高4位控制T1,可能是你理解错了或者书印错了。

嗯是我没理解好,谢谢你的回答!!

一周热门 更多>