| 
 
| 本帖最后由 刘洋讲单片机 于 2017-1-11 14:49 编辑 
 
 众拳【剑齿虎STM8】开发板学习笔记分享
 点击此处查看全部资料
 
    第19讲   STM8通用定时器(TIM3)流水灯实验
 
 目 录
 19.1实验目的        2
 19.2程序文件设计        3
 19.2.1  lib文件中内容分析        3
 19.2.2  main.c文件中的程序        4
 19.2.3  tim.c文件中的程序        5
 19.2.4  tim.h文件中的程序        6
 19.2.5  stm8s_it.c文件中的程序        6
 19.2.6  led.c文件中的程序        7
 19.2.7  led.h文件中的程序        8
 19.2.8  补充说明        9
 
 
 19.1实验目的
 用TIM3定时器产生1秒钟的定时中断,在定时器中断里,驱动3个LED发光二极管,使3个LED发光二极管实现流水灯的效果。
 19.2程序文件设计
 19.2.1  lib文件中内容分析
 我们建立一个“Lib”文件夹,把引用系统本身定义好的库函数添加在其中,我们使用到哪个外设功能,直接引用到此文件夹中即可。一般情况下下面这四个文件都得引用。
 
  图18.1  stm8s_conf.h头文件内部选择
 本节实验及以后的实验我们都是用到库文件,其中 stm8s_conf.h头文件包含了所有外设的声明头文件,在本试验中我们使用到时钟外设和GPIO端口外设。所以#include "stm8s_clk.h"、#include "stm8s_tim3.h"和#include "stm8s_gpio.h"需要“打开”(就是把语句前面的双斜线注释符号删除即可,参考图17.1)。Stm8s_gpio.c库函数包含了所有管脚初始化功能和具体的执行操作;Stm8s_clk.c库函数主要包含了内部时钟和外部时钟设置,在主函数中规定了具体的执行方法,在这个函数中就有具体相关的执行步骤;Stm8s_tim3.c库函数主要包含了定时器3相关寄存器设置和tim3库函数具体执行过程。
 19.2.2  main.c文件中的程序
 主程序就实现初始化和调用驱动程序,这样主程序控制思路清晰,流程简单。要想了解全面详实的程序,请大家参考光盘(网盘)中程序及程序注释。
 /***********************************************************************
 *   说    明: STM8(TIM3)定时器
 *   开发平台: 剑齿虎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)//主程序循环,反复执行循环体里的语句
 {
 }
 }
 /***********************************************************************
 *   函 数 名: BSP_Configuration
 *   功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
 *   形    参:无
 *   返 回 值: 无
 ***********************************************************************/
 void BSP_Configuration(void)
 {
 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//时钟速度为内部16M,1分频,
 LED_Init();//调用LED初始化函数
 Tim3_Init();//调用TIM3初始化程序
 rim();//打开总中断
 }
 /*断言函数:它的作用是在编程的过程中为程序提供参数检查*/
 #ifdef USE_FULL_ASSERT
 void assert_failed(u8* file,u32 line)
 {
 while(1)
 {
 }
 }
 #endif
 19.2.3  tim.c文件中的程序
 #include "pbdata.h"
 /***************************************************************************
 *   函 数 名: Tim3_Init
 *   功能说明: 初始化通用定时器3
 *   形    参:无
 *   返 回 值: 无
 ***************************************************************************/
 void Tim3_Init(void)
 {
 TIM3_TimeBaseInit(TIM3_PRESCALER_16,1000);//初始化定时器3
 TIM3_ARRPreloadConfig(ENABLE);//使能自动重装
 TIM3_ITConfig(TIM3_IT_UPDATE , ENABLE);//数据更新中断
 TIM3_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清零
 }
 19.2.4  tim.h文件中的程序
 #ifndef _TIM_H//宏定义,定义文件名称
 #define _TIM_H
 #include "stm8s.h"
 /*--------------------------函数声明----------------------------------*/
 void Tim3_Init(void);//初始化定时器3
 void Tim3_Led(void);//TIM3实现流水灯函数
 #endif //定义文件名称结束
 19.2.5  stm8s_it.c文件中的程序
 中断和中断处理子程序建立关系必须在stm8s_it.c文件中对应位置中建立。关于定时器3的中断处理子程序要写在事先定义好的入口之内。“INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler,15)”,所以中断处理子程序入口地址必须放在TIM3中断处理中,请看下面程序语句。
 INTERRUPT_HANDLER(TIM3_UPD_OVF_BRK_IRQHandler, 15)
 {
 static u16 k=0; //定义变量k类型为u16   static定义了变量k的生存周期
 if(k<1000)//判断 k当前的数值是否小于1000
 {
 k++;//计数器 k 加1  也可以写成  k=k+1;
 }
 else//如果大于等于100 执行下面这个分支
 {
 k=0;//计数器 k 清零
 
 Tim3_Led();//调用流水灯函数
 }
 TIM3_ClearITPendingBit(TIM3_IT_UPDATE);//清除更新标志位
 }
 19.2.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秒
 }
 19.2.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 //定义文件名称结束
 19.2.8  补充说明
 这个实验中我们自己写了一个子程序,实现流水灯功能,在TIM3中断中调用了。 大家熟悉了这个流水灯的控制流程,可以更改一下其中的参数,就可以实现流水灯从左至右闪动或者从右至左闪动,也可以更改流水灯流动的时间等等。
 
 
 | 
 
×本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?注册 
  |