1、熟悉定时器T0的使用;
2、按下按键KEY1,开始计时间,在OLED显示时间;
3、熟悉中断的作用;
stc8a开发板;
OLED屏幕,4脚OLED;
下载器;
在主程序中,正在运行一段程序,突然有个信号过来,告诉主程序,你先来执行我的程序,主程序就执行中断程序,执行完之后,继续允许主程序。
我正在吃饭,然后突然有个电话过来,听完电话,之后,我们继续吃饭。
类似这样。所以这个中断信号会打断我们正在执行的任务。
那么那些可以是中断信号呢?
定时器中断,定时时间到,就执行他的程序,然后继续主程序;
外部中断,外面有个按钮,别人一按按钮,就先停止你的,执行他们的;
PWM中断;
ADC中断;
串口中断;
等等。
这里有个内容,就是
,如果外面一队中断信号,先执行那个呢?有个优先级,如果不设置,就是默认的顺序。
怎么设置优先级呢?这个后面有需要我们再设置看手册就好了。
2、定时器的概念;
有时候需要单片机定时到一段时间之后,再执行它的函数。处理完,再回到主程序。就需要定时器。
stc8a8k有几个定时器,比较多。我们举例定时器T0的使用。T1和T0差不多。我们循迹小车中,使用T0作为计算小车运行的时间,使用T1作为蓝牙模块的波特率发生器。
首先,我们找手册,定时器0的用法,看看有什么内部资源;一般我们是要设置几个内容:
(1)定时的模式,
有些是16位有些13位,我们要设置一下,一般都是设置16位自动重载的模式;什么是16位自动重载呢,定时计数器,就是从0—1–2-3–2^16—0–1--2,计算到2的16次方,就会反过来0–1。。这里会自动重新计算。最大是2的16次方。这就有个概念就是定时的间隔,因为这里我们设置时12T的模式计算,那么计算一次,就是1us。
(2)定时初值赋值;我们这里定时50ms。
(3)定时器中断打开;?
(4)定时器开关TR0打开?
(5)总中断打开?
当我们需要打开定时器的时候,就打开就行了,不需要,记得关闭。
#include "reg51.h"
#include "intrins.h"
//测试工作频率为11.0592MHz
sbit P10 = P1^0;
void TM0_Isr() interrupt 1 using 1
{
P10 = !P10; //测试端口
}
void main()
{
TMOD = 0x00;
TL0 = 0x66; //65536-11.0592M/12/1000
TH0 = 0xfc;
TR0 = 1; //启动定时器
ET0 = 1; //使能定时器中断
EA = 1;
while (1);
}
学习案例:
1、TMOD=0x00;==0000 0000
TMOD寄存器干什么的?
是一个模式控制的寄存器,就是让定时器按照这个模式运行。
D7----D6–D5–D4控制的是定时器T1的;
GATE=0----------------用TR1控制开关
C、T=0-------------定时模式
M1=0
M0=0----------0 0 ----------16位自动重载模式
D3----D2–D1–D0控制的是定时器T0的;
GATE=0----------------用TR0控制开关
C、T=0-------------定时模式
M1=0
M0=0----------0 0 ----------16位自动重载模式
2- 定时初值的低八位和高8位。这个怎么计算呢?我们先不自己计算,用STC自动计算。
TL0 = 0x66; //65536-11.0592M/12/1000
TH0 = 0xfc;
选择相应模式,然后自动生成代码,包括工作模式,定时器初值等,都生成了,多快。当然我们要自己掌握,比如我们一开始不打开,就TR0=0就好了。把开关关了。
ET0 = 1; /使能定时器中断
,那么ET0=0,就是关闭定时器T0的中断了。
EA = 1;打开总的开关。我们的总开关要开着,不要太自私,其他中断也是用这个总开关的。
4、定时中断的使用(注意全局变量,局部变量的定义,看书本哦)
注意这个端口号和终端号,是对的,不能随便改哦。
void TM0_Isr() interrupt 1 using 1
{
P10 = !P10; //测试端口
}
5、编程思路。
定时50ms,定时器T0,因为不能定时1秒,必须定时50ms,计算20次,就得到50ms*20=1000ms=1秒。
用ISP下载软件生成初值50ms的代码。
void Timer0Init(void) //50毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//******************************************************************************/
#include "stc8a8k.h"
#include "oled.h"
#include "stdio.h"//显示浮点数的sprintf函数,需要
sbit key0=P3^4;
void delay_tms(unsigned int ms)
{
unsigned int i,j;
for(i=ms;i>0;i--)
for(j=0;j<1100;j++);
}
unsigned int count=0;//全局变量
unsigned int sec=0;//全局变量秒
//定时器0中断函数,不需要声明,直接就能用。
void TM0_Isr() interrupt 1 using 1
{
count++;
if(count==20) //到20次,就是1秒
{
sec++;
count=0;
}
}
void main()
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值50ms
TH0 = 0x4C; //设置定时初值50ms
TF0 = 0; //清除TF0标志
//TR0 = 1; //启动定时器
ET0 = 1; //使能定时器中断
EA = 1;
OLED_Init(); //初始化OLED
OLED_Clear() ;
while (1)
{
//按下开关,开启定时器T0
if(key0==0)
{
delay_tms(15);
if(key0==0)
{
TR0=1;//开启定时器T0
}
}
OLED_ShowNum(5*8,2,sec,5,16);
// 显示定时时间,1秒1秒加起来
}
}
**