UAV2201~UAV2205编程训练51定时器

例子001、51单片机定时器基础训练

下面是基本的 51 定时器控制代码LED闪烁0.5s

#include <reg52.h> // 8051 头文件
// 定义时钟频率为 12MHz
#define FOSC 12000000UL

// 定义定时器重装值
#define TIMER_RELOAD_VALUE 65536-50000

sbit LED=P1^0; // 定义 LED 灯连接的端口
unsigned char cnt;
// 初始化定时器0 void Init_Timer0() { TMOD |= 0x01; // 将定时器0工作方式设置为模式1 TH0 = TIMER_RELOAD_VALUE / 256; // 计算定时器重装值的高8位并赋值 TL0 = TIMER_RELOAD_VALUE % 256; // 计算定时器重装值的低8位并赋值 EA = 1; // 开启全局中断 ET0 = 1; // 开启定时器0中断 TR0 = 1; // 开启定时器0 } // 定时器0中断处理函数 void Timer0_ISR() interrupt 1 { TH0 = TIMER_RELOAD_VALUE / 256; // 计算定时器重装值的高8位并赋值 TL0 = TIMER_RELOAD_VALUE % 256; // 计算定时器重装值的低8位并赋值
  cnt++;
if(cnt==10)
  {   cnt = 0;
    LED = ~LED; // LED 灯取反
  } } // 主函数 void main() { Init_Timer0(); // 初始化定时器0 while(1); // 保持程序运行 }

这份代码中,使用定时器0来控制 LED 灯的闪烁。定时器的工作方式被设置为模式1,并且每次重装时赋值为 TIMER_RELOAD_VALUE,即计算出的定时时间。开启定时器0中断后,每当定时器0计数到 TIMER_RELOAD_VALUE 时,会触发中断处理函数 Timer0_ISR(),在其中将计数值重新赋为 TIMER_RELOAD_VALUE 并将 LED 灯进行取反操作。
在你的具体应用中,你可以根据需要更改定时时间和控制操作。

例子002、运用的定时器查询方式和中断方式,实现流水灯每隔0.5s流动或者数码管每隔1s计数

#include <reg52.h>
//#include <intrins.h>
unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段

unsigned char cnt,i;

void main()
{
    TMOD = 0x01; //设定时器0为mode1
    TH0 = (65536-50000)/256;
    TL0 = (65536-50000)%256;
    EA = 1;  //开总中断
    ET0 = 1; //开定时器0中断
    TR0=1;     //启动定时器0
    TF0=0;   //清定时器溢出标志位
    P0=0xff; //1111 1111关闭LED
    P1=0X00; 
    while(1)
    {
        while(TF0==0);
        TF0=0;
        TH0=(65536-50000)/256; // 定时器 T0的高 8 位赋初值
        TL0=(65536-50000)%256; // 定时器 T0的低 8 位赋初值
        cnt++;        
        if(cnt>10)
        {
            cnt=0;
            P0 = Tab[i];
            if(++i>9)i=0;

        }
    }
}


//void time0(void) interrupt 1
//{
//    TH0=(65536-50000)/256; // 定时器 T0 的高 8 位赋初值  
//    TL0=(65536-50000)%256; // 定时器 T0 的低 8 位赋初值    
//    cnt++;
//    if(cnt>10)
//    {
//        cnt=0;
//        if(++i>9)i=0;
//        P2 = ~(1<<i);
//    }
//}

例子003、两位数码管60s计时

使用time0定时,50ms计数20次,作为1s时钟(模式1),
使用time1定时,250us计数32次,作为数码管动态扫描8ms(模式2)

#include <reg52.h>
unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段
char dis[2]={0xc0,0xc0};//显示存储数据,初始显示00
char cnt0,cnt1,second,scan=0;  //变量初始化默认0

void main()
{
    TMOD = 0x21; //设T0为mode1,设T1为mode2,
    TH0 = (65536-50000)/256;
    TL0 = (65536-50000)%256;
    TH1 = 256-250;
    TL1 = 256-250;    
    
    EA = 1;  //开总中断
    ET0 = 1;ET1 = 1;//开T0/T1中断
    TR0 = 1;TR1 = 1;//启动T0/T1
    TF0=0;TF1=1;    //清定时器溢出标志位
    while(1)
    {
        ;
    }
}

void time0(void) interrupt 1   //1s
{
    TH0=(65536-50000)/256; // 定时器 T0 的高 8 位赋初值  
    TL0=(65536-50000)%256; // 定时器 T0 的低 8 位赋初值    
    if(++cnt0 == 20)       //若中断20次就1s
    {
        cnt0 = 0;         //重新计数
        second++;
        if(second==60)
        {
            second = 0;
        }
    }
    dis[0] = Tab[second/10];
    dis[1] = Tab[second%10];
}

void time1(void) interrupt 3   //动态扫描每隔8ms
{
    if(++cnt1 == 32)           //若中断32次就8ms
    {
        cnt1 =0;               //重新计数
        if(++scan == 3)scan =1;
        P0 = 0xff;             //关闭数码管
        P1 = ~scan;
        P0 = dis[scan -1];
    }
}

 例子004、四位数码管60s计数(含ms两位数)

#include <reg52.h>
unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段
char dis[4]={0xc0,0xc0,0xc0,0xc0};//显示存储数据,初始显示00
char cnt0,cnt1,second,scan=0;  //变量初始化默认0

void main()
{
    TMOD = 0x21; //设T0为mode1,设T1为mode2,
    TH0 = (65536-50000)/256;
    TL0 = (65536-50000)%256;
    TH1 = 256-250;
    TL1 = 256-250;    
    
    EA = 1;  //开总中断
    ET0 = 1;ET1 = 1;//开T0/T1中断
    TR0 = 1;TR1 = 1;//启动T0/T1
    TF0 = 0;TF1 = 1;    //清定时器溢出标志位
    while(1)
    {
        ;
    }
}

void time0(void) interrupt 1   //1s
{
    TH0=(65536-10000)/256; // 定时器 T0 的高 8 位赋初值  
    TL0=(65536-10000)%256; // 定时器 T0 的低 8 位赋初值    
    if(++cnt0 == 100)       //若中断20次就1s
    {
        cnt0 = 0;         //重新计数
        second++;
        if(second==60)
        {
            second = 0;
        }
    }
    dis[3] = Tab[second/10];
    dis[2] = Tab[second%10]&0x7f;
    dis[1] = Tab[cnt0/10];
    dis[0] = Tab[cnt0%10];
}

void time1(void) interrupt 3   //动态扫描每隔8ms
{
    if(++cnt1 == 32)           //若中断32次就8ms
    {
        cnt1 =0;               //重新计数
        if(++scan == 4)scan =0;
        P2 = 0xff;             //关闭数码管
        P1 = ~(1<<scan);
        P2 = dis[scan];
    }
}

 

 例子005、四位数码管60s计数含两小数位(定时器1中断,使用延迟10ms动态扫描,外部中断0开始/暂停,外部中断1复位清零)

#include <reg52.h>
unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段
unsigned char count,miao;//秒的小数点后两位计数count
void delay(unsigned int z) //当z=1,延迟时间10ms
{
    unsigned char i,j,k;
    for(i=z;i>0;i--)
        for(j=4;j>0;j--)
            for(k=248;k>0;k--);
}

void main()
{
    TMOD |= 0x10; // 将定时器1工作方式设置为模式1
    TH1 = (65536-10000) / 256; // 计算定时器重装值的高8位并赋值50ms
    TL1 = (65536-10000) % 256; // 计算定时器重装值的低8位并赋值50ms
    EA = 1; // 开启全局中断
    EX0=1;EX1=1;    //开外部中断0/1
    IT0=1;IT1=1;    //外中断0/1设置边沿触发
    ET1 = 1; // 开启定时器1中断
    TR1 = 1; // 开启定时器1
    while(1)
    {
        P2 = Tab[miao/10];
        P1 = ~(1<<3);
        delay(1);
        P1 = 0xff;

        P2 = (Tab[miao%10])&0x7f;
        P1 = ~(1<<2);
        delay(1);
        P1 = 0xff;

        P2 = Tab[count/10];
        P1 = ~(1<<1);
        delay(1);
        P1 = 0xff;

        P2 = Tab[count%10];
        P1 = ~(1<<0);
        delay(1);
        P1 = 0xff;            
    }
}

void time1() interrupt 3
{
    TH1 = (65536-10000) / 256; // 计算定时器重装值的高8位并赋值
    TL1 = (65536-10000) % 256; // 计算定时器重装值的低8位并赋值
    count++;
    if(count == 100) //中断进入100次就是1s
    {
        count = 0;
        miao++;
        if(miao>60)miao=0;
    }
}

void int0(void) interrupt 0
{
    TR1 = ~TR1;
}

void int1(void) interrupt 2
{
    miao = 0;
    count =0;
}

 

 

posted on 2023-12-10 15:50  一郎哥哥  阅读(207)  评论(0编辑  收藏  举报

导航