打印
[ARM入门]

众拳【STM8入门】第20讲 STM8普通定时器(TIM4)精准延时

[复制链接]
1025|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 刘洋讲单片机 于 2017-1-11 14:49 编辑

第20讲.STM8普通定时器(TIM4)精准延时.zip (215.8 KB)

众拳【剑齿虎STM8】开发板学习笔记分享
点击此处查看全部资料

第20讲   STM8普通定时器(TIM4)精准延时

目 录
20.1概述        2
20.1.1  定时器特点        3
20.2实验目的        3
20.3程序文件设计        3
20.3.1  lib文件中内容分析        3
20.3.2  main.c文件中的程序        4
20.3.3  tim.c文件中的程序        5
20.3.4  tim.h文件中的程序        7
20.3.5  stm8s_it.c文件中的程序        7
20.3.6  led.c文件中的程序        8
20.3.7  led.h文件中的程序        9
20.3.8  补充说明        10


20.1概述   
STM8S提供三种类型的TIM定时器:高级控制型(TIM1)、通用型(TIM2/TIM3/TIM5)和基本型定时器(TIM4/TIM6)。它们虽有不同功能但都基于共同的架构。此共同的架构使得采用各个定时器来设计应用变得非常容易与方便(相同的寄存器映射,相同的基本功能)。
20.1.1  定时器特点
TIM1—16位高级控制定时器
TIM2,TIM3—16位通用定时器
TIM4—8位基本定时器

20.2实验目的   
从上表中我们可以看出TIM4是8位定时器,它计数的最大值是255,当计数大于255后就溢出。相对与其它3个定时器它是最简单的。
本次实验目的是用TIM4定时器实现1毫秒钟精确定时。
20.3程序文件设计
20.3.1  lib文件中内容分析
我们在“Lib”文件夹,把引用系统本身定义好的库函数添加在其中,我们使用到哪个外设功能,直接引用到此文件夹中即可。
本节实验及以后的实验我们都是用到库文件,其中 stm8s_conf.h头文件包含了所有外设的声明头文件,在本试验中我们使用到时钟外设和GPIO端口外设。所以#include "stm8s_clk.h"、#include "stm8s_tim4.h"和#include "stm8s_gpio.h"需要“打开”(就是把语句前面的双斜线注释符号删除即可,参考图17.1)。Stm8s_gpio.c库函数包含了所有管脚初始化功能和具体的执行操作;Stm8s_clk.c库函数主要包含了内部时钟和外部时钟设置,在主函数中规定了具体的执行方法,在这个函数中就有具体相关的执行步骤;Stm8s_tim4.c库函数主要包含了定时器4相关寄存器设置和tim4库函数具体执行过程。
20.3.2  main.c文件中的程序
主程序就实现初始化和调用驱动程序,这样主程序控制思路清晰,流程简单。要想了解全面详实的程序,请大家参考光盘(网盘)中程序及程序注释。
/***********************************************************************
*   说    明: STM8(TIM4)定时器
*   开发平台: 剑齿虎STM8开发板        

*   关注微信公众平台微信号:"zxkj-ly",免费获取STM8资料。
*   STM8技术交流QQ群【335123291】
*   哈尔滨卓恩科技开发有限公司
*
*   作    者: 刘洋 张殿东
*   版    本: V1.0
*   日    期: 2016-05-03   
*
*   IAR开发环境    版本 V2.20.1
*   ST库函数       版本 V2.2.0
***********************************************************************/
#include "pbdata.h"//引入自定义公共头文件
void BSP_Configuration(void);//硬件初始化函数声明
/***********************************************************************
*   函 数 名: main
*   功能说明: c程序入口
*   形    参:无
*   返 回 值: 错误代码(无需处理)
***********************************************************************/
int main(void)
{
  BSP_Configuration();//硬件驱动初始化函数
    while(1)//主程序循环,反复执行循环体里的语句
  {
    LED1_R;//PE0引脚电平取反,高电平时LED1发光二极管(熄灭),底电平时LED1发光二极管(发光)
    LED2_R;//PA3引脚电平取反,高电平时LED2发光二极管(熄灭),底电平时LED2发光二极管(发光)
    LED3_R;//PA6引脚电平取反,高电平时LED3发光二极管(熄灭),底电平时LED3发光二极管(发光)
    Tim4_ms(1000);
  }
}
/***********************************************************************
*   函 数 名: BSP_Configuration
*   功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
*   形    参:无
*   返 回 值: 无
***********************************************************************/
void BSP_Configuration(void)
{  
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//时钟速度为内部16M,1分频,
  LED_Init();//调用LED初始化函数
  Tim4_Init();//调用TIM4初始化程序
  rim();//打开总中断
}
/*断言函数:它的作用是在编程的过程中为程序提供参数检查*/
#ifdef USE_FULL_ASSERT
void assert_failed(u8* file,u32 line)
{
  while(1)
  {
  }
}
#endif
20.3.3  tim.c文件中的程序
#include "pbdata.h"
u32 Tim4_Upd_n=0;
/***************************************************************************
*   函 数 名: Tim4_Init
*   功能说明: 初始化通用定时器3
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void Tim4_Init(void)
{
    TIM4_TimeBaseInit(TIM4_PRESCALER_16,100);//初始化定时器4
    TIM4_ARRPreloadConfig(ENABLE);//使能自动重装
    TIM4_ITConfig(TIM4_IT_UPDATE , ENABLE);//数据更新中断
    TIM4_Cmd(ENABLE);//开定时器
}
/***************************************************************************
*   函 数 名: Tim3_Led
*   功能说明: Tim3实现流水灯效果
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void Tim3_Led(void)
{
    static u8 id=0;
    switch(id)//switch 选择语句
    {
        case 0://LED1 发光 LED2 熄灭  LED3 熄灭
          {
                LED1_L;//拉低PE0引脚,LED1发光二极管(发光)
                LED2_H;//拉低PA3引脚,LED2发光二极管(发光)
                LED3_H;//拉低PA6引脚,LED3发光二极管(发光)
          }
          break;
        case 1://LED1 熄灭 LED2  发光 LED3 熄灭
          {
                LED1_H;//拉低PE0引脚,LED1发光二极管(发光)
                LED2_L;//拉低PA3引脚,LED2发光二极管(发光)
                LED3_H;//拉低PA6引脚,LED3发光二极管(发光)
          }
          break;
        case 2://LED1 熄灭 LED2 熄灭  LED3  发光
          {
                LED1_H;//拉低PE0引脚,LED1发光二极管(发光)
                LED2_H;//拉低PA3引脚,LED2发光二极管(发光)
                LED3_L;//拉低PA6引脚,LED3发光二极管(发光)
          }
          break;   
    }
    if(id<2) id++; //ID的范围是0~2 分别代表着switch 选择语句的3个分支
    else id=0;     //当ID 大于等于2 时  ID清零
}
/***************************************************************************
*   函 数 名: Tim4_Upd
*   功能说明: Tim4精准延时函数计数
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void Tim4_Upd(void)
{
    if(Tim4_Upd_n!=0)
    {
        Tim4_Upd_n--;
    }
}
/***************************************************************************
*   函 数 名: Tim4_ms
*   功能说明: Tim4精准延时函数
*   形    参:u32 nTime   输入1为1个毫秒
*   返 回 值: 无
***************************************************************************/
void Tim4_ms(u32 nTime)
{
    Tim4_Upd_n=nTime*10;//输入参数扩大10
    while(Tim4_Upd_n!=0);//延时等待  当Tim4_Upd_n=0时退出while循环
}
20.3.4  tim.h文件中的程序
#ifndef _TIM_H//宏定义,定义文件名称
#define _TIM_H
#include "stm8s.h"
/*--------------------------函数声明------------------------------------*/
void Tim4_Init(void);//初始化定时器4
void Tim4_Upd(void);//Tim4精准延时函数计数
void Tim4_ms(u32 nTime);//Tim4精准延时函数
#endif //定义文件名称结束
20.3.5  stm8s_it.c文件中的程序
中断和中断处理子程序建立关系必须在stm8s_it.c文件中对应位置中建立。关于定时器4的中断处理子程序要写在事先定义好的入口之内。“INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)”,所以中断处理子程序入口地址必须放在TIM4中断处理中,请看下面程序语句。
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
    Tim4_Upd();  //调用Tim4精准延时函数计数  
    TIM4_ClearITPendingBit(TIM4_IT_UPDATE);//清除更新标志位
}
20.3.6  led.c文件中的程序
#include "pbdata.h"
/***************************************************************************
*   函 数 名: LED_Init
*   功能说明: LED的GPIO管脚初始化
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void LED_Init(void)
{
  GPIO_Init(LED1_PORT, LED1_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED1管脚为低速开漏输出高阻态
  GPIO_Init(LED2_PORT, LED2_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED2管脚为低速开漏输出高阻态
  GPIO_Init(LED3_PORT, LED3_PIN, GPIO_MODE_OUT_OD_HIZ_SLOW);//初始化LED3管脚为低速开漏输出高阻态
}
/***************************************************************************
*   函 数 名: LED_Demo1
*   功能说明: 闪烁例程,间隔时间为1秒。
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void LED_Demo1(void)
{
    LED1_L;//拉低PE0引脚,LED1发光二极管(发光)
    LED2_L;//拉低PA3引脚,LED2发光二极管(发光)
    LED3_L;//拉低PA6引脚,LED3发光二极管(发光)
    delay_ms(1000);//延时1秒
    LED1_H;//拉高PE0引脚,LED1发光二极管(熄灭)
    LED2_H;//拉高PA3引脚,LED2发光二极管(熄灭)
    LED3_H;//拉高PA6引脚,LED3发光二极管(熄灭)
    delay_ms(1000);//延时1秒
}
/***************************************************************************
*   函 数 名: LED_Demo2
*   功能说明: 闪烁例程,间隔时间为1秒。
*   形    参:无
*   返 回 值: 无
***************************************************************************/
void LED_Demo2(void)
{
    LED1_R;//PE0引脚电平取反,高电平时LED1发光二极管(熄灭),底电平时LED1发光二极管(发光)
    LED2_R;//PA3引脚电平取反,高电平时LED2发光二极管(熄灭),底电平时LED2发光二极管(发光)
    LED3_R;//PA6引脚电平取反,高电平时LED3发光二极管(熄灭),底电平时LED3发光二极管(发光)
    delay_ms(1000);//延时1秒
}
20.3.7  led.h文件中的程序
/***********************************************************************
*    剑齿虎STM8开发板硬件连接
*    LED1-PE0         
*    LED2-PA3         
*    LED3-PA6         
************************************************************************/
#ifndef _LED_H  //宏定义,定义文件名称
#define _LED_H
/*---------------------------头文件引用--------------------------------------*/
#include "stm8s.h"//引用STM8头文件
/*---------------------------宏定义声明--------------------------------------*/
#define LED1_PIN GPIO_PIN_0  //定义GPIO_PIN_0引脚为LED1_PIN,相当于重新命名。
#define LED2_PIN GPIO_PIN_3  //定义GPIO_PIN_3引脚为LED2_PIN,相当于重新命名。
#define LED3_PIN GPIO_PIN_6  //定义GPIO_PIN_6引脚为LED3_PIN,相当于重新命名。
#define LED1_PORT GPIOE  //定义GPIOE端口为LED1_PORT,相当于重新命名。
#define LED2_PORT GPIOA  //定义GPIOA端口为LED2_PORT,相当于重新命名。
#define LED3_PORT GPIOA  //定义GPIOA端口为LED3_PORT,相当于重新命名。
//如果想用其他管脚控制LED,那么只需更改上面对应的端口与引脚编号即可
#define LED1_L GPIO_WriteLow(LED1_PORT,LED1_PIN);       //定义LED1_L,调用LED1_L命令,PE0引脚输出低电平
#define LED1_H GPIO_WriteHigh(LED1_PORT,LED1_PIN);      //定义LED1_H,调用LED1_H命令,PE0引脚输出低高平
#define LED1_R GPIO_WriteReverse(LED1_PORT,LED1_PIN);   //定义LED1_R,调用LED1_R命令,PE0引脚输出电平状态取反
#define LED2_L GPIO_WriteLow(LED2_PORT,LED2_PIN);       //定义LED2_L,调用LED2_L命令,PA3引脚输出低电平
#define LED2_H GPIO_WriteHigh(LED2_PORT,LED2_PIN);      //定义LED2_H,调用LED2_H命令,PA3引脚输出低高平
#define LED2_R GPIO_WriteReverse(LED2_PORT,LED2_PIN);   //定义LED2_R,调用LED2_R命令,PA3引脚输出电平状态取反
#define LED3_L GPIO_WriteLow(LED3_PORT,LED3_PIN);       //定义LED3_L,调用LED2_L命令,PA6引脚输出低电平
#define LED3_H GPIO_WriteHigh(LED3_PORT,LED3_PIN);      //定义LED3_H,调用LED2_H命令,PA6引脚输出低高平
#define LED3_R GPIO_WriteReverse(LED3_PORT,LED3_PIN);   //定义LED3_R,调用LED2_R命令,PA6引脚输出电平状态取反
/*---------------------------函数声明--------------------------------------*/
void LED_Init(void);  //LED初始化函数
void LED_Demo1(void); //闪烁例程1,间隔时间为1秒
void LED_Demo2(void); //闪烁例程2,间隔时间为1秒
#endif //定义文件名称结束
20.3.8  补充说明
TIM4是一个很弱的定时器,使用过程中请大家注意:
1、预装载值不要选择太小,这个预装载值在理论上应该在它的范围内就可以,比如我们写成10,但在时基使用中不行,我们食言了很多次,最好的取值范围是50~255。
2、 预装载值不要大于255 。   
         

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

148

主题

499

帖子

61

粉丝