📄 t2timer.c
字号:
//////////////////////////////////////////////////////////////////
// T2用作计数/定时器或波特率发生器时的编程方法 //
// -- xiaoqi //
// t2conSet的定义如下,不包括通信波特率发生器方式 //
// 0x04...... TR2 = 1,开始计时,CP/RL2=0,自动重装 //
// EXEN2 = 0,忽略外部T2EX(P1.1) //
// 0x05...... TR2 = 1,开始计时;CP/RL2=1,不自动重装 //
// EXEN2 = 0,忽略外部T2EX(P1.1) //
// 0x07...... TR2 = 1,开始计数;CP/RL2=1,不自动重装 //
// EXEN2 = 0,忽略外部T2EX(P1.1) //
// C/T2 = 1,使用外部时钟线T2 //
// 0x0F...... TR2 = 1,开始计数;CP/RL2=1,不自动重装 //
// C/T2 = 1,使用外部时钟线T2 //
// EXEN2 = 1,EXF2受控于捕获允许EXEN2的状态,EXEN2 //
// 置1时一个外部T2EX的负脉冲将引发T2中断,同时用当 //
// 前计数寄存器中的数值去刷新备用寄存器,备用寄存器//
// 原设定值被更新,捕获模式 //
//--------------------------------------------------------------//
// 用作波特率发生器 //
// 0x35...... TR2 = 1,开始计数;CP/RL2=1,不自动重装,但被CRLK和//
// CTLK/CRLK的设立而忽略 //
// C/T2 = 0,使用内部时钟 //
// EXEN2 = 0,忽略外部T2EX(P1.1) //
// EXF2受控于EXEN2的状态,置1时一个外部T2EX的负脉冲//
// 将引发T2中断。不刷新备用寄存器 //
// CTLK = 1,引用为发送时钟源(波特率发生器) //
// CRLK = 1,引用为接收时钟源,强制自动重装初值。 //
// 当计数器溢出时并不设立标志TF2,所以不引发中断 //
// 如果设定了允许CT2中断视作无效 //
//--------------------------------------------------------------//
// 附加说明: //
// 定时器的使用时可以随时切换的,在不通信的时候可以换回来又用作 //
// 定时器或计数器,定时或计数器之间也可以来回切换,发挥最大效益 //
//////////////////////////////////////////////////////////////////
#include <reg52.h>
// 定义定时计数器的工作模式
#define t2conSet 0x04
#define Bodrate 0xFFDC // FFDC相对于11.0592M晶振下9600波特率,
// 通信实际9600
unsigned char timerForDelay;
void init();
void uart_init(void);
void main()
{
init();
timerForDelay = 10;
while(timerForDelay); // 延时等待观察效果
uart_init(); // 该做波特率发生器定时中断暂停
SBUF = 0xaa; // 发送一字节
while(!TI);
TI = 0;
while(1);
}
//////////////////////////////////////////////////////////////////
// 初始化开启定时器2 //
//////////////////////////////////////////////////////////////////
void init()
{
RCAP2H = 0xff;
RCAP2L = 0xE0;
TH2 = 0xff; // 定时器初值
TL2 = 0xE0;
ES = 0; // 关闭通信中断
ET2 = 1; // 允许T2中断
T2CON = t2conSet;
EA = 1;
// DCEN = 1; // at89s52才有的计数方向选择
}
//////////////////////////////////////////////////////////////////
// 定时器CT2中断服务程序 //
//////////////////////////////////////////////////////////////////
void timer2Int(void) interrupt 5
{
TF2 = 0; // 溢出标志必须由软件清零
EXF2 = 0; // 捕获标志必须由软件清零
if(timerForDelay)timerForDelay--;
}
//////////////////////////////////////////////////////////////////
// 定时器CT2用于串行通信波特率发生器 //
// 定义为波特率发生器以后,ET2自动失效 //
//////////////////////////////////////////////////////////////////
void uart_init(void)
{
T2CON = 0x35; // 0b0011 0101 16位串行波特率
// 发生器,自动重装
TH2 = (unsigned char )(Bodrate>>8) ;
TL2 = (unsigned char )(Bodrate & 0xff);
RCAP2H = (unsigned char )(Bodrate>>8) ;
RCAP2L = (unsigned char )(Bodrate & 0xff);
TR2 = 1; // 启动时钟
SCON = 0x7A; // 0b0111 1010 第一种工作方式
// 8位单机通信
ES = 1; // 允许通信中断
EA = 1; // 中断打开
}
//////////////////////////////////////////////////////////////////
// 串口中断服务程序 //
//////////////////////////////////////////////////////////////////
void receive() interrupt 4
{
if(RI) //判断接收中断状态
{
timerForDelay = SBUF;
RI = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -