STM8S_003_TIM定时中断

发布者:RadiantSerenity最新更新时间:2017-09-16 来源: eefocus关键字:STM8S  TIM  定时中断 手机看文章 扫描二维码
随时随地手机看文章

Ⅰ、写在前面

上一篇文章讲述了TIM精确延时(阻塞式),它主要的特点是延时精确,而阻塞式延时在这一延时过程中不能做其它事情,只能等待延时结束。

 

在某些场合下,我们需要在延时的过程中也要进行其它操作,如在延时过程中需要检测某一个IO口的电平状态、检测某一按键是否处于按下状态等。这个时候我们简单的处理方法就是使用定时中断,一旦这个延时时间到就进行下一个操作。

 

本文将简单讲述如何实现TIM定时和中断,提供简单的例程源代码。



为方便大家阅读,本文内容已经整理成PDF文件:

http://pan.baidu.com/s/1i5uWhJR


作者:strongerHuang

版权所有,未经允许,禁止用于其它商业用途!!!

 

Ⅱ、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状态···)。


Ⅳ、下载

STM8S资料:

http://pan.baidu.com/s/1o7Tb9Yq

 

软件源代码工程(STM8S-A03_TIM定时中断):

http://pan.baidu.com/s/1c2EcRo0


关键字:STM8S  TIM  定时中断 引用地址:STM8S_003_TIM定时中断

上一篇:STM8S_004_UART基本收发数据
下一篇:STM8S_002_TIM精确延时(阻塞式)

推荐阅读最新更新时间:2024-03-16 15:37

avr单片机定时器0溢出中断程序
2014年2月17日22:26:32 芯片名称: AVR (艾特梅尔公司)mega16A 微控制器芯片; 开发板: 自主研发的 YF-A1芯片开发板; (YF :是本人名字缩写 ) 第53次试验,用逻辑分析仪捕捉,输出于IO口的数字,脉冲信号,脉冲信号宽度:1.5~1.8微妙,每9~11个脉宽1.5us的信号时序中,夹杂着一个脉宽位为3微妙的高脉冲信号. 我用了好几个小时都计算不出定时器0内部的时钟频率........哪里出错了呢? 外部用12兆晶体整荡器; 我的计算结论是:定时器0内部频率为32khz ,但是这显然有问题. 定时器时钟为内部8分频 TCCR0=0X0
[单片机]
STM8S之GPIO自学笔记
STM8S105C6T6 48个引脚 32KB Flash 封装:LQFP temp:-40~85 PA1~PA6,PB0~PB7,PC1~PC7,PD0~PD7,PE0~PE3,PE5~PE7,PG0,PG1, 一共38个通用I/O口。 GPIO寄存器 端口x输出数据寄存器(Px_ODR); 端口x输入数据寄存器(Px_IDR); 端口x输出数据方向(Px_DDR);0:输入模式 1:输出模式; 端口x控制寄存器1(Px_CR1); 当DDR=1;置0 模拟开漏输出;置1 推挽输出;(CR2位做输出摆率控制); 当DDR=0;置0 浮空输入;置1 上拉输入; 端口x控制寄存器2(Px_CR2); 当DDR=0;置0 禁止外部
[单片机]
STM32基本定时TIM6和TIM7
1. STM32上定时器的分类 前面学习了STM32系统定时器SysTick,它的主要作用是为OS提供系统滴答,当然我们也可以利用它实现了精准延时。在STM32单片机中,除了属于CM3内核中的一个外设的系统定时器外,还有几个属于片上外设的定时器:基本定时器(TIM6和TIM7)、通用定时器(TIM2/3/4/5)和高级定时器(TIM1和TIM8)。强调,这里指的是除互联型的STM32F1系列单片机。 它们各自具有的功能特点可以详见《STM32中文参考手册_V10.pdf》-P298,这里简单描述: (1)基本定时器(TIM6和TIM7):16位的只能向上计数的定时器,只能实现定时,没有外部IO通道与它关联。
[单片机]
STM32基本<font color='red'>定时</font>器<font color='red'>TIM</font>6和<font color='red'>TIM</font>7
STM8s窗口看门狗
看看窗口看门狗的框图 从图里看出产生复位信号有2个方式: 1 WDGCR寄存器的T6 由1变0,也就是从此寄存器的值从0x40变成0x3F会产生复位信号; 2 当寄存器WDGCR的值大于WDGWR的时候写WDGCR寄存器会产生复位信号; 解释: WDGCR的最高位WDGA是开启看门狗的(WDGA=1开启),当然如果开启了硬件看门狗这个位就没用了。硬件看门狗在OPTION BYTES里设置。 WDGCR的低六位是计数用的从图里可以得出这个计数器的时钟是fCPU时钟分频得来的。这个分频值固定是12288,根据这个可以计算看门狗的延时时间。 WDGWR是窗口寄存器,最高位保留,低六位保存的是窗口值,从图里的逻辑图发现co
[单片机]
<font color='red'>STM8s</font>窗口看门狗
STM8S学习02——ADC
一、ADC_转换模式 1、ADC支持5种转换模式:单次模式,连续模式,带缓存的连续模式,单次扫描模式,连续扫描模式。 2、单次模式 在单次转换模式中, ADC仅在由ADC_CSR寄存器的CH 选定的通道上完成一次转换。 该模式是在当CONT位为0时通过置位ADC_CR1 寄存器的ADON位来启动的。 一旦转换完成,转换后的数据存储在ADC_DR寄存器中, EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断。 3、连续和带缓存的连续模式 在连续转换模式中,ADC在完成一次转换后就立刻开始下一次的转换。当CONT位被置位时即将ADC设为连续模式,该模式是通过置位 ADC_CR1寄存器的 ADON 位来启动的。 (
[单片机]
STM8S库GPIO_ReadInputPin函数问题
ST官网推出了库函数操作,大大方便了用户,但是库函数有一些问题,例如 1.库函数GPIO_ReadInputPin问题 以下是ST文件读取指定IO口电平原型 BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin) { return ((BitStatus)(GPIOx- IDR & (uint8_t)GPIO_Pin)); } 当你在程序中调用 if(GPIO_ReadInputPin(GPIOC,GPIO_PIN_7) == SET) { .................. } 你会发现你永远得不到你想要的! 原
[单片机]
关于基于STM8S,MPU6050驱动的说明及程序
这个MPU6050使用的是IIC驱动的,而在具体电路图中没有使用STM8S自带的硬件IIC接口,所使用的是模拟IIC, 需要指出的是,在STM8S,IO配置的时候,SDA,对于挂SDA的IO来说,在STM8S的处理器上IO是没有真正的开漏输出功能的, 也就是将该IO配置成开漏输出的时候,IO高低电平输出实际是没有变化的,所以在IO具体输出或者读取状态的时候,必须切换IO模式, 另外需要注意的是,在配置IO的输出模式的时候,最好直接使用寄存器操作,如果使用 g_sda_output(); Handler_G_SDA_L;,也就是库函数操作的话,那么在配置成输出模式之后,并且接下来的代码立即输出高或者低的时候,
[单片机]
STM8S系统时钟应用(IAR)
STM8上电运行时默认使用内部16M的RC振荡器经8分频后的2M时钟频率作为系统时钟。程序开始运行后可以通过设置相关寄存器来修改主时钟源,可以选择外部晶振作为主时钟源和CPU时钟分频。那么这里就选择比较简单的操作,修改内部RC时钟预分频器获得8M系统时钟。 增加内部RC时钟预分频后的代码如下: #i nclude iostm8s207sb.h #define LED1_FLASH PD_ODR_ODR3 = !PD_ODR_ODR3 // LED闪灯指示 void delay(unsigned int count) { while(count--); } void CLK_init(void) { CLK_C
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved