09-CubeMx+Keil+Proteus仿真STM32 - 定时器(二)

本文例子参考《STM32单片机开发实例——基于Proteus虚拟仿真与HAL/LL库》
源代码:https://github.com/LanLinnet/STM32F103R6

项目要求

通过定时器中断的方式,实现流水灯的效果。

硬件设计

  1. 第一节的基础上,在Proteus中添加电路如下图所示。

  2. 上一节定时器阻塞延时的基础上,我们在本项目中同样使用TIM3进行中断。时钟频率采用默认的8MHz,我们不妨设置PSC为3999,ARR为999,那么此时可以计算出TIM3的计数脉冲周期为\(T_{CNT}\)为0.5ms,一次中断的溢出时间\(T_{OUT}\)为0.5s。

  3. 打开CubeMX,建立工程。我们首先将PC0-PC7管脚设置为GPIO_Output。
    随后对定时器进行设置:点击“Categories”中的“Timer”列表,选中“TIM3”。在“TIM3 Mode and Configuration”窗口中设置“Clock Source”为Internal Clock,设置“PSC”为3999,“Counter Period”为999

    随后点击“NVIC Settings”,将定时器3全局中断“TIM3 global interrupt”使能。

    接下来点击“Clock Configuration”进入时钟配置界面,这里我们采用默认设定的8MHz。

    最后因为我们的GPIO编程采用的是LL库函数,所以这里将GPIO设置为LL库。

  4. 点击“Generator Code”生成Keil工程。

软件编写

  1. 本次我们需要实现定时器中断使得LED灯闪烁,需要用到定时器中断相关函数,其API文档如下:
    HAL_TIM_Base_Start_IT 定时器打开中断

    HAL_TIM_PeriodElapsedCallback 定时器中断回调函数

  2. 点击“Open Project”在Keil中打开工程,双击“main.c”文件。

  3. 与定时器阻塞方式不同,我们只需要在main函数中初始化定时器,剩下所有的功能都在中断回调函数中运行,这样的操作模式使得CPU大部分时间工作在main函数的while循环中,仅在中断溢出的时候进入中断回调函数中执行指令,大大提高了CPU的利用效率。
    我们首先在main.c文件的main函数中初始化定时器。

    /* USER CODE BEGIN 2 */
    LL_GPIO_WriteOutputPort(GPIOC, 0xfe);
    HAL_TIM_Base_Start_IT(&htim3);  //初始化定时器
    /* USER CODE END 2 */
    

    最后,在/* USER CODE BEGIN 4 *//* USER CODE END 4 */之间插入定时器中断回调函数,代码如下

    /* USER CODE BEGIN 4 */
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
      static uint8_t counter = 0;  
      if(htim == &htim3)  //定时器3中断
      {
        counter++;
        if(counter>=8) counter=0;
        LL_GPIO_WriteOutputPort(GPIOC, (0xfe<<counter)|(0xfe>>(8-counter)));  //流水灯状态改变一次
      }
    }
    /* USER CODE END 4 */
    

联合调试

  1. 点击运行,生成HEX文件。
  2. 在Proteus中加载相应HEX文件,点击运行,LED灯呈现流水灯状态。
posted @ 2022-05-10 10:20  Sheepeach  阅读(1965)  评论(0编辑  收藏  举报