OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 263|回复: 0

《M144Z-M3最小系统板使用指南——STM32F103版》第十六章 基本定时器中断实验

[复制链接]

1061

主题

1072

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4407
金钱
4407
注册时间
2019-5-8
在线时间
1196 小时
发表于 2024-4-2 15:41:01 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-4-1 17:46 编辑

第十六章 基本定时器中断实验
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板

2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... _mini_sysboard.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32技术交流QQ群:725095144

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

STM32F103内部有多种多个定时器(TIM),本章介绍STM32F103基本定时器的使用,基本定时器是一类只能实现定时功能、没有外部接口的定时器。通过本章的学习,读者将学习到基本定时器的使用。
本章分为如下几个小节:
16.1 硬件设计
16.2 程序设计
16.3 下载验证

16.1 硬件设计
16.1.1 例程功能
1. LED1以1Hz的频率闪烁
2. LED0闪烁,提示程序正在运行

16.1.2 硬件资源
1. LED
       LED0 - PB5
       LED1 - PE5
2. TIM6

16.1.3 原理图
本章实验使用的TIM6为STM32F103的片上资源,因此并没有相应的连接原理图。

16.2 程序设计
16.2.1 HAL库的TIM驱动
本章实验将配置TIM6每间隔500毫秒产生一次中断,并在其中断服务函数中改变一次LED1的状态,具体的步骤如下:
①:初始化TIM6
②:开启TIM6中断模式计数
在HAL库中对应的驱动函数如下:
①:初始化TIM
该函数用于初始化TIM的各项参数,其函数原型如下所示:
  1. HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
复制代码
该函数的形参描述,如下表所示:
QQ截图20240401174341.png
表16.2.1.1 函数HAL_TIM_Base_Init()形参描述
该函数的返回值描述,如下表所示:
QQ截图20240401174334.png
表16.2.1.2 函数HAL_TIM_Base_Init()返回值描述
该函数需要传入TIM的句柄指针,该句柄中就包含了TIM的初始化配置参数结构体,该结构体的定义如下所示:
  1. typedef struct
  2. {
  3.     uint32_t Prescaler;         /* 分频系数 */
  4.     uint32_t CounterMode;       /* 计数模式 */
  5.     uint32_t Period;            /* 重装载值 */
  6.     uint32_t ClockDivision;     /* 计数分频 */
  7.     uint32_t RepetitionCounter; /* 重复计数器 */
  8.     uint32_t AutoReloadPreload; /* 自动重装载 */
  9. }TIM_Base_InitTypeDef;
复制代码
该函数的使用示例,如下所示:
  1. #include "stm32f1xx_hal.h"
  2. void example_fun(void)
  3. {
  4.    TIM_HandleTypeDef tim_handle = {0};
  5.    
  6.     /* 初始化TIM6 */
  7.    tim_handle.Instance = TIM6;
  8.    tim_handle.Init.Prescaler = 72 - 1;
  9.    tim_handle.Init.Period = 1000 - 1;
  10.    HAL_TIM_Base_Init(&tim_handle);
  11. }
复制代码
②:开启TIM中断模式计数
该函数用于开启TIM中断模式计数,其函数原型如下所示:
  1. HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
复制代码
该函数的形参描述,如下表所示:
QQ截图20240401174327.png
表16.2.1.3 函数HAL_TIM_Base_Start_IT()形参描述
该函数的返回值描述,如下表所示:
QQ截图20240401174317.png
表16.2.1.4 函数HAL_TIM_Base_Start_IT()返回值描述
该函数的使用示例,如下所示:
  1. #include "stm32f1xx_hal.h"
  2. void example_fun(void)
  3. {
  4.     /* 开启TIM6中断模式计数 */
  5.     HAL_TIM_Base_Start_IT(&tim_handle);
  6. }
复制代码
16.2.2 基本定时器驱动
本章实验的基本定时器驱动主要负责向应用层提供基本定时器的初始化函数,并实现基本定时器的中断回调函数。本章实验中,基本定时器的驱动代码包括btmr.c和btmr.h两个文件。
基本定时器驱动中,对TIM的相关宏定义,如下所示:
  1. #define BTIM_TIMX_INT              TIM6
  2. #define BTIM_TIMX_INT_IRQn         TIM6_DAC_IRQn
  3. #define BTIM_TIMX_INT_IRQHandler   TIM6_DAC_IRQHandler
  4. #define BTIM_TIMX_INT_CLK_ENABLE()                                     \
  5.                                      do {                                \
  6.                                          __HAL_RCC_TIM6_CLK_ENABLE();   \
  7.                                      } while (0)
复制代码
基本定时器驱动中TIM6的初始化函数,如下所示:
  1. /**
  2. *@brief   初始化基本定时器
  3. *@param   arr: 自动重装载值
  4. *@param   psc: 预分频系数
  5. *@retval  无
  6. */
  7. voidbtim_timx_int_init(uint16_t arr, uint16_t psc)
  8. {
  9.    g_timx_handle.Instance =BTIM_TIMX_INT;
  10.    g_timx_handle.Init.Prescaler = psc;
  11.    g_timx_handle.Init.Period = arr;
  12.    HAL_TIM_Base_Init(&g_timx_handle);
  13.    HAL_TIM_Base_Start_IT(&g_timx_handle);
  14. }
复制代码
从TIM6的初始化代码中可以看到,该函数调用了函数HAL_TIM_Base_Init()和函数HAL_TIM_Base_Start_IT()分别用来初始化TIM6和开启了TIM6的中断模式计数。
基本定时器驱动中TIM6的计数溢出回调函数,如下所示:
  1. /**
  2. *@brief   HAL库基本定时器超时中断回调函数
  3. *@param   无
  4. *@retval  无
  5. */
  6. voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  7. {
  8.     if (htim->Instance == BTIM_TIMX_INT)
  9.     {
  10.          LED1_TOGGLE();
  11.     }
  12. }
复制代码
从上面的代码中可以看出,在TIM6每次计数溢出后都会翻转一次LED1的状态。

16.2.3 实验应用代码
本章实验的应用代码,如下所示:
  1. int main(void)
  2. {
  3.    HAL_Init();                             /* 初始化HAL库 */
  4.    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 配置时钟,72MHz */
  5.    delay_init(72);                         /* 初始化延时 */
  6.    usart_init(115200);                     /* 初始化串口 */
  7.    led_init();                             /* 初始化LED */
  8.    btim_timx_int_init(5000 - 1, 7200 - 1); /* 初始化基本定时器,溢出频率为2Hz */
  9.    
  10.     while (1)
  11.     {
  12.          LED0_TOGGLE();
  13.          delay_ms(200);
  14.     }
  15. }
复制代码
从上面的代码中可以看到,TIM6的自动重装载配置为(5000-1),TIM6的预分频器数值配置为(7200-1),并且TIM6的时钟频率为72MHz,因此TIM6的计数频率为10KHz,且TIM6计数5000次溢出一次,因此溢出频率为2Hz,又因为TIM6每溢出一次都会改变一次LED1的状态,因此LED1的闪烁频率为1Hz。

16.3 下载验证
在完成编译和烧录操作后,可以看到板子上的LED0和LED1都在闪烁,但闪烁频率不同,LED0每间隔200毫秒改变一次状态,LED1在TIM6的中断回调函数中被改变状态,其闪烁的频率约为1Hz。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 16:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表