本章重点讲解将TIM0用作两个8位定时器,同时将TIM1用作波特率发生器。
当定时器T0在方式3时,T1不能产生中断,但可以正常工作在方式0、1、2下,大多数情况下,T1将用作串口的波特率发生器。
1、定时器0工作在模式3框图:
2、定时器1工作在模式2用作波特率发生器框图:
#define OSC_FREQ 11059200L
//#define BAUD_115200 256 - (OSC_FREQ/192L)/115200L //
//#define BAUD_38400 256 - (OSC_FREQ/192L)/38400L //
#define BAUD_Time 1
#if(BAUD_Time==1)
//若波特率加倍,则使用下面参数;
#define BAUD_57600 256 - (OSC_FREQ/192L)/57600L //255
#define BAUD_28800 256 - (OSC_FREQ/192L)/28800L //254
#define BAUD_19200 256 - (OSC_FREQ/192L)/19200L //253
#define BAUD_14400 256 - (OSC_FREQ/192L)/14400L //252
#define BAUD_9600 256 - (OSC_FREQ/192L)/9600L //250
#define BAUD_4800 256 - (OSC_FREQ/192L)/4800L //244
#define BAUD_2400 256 - (OSC_FREQ/192L)/2400L //232
#define BAUD_1200 256 - (OSC_FREQ/192L)/1200L //208
#else
//若波特率不加倍,则使用下面参数;
#define BAUD_9600 256 - (OSC_FREQ/384L)/9600L
#define BAUD_4800 256 - (OSC_FREQ/384L)/4800L
#define BAUD_1200 256 - (OSC_FREQ/384L)/1200L
#endif
void Serial_Port_Initialization()
{
#if(BAUD_Time==1)
PCON = 0x80;//波特率翻倍
#else
PCON = PCON&0x7F;//波特率不翻倍
#endif
SCON = 0x50; //串行控制寄存器: SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//SM1:SM0=01,选择方式1,SM2=0,表示非多机通讯,8-bit UART;
//REN=1,使能接收;
TMOD |= 0x20; //定时器方式控制寄存器:GATE1,C/T1,M11,M10,GATE0,C/T0,M01,M00
//GATE=0,TR置1便可以启动Timer;GATE=1,TR置1,且INT脚输入高电
//平,才可以启动Timer;
//M11:M10=10,选择方式2,8位自动重装载;
if(PCON &0x80==0x80)TH1 = BAUD_9600; //TH1: reload value for 9600 baud @ 11.0592MHz
else TH1 = BAUD_9600; //TH1: reload value for 9600 baud @ 11.0592MHz
TR1 = 1; //启动Timer1;
TI = 1; //发送UART的第一个字节,为下次发送做准备;
}
3、定时器0工作在模式3应用
#include <REG51.h> //包含头文件REG51.h,使能51内部寄存器;
#include <stdio.h> //包含头文件stdio.h
//_getkey();从串口读入一个字符;
//putchar();向串口发送一个字节;
//printf();向串口发送一串字节;
//定时器的方式控制寄存器TMOD: GATE1,C/T1,M1_1,M1_0,GATE0,C/T0,M0_1,M0_0
//GATE1=1,表示T1是受INT1脚(P3.3)控制运行;
//C/T1=0,表示T1的时钟源为fosc/12;C/T1=1,表示T1的时钟源为T1脚(P3.5);
//GATE0=1,表示T0是受INT0脚(P3.2)控制运行;
//C/T0=0,表示T0的时钟源为fosc/12;C/T0=1,表示T0的时钟源为T0脚(P3.4);
//下面说明T0的工作方式
//M0_1:M0_0=00,表示T0为13位定时器/计数器;
//M0_1:M0_0=01,表示T0为16位定时器/计数器;
//M0_1:M0_0=10,表示T0为8位自动重装载定时器/计数器;
//M0_1:M0_0=11,表示T0分为两个8位计数器;
//下面说明T1的工作方式
//M1_1:M1_0=00,表示T1为13位定时器/计数器;
//M1_1:M1_0=01,表示T1为16位定时器/计数器;
//M1_1:M1_0=10,表示T1为8位自动重装载定时器/计数器;
//M1_1:M1_0=11,表示T1没有此工作方式;
//定时器的控制寄存器TCON: TF1,TR1,TF0,TR0,IE1,IT1,IE0,IT0
//TF1=1,表示T1溢出到0x0000,CPU响应中断后,由硬件自动清除;
//当GATE1=0时,TR1=1,表示启动T1开始工作,当GATE1=1时,Timer1由INT1脚(P3.3)和TR0控制;
//TF0=1,表示T0溢出到0x0000,CPU响应中断后,由硬件自动清除;
//当GATE0=0时,TR0=1,表示启动T0开始工作,当GATE0=1时,Timer0由INT0脚(P3.2)和TR0控制;
#define OSC_FREQ 11059200L
//#define BAUD_115200 256 - (OSC_FREQ/192L)/115200L //
//#define BAUD_38400 256 - (OSC_FREQ/192L)/38400L //
#define BAUD_Time 1
#if(BAUD_Time==1)
//若波特率加倍,则使用下面参数;
#define BAUD_57600 256 - (OSC_FREQ/192L)/57600L //255
#define BAUD_28800 256 - (OSC_FREQ/192L)/28800L //254
#define BAUD_19200 256 - (OSC_FREQ/192L)/19200L //253
#define BAUD_14400 256 - (OSC_FREQ/192L)/14400L //252
#define BAUD_9600 256 - (OSC_FREQ/192L)/9600L //250
#define BAUD_4800 256 - (OSC_FREQ/192L)/4800L //244
#define BAUD_2400 256 - (OSC_FREQ/192L)/2400L //232
#define BAUD_1200 256 - (OSC_FREQ/192L)/1200L //208
#else
//若波特率不加倍,则使用下面参数;
#define BAUD_9600 256 - (OSC_FREQ/384L)/9600L
#define BAUD_4800 256 - (OSC_FREQ/384L)/4800L
#define BAUD_1200 256 - (OSC_FREQ/384L)/1200L
#endif
#define TL0_Load_Value 256-100L //配置TL0为100us中断一次;
#define TH0_Load_Value 256-200L //配置TH0为200us中断一次;
sbit LED1 = P1^0;
sbit LED2 = P1^1;
uynsigned int Time0TL0Count;
uynsigned int Time0TH0Count;
//函数功能: TL0计数器的中断服务函数,每100us中断一次;
void TL0_interrupt_program() interrupt 1 using 1
{ TL0=TL0_Load_Value; //手动装载初值;
Time0TL0Count++;
if(Time0TL0Count>5000)//0.5秒
LED1=~LED1;
}
//函数功能: TH0计数器的中断服务函数,每200us中断一次;
void TH0_interrupt_program() interrupt 3 using 1
{
TH0=TH0_Load_Value; //手动装载初值;
Time0TH0Count++;
if(Time0TH0Count>5000)//0.5秒
LED2=~LED2;
}
//函数功能: Timer0初始化;
void timer0_initializtion()
{ TMOD&= 0xF4; //设置GATE0=0,即不允许外部INT0脚控制Timer0;
TMOD|= 0x03; //配置Timer0为方式3(两个8位定时器,一个用TL0计数,一个用TH0计数);
TL0=TL0_Load_Value; //手动装载初值;
TH0=TH0_Load_Value; //手动装载初值;
TR0=1; //当GATE0=0时,TR0=1,表示启动Timer0中的TL0开始工作;
TR1=1; //设置Timer0的TH0时钟源为晶振频率的1/12,并启动TH0开始工作;
ET0=1; //允许Timer0中的TL0溢出中断;
ET1=1; //允许Timer0中的TH0溢出中断;
EA=1; //开总中断允许位;
Time0TL0Count=0;
Time0TH0Count=0;
}
//函数功能: Timer1初始化;
void timer1_initializtion()
{ TMOD&= 0x4F; //设置GATE1=0,即不允许外部INT1脚控制Timer1;
TMOD|= 0x20; //配置Timer1为方式2(8位自动重装载),用于波特率发生器;
TH1=BAUD_9600; //TH1: reload value for 9600 baud @11.0592MHz;
TL1=TH1;
}
//函数功能:初始化串口,设置波特率为9600bps@11.0592MHz,使能接收,使用8位UART;
void Serial_Port_Initialization()
{ PCON = 0x80;
SCON=0x50; //串行控制寄存器: SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//SM1:SM0=01,选择方式1,SM2=0,表示非多机通讯,8-bit UART;
//REN=1,使能接收;
timer1_initializtion();
TI=1; //发送UART的第一个字节,为下次发送做准备;
RI=0;
//ES=1; //使能串口接收和发送中断;
EA=1; //开总中断
}
void main(void)
{ timer0_initializtion(); //Timer0初始化;
Serial_Port_Initialization();
//初始化串口,设置波特率为9600bps@11.0592MHz,使能接收,使用8位UART;
printf( "Timer0 works in mode3;\n" );
printf( "TL0 is a timer.\n" );
printf( "TH0 is a timer,too;\n" );
printf( "Timer1 works in mode2,It is a baud_rate_generator!\n" );
while(1);
{
}
}