Ⅱ、TIM基础知识
在上一篇文章中讲述了一些关于TIM的知识,本文说一下TIM中断相关知识。
TIM框图:
TIM4属于基本定时器,是8位计数的定时器,也就是说UP-COUNTER和Auto-reload register是8位的寄存器,最大值只能为255。
主系统时钟fMASTER进来,通过分频Prescaler给计数器UP-COUNTER计数,当计数器和Auto-reload register相等时,有一个事件更新(这就是上文的延时时间到),如果使能了事件更新中断,则会响应中断(UIF)。
这里再次强调一下,基本定时器的8位的定时器,最大值为255,如果不满足要求,可以使用16位的通用定时器。
Ⅲ、软件工程源代码
1、关于工程
本文提供的工程代码是基于前面软件工程“STM8S_Demo”增加TIM定时器修改而来。初学的朋友可以参看我前面对应的基础文章,那些文章讲的比较详细。
工程以简单、易理解为主,方便更多初学者快速理解,工程的大部分配置都是使用默认配置,具体配置可参看我的文章:IAR for STM8系列教程(一)_新建软件工程详细过程。
2.软件概要说明
坚持简单、基础、方便初学者理解为原则,本文提供软件工程中的源代码只添加了最简单的内容:
系统初始化:System_Initializes
v BSP_Initializes:时钟初始化CLK_Configuration和GPIO_Configuration初始化;
v TIMER_Initializes:定时器初始化,本文重点内容;
功能实现:while(1)
v TIMTiming_Nms和TIMTiming_Off:开启定时和关闭定时;
v TIM4_UPD_OVF_IRQHandler:定时器中断。
3.代码分析说明
关于BSP_Initializes中的内容这里不再详细说明,请见前面相关的文章:STM8S_001_GPIO基础知识
本文重点讲述关于TIM相关的内容:
A.TIMER_Initializes定时器初始化
void TIMER_Initializes(void)
{
TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125-1); //定时1ms (16M/128/125 = 1000)
TIM4_ClearFlag(TIM4_FLAG_UPDATE); //清除标志位
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE); //使能更新UPDATE中断
enableInterrupts(); //使能全局中断
}
我们提供的软件工程是实现1ms的延时,实现的公式为:16MHz / 128 / 125 = 1KHz(1ms)。
第一个参数TIM4_PRESCALER_128:即128分频,这个参数为枚举类型,具体为如下:
typedef enum
{
TIM4_PRESCALER_1 = ((uint8_t)0x00),
TIM4_PRESCALER_2 = ((uint8_t)0x01),
TIM4_PRESCALER_4 = ((uint8_t)0x02),
TIM4_PRESCALER_8 = ((uint8_t)0x03),
TIM4_PRESCALER_16 = ((uint8_t)0x04),
TIM4_PRESCALER_32 = ((uint8_t)0x05),
TIM4_PRESCALER_64 = ((uint8_t)0x06),
TIM4_PRESCALER_128 = ((uint8_t)0x07)
} TIM4_Prescaler_TypeDef;
第二个参数125-1:这个参数的值,实际上的自动重载寄存器(Auto-reload register)的值,也是定时的周期值。从公式中可以看出,它是得出1ms延时的来源。
很多人不理解为什么125-1,而不是125呢?
原因很简单:计数是从0开始的,0至124就是计数125个,因此这里是124。
语句TIM4_ClearFlag(TIM4_FLAG_UPDATE):
这条语句的意思很简单,清除UPDATE更新标志位。
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
enableInterrupts();
如果我们需要在定时的时间到了之后响应中断,只需要配置这两条语句即可。(在中断函数里面添加需要的内容)
B.启动和关闭定时:TIMTiming_Nms / TIMTiming_Off
void TIMTiming_Nms(uint16_t Times)
{
gTIMTiming_Num = Times; //定时Nms
gTIMTiming_Flag = 0; //清零标志
TIM4_SetCounter(0); //计数值归零
TIM4_Cmd(ENABLE); //启动定时器
}
void TIMTiming_Off(void)
{
gTIMTiming_Flag = 0;
TIM4_Cmd(DISABLE); //关闭定时器
}
本文提供代码中定义了两个全局变量:
gTIMTiming_Num:定时计数(定时多少ms)
gTIMTiming_Flag:定时标志(0-无效 1-有效),也就是我们定时的时间到,有效的标志。
TIM4_SetCounter(0);
每次启动定时器之前,将计数值归零,这样才能保证第一次计数(延时)准确。
C.定时中断
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
TIM4_ClearITPendingBit(TIM4_IT_UPDATE); //清除中断标志
gTIMTiming_Num--;
if(0 == gTIMTiming_Num)
{
TIM4_Cmd(DISABLE); //关闭定时器
gTIMTiming_Flag = 1; //标志有效
}
}
中断的入口INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23),位于stm8s_it.c文件下面,由系统决定,我们不用去修改。
每次进入中断,需要添加语句TIM4_ClearITPendingBit(TIM4_IT_UPDATE);清除中断标志位。后面的由我们自己添加,我这里为了方便测试,使用gTIMTiming_Num变量,这样可以使定时时间为1ms的倍数。
D.具体实现功能
TIMTiming_Nms(500); //定时500ms
while(1)
{
if(1 == gTIMTiming_Flag)
{
gTIMTiming_Flag = 0; //清除标志
LED_REVERSE; //LED变化
TIMTiming_Nms(500); //定时500ms
}
//添加处理语句
}
这里实现的功能比较简单,定时500ms改变LED的状态。在这里可以添加自己的处理语句(如检测某一IO状态···)。
上一篇:IAR for STM8系列教程(一)_新建软件工程详细过程
下一篇:STM8控制4位LED数码管显示数字
推荐阅读最新更新时间:2024-11-09 11:28
设计资源 培训 开发板 精华推荐
- TAR5S19 点稳压器(低压差稳压器)的典型应用
- LTC3621EDCB-3.3 1.2Vout、同步至 600kHz、强制连续模式同步降压稳压器的典型应用
- AD9637-80EBZ,用于 AD9633、8 通道、12 位、80 MSPS 模数转换器的评估板
- NIS3001AEVAL,用于工业用 NIS3001 MOSFET 功率驱动器的评估板
- 使用STWLC68的基于Qi的无线功率接收器,适用于最高5W的低功率标准(BPP)应用
- 具有 3MHz 开关频率和顺序上电的 LTC3374EUHF 组合降压器的典型应用电路
- 232转485模块
- AN54,采用 LTC1147 5-14V、5V/1A 降压转换器和表面贴装技术的应用电路
- DC1922A,使用 LTC3129 高效率、15V、200mA 同步降压-升压 DC-DC 转换器的演示板
- LTC4367CMS8-1 用于限制浪涌电流的过压电源保护控制器的典型应用