单片机交流
直播中

张勇

7年用户 1448经验值
私信 关注
[问答]

请问51单片机定时器如何控制数码管与led共同闪烁?

请问51单片机定时器如何控制数码管与led共同闪烁?

回帖(1)

申志敏

2021-11-4 09:57:07
外接晶振为12MHz时,51单片机相关周期的具体值为:
振荡周期=1/12us;
状态周期=1/6us;
机器周期=1us;
指令周期=1~4us;
51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
1、工作方式寄存器TMOD





工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
GATE是门控位, GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。
C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
M1M0:工作方式设置位。定时/计数器有四种工作方式。





控制寄存器TCON
TCON的高4位用于控
制定时/计数器的启动和中断申请。其格式如下:





TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
TR0(TCON.4):T0运行控制位,其功能与TR1类同。
定时/计数器的工作方式
1、方式1
方式1的计数位数是16位,由TL0作为低8位,TH0
作为高8位,组成了16位加1计数器 。计数个数与计数初值的关系为:X=2(16次方)-N
2、方式2
为自动重装初值的8位计数方式。 计数个数与计数初值的关系为:X=28-N
工作方式2特别适合于用作较精确的脉冲信号发生器。所以串口通信处用此方式。
计数器初值的计算
机器周期也就是CPU完成一个基本操作所需要的时间。
机器周期=1/单片机的时钟频率。
51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us。
而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H
中断允许寄存器IE





EX0(IE.0),外部中断0允许位;
ET0(IE.1),定时/计数器T0中断允许位;
EX1(IE.2),外部中断0允许位;
ET1(IE.3),定时/计数器T1中断允许位;
ES(IE.4),串行口中断允许位;
EA (IE.7), CPU中断允许(总允许)位。





主程序中需要有以下代码:

include
#include


typedef unsigned int u16;
typedef unsigned char u8;


***it led1=P2^0;
***it LSA=P2^2;
***it LSB=P2^3;
***it LSC=P2^4;


u16 smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f};


void init0()
{
        EA=1;
        ET0=1;
        TR0=1;
        TMOD=0x01;
        TH0=0xFC;
        TL0=0x18;
        LSA=0;
        LSB=0;
        LSC=0;
}
int main()
{
        init0();
        while(1);
        return 0;
}


u16 count=0;
u16 i=0;


void Init() interrupt 1
{
        count++;
        TH0=0xFC;
        TL0=0x18;
        if(count==1000)
        {
                 led1=~led1;
                count=0;
                if(led1==0)
                {
                        i++;
                        i=i%10;
                        P0=smgduan;
                }
                else
                        P0=0x00;
        }
}
举报

更多回帖

×
20
完善资料,
赚取积分