时间:2024.9.2
目的:手撕51
作者:Whappy
定时器0寄存器配置
1.定时器0配置过程
首先要配置定时器的寄存器TCON和TMOD使计数器开始计数及定时器的初始值,配置使这个链路连起来。
#include <REGX52.H>
void Timer0_Init()
{
TMOD = 0x01; //工作模式寄存器
//控制寄存器
TF0 = 0;
TR0 = 1;
/*定时器赋初值 定时1ms,12Mhz的晶振,1us产生一个计数脉冲,
而16位的计数器是0~65535个可能,也就是65536us,65536个脉冲
如何差生一微秒(1ms=1000us)那么从64535开始记到65535产生一个中断
通过配置TL0和TH0控制处置也就是把64535变成16进制TL0是低八位两个十六进制,TH0是高八位的两十六进制*/
TL0 = 64535%56;
TH0 = 64535/256;
ET0 = 1;
EA = 1;
PT0 = 0;
}
void Timer0_Rountine(void) interrupt 1
{
P2_0 = 0;
}
void main()
{
Timer0_Init();
while(1)
{
}
}
配置好定时器之后,紧接着写一个定时器溢出时的中断服务程序,首先main函数在执行Timer0_Init()函数时,有上图红色画线的箭头可知,Timer0_Init()会进入Timer0_Rountine(void) interrupt 1 执行相应的操作,如上述程序,主函数并没有调用Timer0_Rountine(void) interrupt 1函数,但是我们执行Timer0_Init()函数时,Timer0_Init()函数进入到了Timer0_Rountine(void) interrupt 1函数,我们在Timer0_Rountine(void) interrupt 1函数中写了一个点灯命令,如果灯亮了说明Timer0_Init()函数调用了Timer0_Rountine(void) interrupt 1函数
2.精确定时1秒钟
unsigned int T0Count ;
void Timer0_Rountine(void) interrupt 1
{
TL0 = 64535%56; //重新赋初值
TH0 = 64535/256;
T0Count++;
if(T0Count >= 1000)
{
T0Count = 0;
P2_0 = ~P2_0;
}
}
中断函数如果不被打断就会被一直执行下去
3.按键k1控制流水灯
代码:
main.c
#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include <INTRINS.H>
unsigned char KeyNum,LEDMode;
void main()
{
P2=0xFE;
Timer0Init();
while(1)
{
KeyNum=Key(); //获取独立按键键码
if(KeyNum) //如果按键按下
{
if(KeyNum==1) //如果K1按键按下
{
LEDMode++; //模式切换
if(LEDMode>=2)LEDMode=0;
}
}
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++; //T0Count计次,对中断频率进行分频
if(T0Count>=500)//分频500次,500ms
{
T0Count=0;
if(LEDMode==0) //模式判断
P2=_crol_(P2,1); //LED输出
if(LEDMode==1)
P2=_cror_(P2,1);
}
}
Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,1毫秒@12.000MHz
* @param 无
* @retval 无
*/
void Timer0Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
*/
Key.c
#include <REGX52.H>
#include "Delay.h"
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
*/
unsigned char Key()
{
unsigned char KeyNumber=0;
if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}