STC89C52RC/RD中定时器2的使用方法

学过一段时间单片机的你发现,中断服务函数可以在主函数进行的同时,进行一些对时间要求高的模块的配置时,则要用到定时器中断。而如果你要实现多个功能的操作,会使用多个定时器是必要的STC89C51单片机所有的资源中最不好搞清楚的就是定时器2,尤其是对于那些以前从来没有玩过单片机的新手。定时器2是新增资源,也是51单片机定时器里面功能最强大的一个定时器。

​ 定时器2有三个模式,在这里我们只是介绍系统的简单配置与将定时器2当成一般递增/递减计数器的使用代码,剩下的模式可以自己查阅手册:

​ 下面我带着大家简单配置一下:


​ 手册上写着T2CON是可位寻址的。意思就是可以单独对一个位进行配置。打开单片机的头文件#include <REGX52.H>,可以看到,这些位的具体定义。

​ TH2,TL2为大家熟悉的定时器计数初值的配置,RCAP2L与RCAP2H称作陷阱寄存器,用作重装载值的配置。可以在DECN=0的原理图里看到reload字样,表示重装载

​ 需要我们手动配置的也就是TF2(定时器溢出标志)和TR2(定时器开关)剩下的寄存器一部分配置定时器的工作模式,这里选择16位自动重装,所以都配置为0

​ EXEN2,由于我们不使用捕获模式,所以不用,将其置0.

​ 这里需要我们配置的寄存器比较少,所以采用T2CON = 0;先将所有位都置0,然后再按位寻址,
源码/模板:
/**
  * @brief  定时器2初始化,1毫秒@11.0592MHz
  * @param  无
  * @retval 无
  */
void Timer2_Init(void)        
{
    T2MOD = 0;    //初始化模式寄存器
    T2CON = 0;    //初始化控制寄存器
    TL2 = 0x66;    //设置定时初值
    TH2 = 0xFC;    //设置定时初值
    ET2=1;
    EA=1;
    PT2=0;
    TR2 = 1;        //定时器2开始计时
}
//中断服务函数模板
void Timer2_Routine() interrupt 5
{
    TF2 = 0;           //中断标志复位
    RCAP2L  = 0x66       //设置低位定时初值
    RCAP2H = 0xFC      //设置高位定时初值
    /***/
}
————————————————

#include <STC89C5xRC.H>
void InitT0(){
    TMOD=0X01;
    TH0=0XFC;
    TL0=0x66;
    ET0=1;
    TR0=1;
}
void servicet0() interrupt 1{
    static unsigned int t_1s=0;
    TH0=0XFC;
    TL0=0x66;
    t_1s++;
    if(t_1s>=1000){
        t_1s=0;
        P00=~P00;
    }
}

void InitT2(){
    T2MOD = 0;        //初始化模式寄存器
    T2CON = 0;        //初始化控制寄存器
    TL2 = 0x66;        //设置定时初始值
    TH2 = 0xFC;        //设置定时初始值
    RCAP2L = 0x66;        //设置定时重载值
    RCAP2H = 0xFC;        //设置定时重载值
    TR2 = 1;        //定时器2开始计时
    PT2=0;            //感觉比定时器0快一些
    ET2=1;
}
void servicet2() interrupt 5{
    static unsigned int t_1s=0;
    TF2=0;
    t_1s++;
    if(t_1s>=1000){
        t_1s=0;
        P01=~P01;
    }
}

 

void main(){
    InitT0();
    InitT2();
    EA=1;
    P1=(P1&0XE0)|0X0E;
    while(1){
    }
}
原文链接:https://blog.csdn.net/qq_60521516/article/details/124450447

  • 2
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,设计一个时钟,需要用到STC89C52RC/LE52RC单片机、LCD1602液晶屏、电位器、晶振、电容、电阻等元器件。 电路连接如下: ![时钟电路连接图](https://img-blog.csdn.net/20171024153410451?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFpMzEyMjEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/75) 代码如下: ```c #include <reg52.h> #include <intrins.h> #define uint unsigned int #define uchar unsigned char sbit RS = P2^5; //RS引脚 sbit RW = P2^6; //RW引脚 sbit EN = P2^7; //EN引脚 uchar code table[] = "2019-02-15 00:00:00"; //初始时间 uchar time[20]; //存放时间的数组 uchar hour, minute, second; //时、分、秒 bit flag; //秒钟更新标志 void delay(uint t) //延时函数 { uint i, j; for(i = t; i > 0; i--) { for(j = 110; j > 0; j--) { _nop_(); } } } void write_com(uchar com) //写命令函数 { RS = 0; RW = 0; P0 = com; EN = 1; delay(5); EN = 0; } void write_data(uchar dat) //写数据函数 { RS = 1; RW = 0; P0 = dat; EN = 1; delay(5); EN = 0; } void init() //LCD初始化函数 { write_com(0x38); //设置显示模式:16*2、5*7点阵、8位数据接口 write_com(0x0c); //开启显示,不显示光标 write_com(0x06); //光标右移,不移动屏幕 write_com(0x01); //清屏 } void get_time() //获取时间函数 { uchar i; for(i = 0; i < 20; i++) { time[i] = table[i]; } hour = (time[11] - 48) * 10 + (time[12] - 48); //计算小时 minute = (time[14] - 48) * 10 + (time[15] - 48); //计算分钟 second = (time[17] - 48) * 10 + (time[18] - 48); //计算秒钟 } void display_time() //显示时间函数 { uchar h1, h2, m1, m2, s1, s2; h1 = hour / 10; h2 = hour % 10; m1 = minute / 10; m2 = minute % 10; s1 = second / 10; s2 = second % 10; write_com(0x80); //显示位置:第一行第一列 write_data(h1 + 48); //显示小时的十位数 write_data(h2 + 48); //显示小时的个位数 write_data(':'); //显示冒号 write_data(m1 + 48); //显示分钟的十位数 write_data(m2 + 48); //显示分钟的个位数 write_data(':'); //显示冒号 write_data(s1 + 48); //显示秒钟的十位数 write_data(s2 + 48); //显示秒钟的个位数 } void timer0() interrupt 1 //定时器0断函数 { TH0 = 0x3c; TL0 = 0xb0; flag = 1; //秒钟更新标志 } void main() { TMOD = 0x01; //定时器0,模式1 TH0 = 0x3c; //定时器初值 TL0 = 0xb0; TR0 = 1; //启动定时器0 ET0 = 1; //开启定时器0断 EA = 1; //开启总断 init(); //LCD初始化 get_time(); //获取时间 while(1) { if(flag) //一秒钟更新一次 { flag = 0; //清除秒钟更新标志 second++; //秒钟加1 if(second == 60) //一分钟更新一次 { second = 0; //秒钟清零 minute++; //分钟加1 if(minute == 60) //一小时更新一次 { minute = 0; //分钟清零 hour++; //小时加1 if(hour == 24) //一天更新一次 { hour = 0; //小时清零 } } } display_time(); //显示时间 } } } ``` 在此代码使用定时器0断来更新时间,一秒钟更新一次。在更新时间时,需要注意进位的问题。最后,将更新后的时间显示在LCD上,实现一个简单的时钟程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值