51单片机之计数器

2019-09-26  本文已影响0人  David_Rao

51计数器

以下是一个方波脉冲(波峰是1,高电位;波谷是0,低电位)
每来一个脉冲(波峰),计数器+1




程序的思路是:用延时函数令P10口反复改变电平状态,形成方波信号

准备工作:连接P10和P34引脚



计数器的配置

// 计数器0初始化
void counter0Init()
{
    TR0 = 1;  //启动计数器0
    TMOD = 0x05;  //计数器工作模式 M1=0;M0=1;
    TH0 = 0;
    TL0 = 0;
}

测试程序如下

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;  //数码管段选
sbit WE = P2^7;  //数码管位选
sbit LED1 = P1^0;


uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f} ;  //code表示存在code区,数据不能被修改

void delay(unsigned int z)
{
    unsigned int x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y >0; y--);
}

void display(uchar i)
{
    uchar bai, shi, ge;
    bai = i / 100;
    shi = i / 10 % 10;
    ge = i % 10;
    /*******************************************************/
    P0 = 0xff;  //清除断码
    WE = 1;  //打开位选
    P0 = 0XFE;  //1111 1110选择第一个数码管
    WE = 0;  //锁住位选数据
    
    DU = 1;  //打开段选
    P0 = table[bai];  //显示百位
    DU = 0;  //锁住段选数据
    delay(5);  
    /*******************************************************/
    P0 = 0xff;  //清除断码
    WE = 1;  //打开位选
    P0 = 0XFD;  //1111 1101选择第二个数码管
    WE = 0;  //锁住位选数据
    
    DU = 1;  //打开段选
    P0 = table[shi];  //显示十位
    DU = 0;  //锁住段选数据
    delay(5); 
    /*******************************************************/
    P0 = 0xff;  //清除断码
    WE = 1;  //打开位选
    P0 = 0XFB;  //1111 1011选择第三个数码管
    WE = 0;  //锁住位选数据
    
    DU = 1;  //打开段选
    P0 = table[ge];  //显示个位
    DU = 0;  //锁住段选数据
    delay(5);  
}
// 计数器0初始化
void counter0Init()
{
    TR0 = 1;  //启动计数器0
    TMOD = 0x05;  //计数器工作模式 M1=0;M0=1;
    TH0 = 0;
    TL0 = 0;
}

void main()
{
    delay(500);
    LED1 = ~LED1;
    display(TL0);
}

虽然已经能观察到现象,但是以上程序存在一个问题,使用delay函数会占用单片机运行资源,导致单片机没有办法“抽出时间”去处理数码管动态扫描。

程序改进

利用定时器1来产生脉冲方波

// 计数器0初始化
void counter0Init()
{
    TR0 = 1;  //启动计数器0
    TMOD = 0x15;  //计数器工作模式 M1=0;M0=1;
    TH0 = 0;
    TL0 = 0;
}

//定时器1初始化
void timer1Init()
{
    TR1 = 1;  //启动定时器1
    TMOD = 0x15;  //定时器1工作模式1,16位定时模式
    TH1 = 0x4b;
    TL1 = 0xfd;  //定时50ms
}

void main()
{
    uchar mSec;  //毫秒
    counter0Init();  //计数器0初始化
    timer1Init();  //定时器1初始化
    while(1)
    {
        if(TF1 == 1)  //TF0==1即经过50ms
        {
            TF1 = 0;  //软件清零溢出标志位
            TH1 = 0x4b;  //重放初值
            TL1 = 0xfd;
            mSec++;  //50ms到
            if(mSec == 10)  //10个50ms到
            {
                mSec = 0;
                LED1 = ~LED1;  //产生方波脉冲
            }
        }
        display(TL0);
    }
}
上一篇下一篇

猜你喜欢

热点阅读