STM32的通用定时器中断编程

如果遇到需要单片机产生严格时序的场景(比如DAC输出特定模拟信号,GPIO口控制模拟开关),延时函数可能就无法胜任了。最近在工作时公司上级教会了我使用“门票”思维(中断标志位)编写单片机裸机程序,今天写一篇简单的验证实验报告来记录一下。这里我设计了一个简单的实验,单片机开发板上有LED0和LED1,我们让LED0亮500ms之后熄灭,随后LED1亮100ms之后熄灭,以此循环。

1.首先设定挂载定时器的时钟总线频率,我这里使用了默认的16M。

1e1616742a9d4e1da52adc6104ab1aac.png

2.使能定时器并且设置定时器的预分频系数计数周期(自动重装载计数器的值)

5b6e21c409894bcea49d77a52003c19c.png

3.使能中断函数并且调整中断优先级

63b876a9356242d780e7e272f630544b.png

4.生成代码验证实验

 (1)在定时器初始化函数中开启定时器7中断

/* TIM7 init function */
void MX_TIM7_Init(void)
{

  /* USER CODE BEGIN TIM7_Init 0 */

  /* USER CODE END TIM7_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM7_Init 1 */

  /* USER CODE END TIM7_Init 1 */
  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 3999;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = 199;
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM7_Init 2 */
   HAL_TIM_Base_Start_IT(&htim7);//开启定时器7中断
  /* USER CODE END TIM7_Init 2 */

}

(2)在stm32f4xx_it.c中找到这个中断处理函数

d1eadf0db63c4f6991a6c9fecf140b11.png

(3)跳转定义查看函数底层逻辑,找到中断回调函数

1067e76ec54e49e6892aa54a25f36b5b.png

(4)跳转定义,发现属于虚函数可以进行重写

__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
   */
}

(5)在stm32f4xx_it.c的代码沙盒段内进行虚函数重写,并且定义所需全局变量

/* USER CODE BEGIN EV */
uint8_t g_timTick=0;               //定时器中断节拍
uint8_t g_timSwitch=0;             //定时器中断“门票”
/* USER CODE END EV */
/* USER CODE BEGIN 1 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == TIM7){                              //涉及到多个定时器中断的时候检查就很有必要了
		const uint8_t increment=1;                         //计数步长为常量1
    g_timTick = (g_timTick + increment) % 5;               //5:1的GPIO口时序
	}
	g_timSwitch++;                                         //回调函数发放门票
}
/* USER CODE END 1 */

(6)在stm32f4xx_it.中声明全局变量

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "main.h"            //防止uint8_t无法被编译器识别
/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern uint8_t g_timTick;          
extern uint8_t g_timSwitch;
/* USER CODE END EC */

(7)主函数编写功能函数

			if(g_timSwitch){
		  g_timSwitch--;                             //进入主循环则收回门票,防止CPU重复判断
			if(g_timTick==0){
			  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);	
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);	
			}else{
			  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);	
		    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
			}	
		}

(8)下载验证

9c315ac46ed8438eaa04645774a4329c.jpeg

观察到单片机开发板的LED灯进行频闪,试验成功。不过从波形上来看会有较大的误差,因为只有500ms的时序是用中断严格实现的。想要精准控制原理就是上述的那些,感兴趣的同学可以自己试一试。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-18 08:46:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-18 08:46:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-18 08:46:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-18 08:46:02       20 阅读

热门阅读

  1. Mac电脑安装配置NVM

    2024-06-18 08:46:02       6 阅读
  2. 架构设计 - 本地热点缓存

    2024-06-18 08:46:02       5 阅读
  3. 热门开源项目推荐

    2024-06-18 08:46:02       8 阅读
  4. 解析网络空间的安全威胁与应对

    2024-06-18 08:46:02       7 阅读
  5. 11、Spring之Bean生命周期~依赖注入(2)

    2024-06-18 08:46:02       8 阅读
  6. Go微服务: 悲观锁

    2024-06-18 08:46:02       5 阅读
  7. websocket nignx 配置

    2024-06-18 08:46:02       7 阅读
  8. 力扣-2379. 得到 K 个黑块的最少涂色次数

    2024-06-18 08:46:02       8 阅读
  9. 【快速定位生产问题】

    2024-06-18 08:46:02       7 阅读
  10. linux中如何进行yum源的挂载

    2024-06-18 08:46:02       8 阅读