知识的价值不在于占有,而在于使用。这篇文章主要讲述实例7:stc8a8k定时器0,定时50ms,进入中断之后,加数20次到1秒,计算时间。相关的知识,希望能为你提供帮助。
一、实验目的 1、熟悉定时器T0的使用;
2、按下按键KEY1,开始计时间,在OLED显示时间;
3、熟悉中断的作用;
二、实验设备 stc8a开发板;
OLED屏幕,4脚OLED;
下载器;
三、实验原理 1、中断的概念; 【实例7(stc8a8k定时器0,定时50ms,进入中断之后,加数20次到1秒,计算时间。)】在主程序中,正在运行一段程序,突然有个信号过来,告诉主程序,你先来执行我的程序,主程序就执行中断程序,执行完之后,继续允许主程序。
我正在吃饭,然后突然有个电话过来,听完电话,之后,我们继续吃饭。
类似这样。所以这个中断信号会打断我们正在执行的任务。
那么那些可以是中断信号呢?
定时器中断,定时时间到,就执行他的程序,然后继续主程序;
外部中断,外面有个按钮,别人一按按钮,就先停止你的,执行他们的;
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)总中断打开?
当我们需要打开定时器的时候,就打开就行了,不需要,记得关闭。
文章图片
:
文章图片
3、定时器T0的使用和相关寄存器;
文章图片
#include "reg51.h"
#include "intrins.h"//测试工作频率为11.0592MHzsbitP10=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开始计时
}
**
用STC软件案例代码修改:
文章图片
案例:一定请琢磨透彻。
//******************************************************************************/
#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秒加起来
}
}
**
推荐阅读
- 编译器优化机制详解
- 实例3,stc8a利用内置的PWM模块,控制小车直流电机运动
- 实例6配套头文件和c文件,4脚OLED显示,I2C
- 测试
- 小车,测走过的距离,计算走过的时间,stc8a8k
- RedHat的yum配置 以及提示“This system is not registered with RHN”的解决
- 实例8(stc8a8k外部中断,计算小车运行的距离)
- 实例6,stc8a8k单片机开发板4脚的OLED显示数据(I2C通信)
- MYSQL查看和新增表分区