因为使用Delay函数延时会一直占用cpu,导致cpu不能够做其他事情,
就需要配置两个和定时器T1,其余在这个实验不需要配置
还需要涉及定时器的功能
具体看手册
TL0 +TH0共 十六位寄存器,TF0 溢出65535个时间脉冲,申请中断,
SYSclk或者T0pin提供时钟,进行12 或6分频,C/T是选择counter还是timer即计数器或定时器。
中断系统
在这里定时器溢出发出中断,cpu转而执行最优中断级别的事件,可以进行中断嵌套。
最新版本请看手册
下面进行流水灯控制
代码如下
#include <REGX52.H>
#include "Timer.h"
#include "Delay.h"
#include "Key.h"
#include <INTRINS.H>
/*
使用定时器0做定时器中断做流水灯控制
*/
unsigned char Keynumber;//储存按键
unsigned char LEDmode;//判断led的模式是左流水还是右流水
void main()
{
P2=0xFE;//先初始化P2
Timer0Init();//初始化定时器0
/*
解释一下,程序正常运行,当计时器中断来临,程序从正常的while循环里面跳出来
执行interupt1中断服务子程序,在这里是转换led流水灯方向
*/
/*
实现流水灯,可以使用循环右移或左移
*/
while(1)
{
Keynumber=Key();
if(Keynumber)
{
if(Keynumber==1)//如果按键1按下
{
LEDmode++;
if(LEDmode>=2)LEDmode=0;//ledmode只有两种模式,按一下按键切换一种模式进行led流水
}
}
}//
}
/*
中断服务子程序
*/
static unsigned int Tcount;
void Timer0_Routine() interrupt 1//在这里实现流水灯控制
{
TL0 = 0x18; //设置定时初始值,每次执行中断后寄存器就变成0,所以要重新赋初值
TH0 = 0xFC; //设置定时初始值
Tcount++;//每次中断+1
if(Tcount>=500)//即到了1s
{
Tcount=0;
if(LEDmode==0)//模式一
P2=_cror_(P2,1);//循环右移进行流水灯
if(LEDmode==1)//模式二
P2=_crol_(P2,1);//循环左移
}
}
相关的模块化文件
//定时器模块Timer.c
#include <REGX52.H>
//自己配置
// //TMOD=0x01;//0000 0001 配置工作模式,但是每次操作会覆盖第四位
// TMOD&=0xF0;//将
// TF0=0;//中断标志位,当为1时产生中断
// TR0=1;//定时器是否开启
// TH0=64535/256;//定时器赋初值th0为高位,最大可以计数65535,赋初值可以取整1000个时间脉冲
// TL0=64535%256;
// ET0=1;//下面都是中断配置
// EA=1;
// PT0=0;
void Timer0Init(void) //1毫秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;//下面都是中断配置
EA=1;
PT0=0;
}
```c
//Delay.c
#include <INTRINS.H>
void Delayms(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}