微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 8051 单片机入门 定时器与中断 寄存器 数码管显示

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

时间:10-02 整理:3721RD 点击:
请问有朋友看过宋雪松老师的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;
    }
}

TMOD是分两半的,你没理解透
TMOD=0x01是定时器0的方式1,TMOD=0x10是定时器1的方式1


TMOD寄存器工作模式1是16位的计时计数器最大值为65536,模式2是八位,最大值为256。你设置的TH1和TL1的初值决定你计数器计时的时间。公式可查。

这才是定时器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

模式不同,初始值设置定时的时间不同,这个我是知道的,我想问的问题是,
        TMOD = 0x01;   //用T1定时器时, 模式 1(TMOD=0x01) 下 数码管变化非常快,不能达到每秒变化的要求,为了解决这个问题,我自己做了尝试:1.T1不变,把模式1改为模式2,即TMOD=0x10;2.把T1定时器改为T0定时器,仍用模式1。以上两种方法能够达到目的。但是为什么?
        TH1 = 0xFC;
        TL1 = 0x67;
        TR1 = 1;

TMOD=0x01;
下面两种是可以的:
TH0=0xFC;
TL0=0x67;
TR0=1;
或者
TMOD=0x10;
TH1=0xFC;
TL1=0x67;
TR1=1;
难道两种定时器有什么特殊用法?小白求教

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

51核心的定时器0和定时器1的设置都是一样的,TMOD寄存器的低4位控制T0,高4位控制T1,可能是你理解错了或者书印错了。

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

这样的啊,懂了
非常感谢!

谢谢小编

可能是模式1没有自动重装功能导致,可以在多个地方设置一下。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top