【星云 Orbit•STM32F4】14. 定时器进阶:通用定时器

【星云 Orbit•STM32F4】14. 定时器进阶:通用定时器

七律 · 定时器

通用模式精妙三,中断配置是精华。
初学成兴会自融,定时努力器必通。

博客重心在工程框架和代码思路,配置步骤,需要读者常思考,勤动手。“手把手”是高中阶段的老师喂知识模式,都大学了,换个自己想要的方式,不读高四高五了。


摘要

本文将配置STM32F407的通用定时器,并结合LED、蜂鸣器和按键进行实际应用。学会如何使用HAL库配置定时器,并实现按键控制定时器启动/停止,定时器触发时控制LED闪烁和蜂鸣器响起。

关键字

STM32F407、通用定时器、HAL库、LED、蜂鸣器、按键、定时器配置

1. 引言

定时器是嵌入式系统中的重要组件,常用于定时控制、PWM输出等场景。本教程将通过实际案例,展示如何配置STM32F407的通用定时器,并结合LED、蜂鸣器和按键实现交互功能。


2. 基础知识

定时器的基本概念

定时器是一种计数器,用于生成定时信号或测量时间间隔。STM32F407的通用定时器支持多种模式,包括:

  • 上升计数模式
  • 下降计数模式
  • 中心对齐模式

外设功能

  • LED:用于指示定时器状态
  • 蜂鸣器:用于音频反馈
  • 按键:用于手动控制定时器

3. 硬件设计

硬件电路连接

  1. LED:连接到GPIOA的第5个引脚(PA5)
  2. 蜂鸣器:连接到GPIOA的第6个引脚(PA6)
  3. 按键:连接到GPIOC的第13个引脚(PC13)

4. 软件配置

文件结构

STM32F40x_Project/
├── Drivers/
│   ├── BSP/
│   │   ├── led/
│   │   │   ├── bsp_led.c
│   │   │   └── bsp_led.h
│   │   ├── buzzer/
│   │   │   ├── bsp_buzzer.c
│   │   │   └── bsp_buzzer.h
│   │   └── button/
│   │       ├── bsp_button.c
│   │       └── bsp_button.h
│   ├── Module/
│   │   └── timer/
│   │       ├── drv_timer.c
│   │       └── drv_timer.h
│   ├── CMSIS/
│   └── STM32F4xx_HAL_Driver/
└── Users/
    └── main.c

HAL库函数详解

  • HAL_TIM_Init(): 初始化定时器
  • HAL_TIM_Start(): 启动定时器
  • HAL_TIM_Stop(): 停止定时器
  • HAL_GPIO_WritePin(): 控制GPIO引脚输出
  • HAL_GPIO_ReadPin(): 读取GPIO引脚输入

5. 模块化代码实现

drv_timer.h

#ifndef __DRV_TIMER_H
#define __DRV_TIMER_H

#include "stm32f4xx_hal.h"

void Timer_Init(void);
void Timer_Start(void);
void Timer_Stop(void);
void Timer_IRQ_Handler(void);

#endif /* __DRV_TIMER_H */

drv_timer.c

#include "drv_timer.h"

TIM_HandleTypeDef htim3;

void Timer_Init(void) {
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 168 - 1;  // 配置分频器,假设系统时钟为168MHz
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 1000 - 1;    // 配置周期为1000个时钟周期
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    
    HAL_TIM_Init(&htim3);
    HAL_TIM_IRQHandler(&htim3);
}

void Timer_Start(void) {
    HAL_TIM_Start(&htim3);
}

void Timer_Stop(void) {
    HAL_TIM_Stop(&htim3);
}

void Timer_IRQ_Handler(void) {
    HAL_TIM_IRQHandler(&htim3);
}

bsp_led.h

#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "stm32f4xx_hal.h"

void LED_Init(void);
void LED_On(void);
void LED_Off(void);
void LED_Toggle(void);

#endif /* __BSP_LED_H */

bsp_led.c

#include "bsp_led.h"

GPIO_HandleTypeDef hled;

void LED_Init(void) {
    hled.Instance = GPIOA;
    hled.Pin = GPIO_PIN_5;
    hled.Mode = GPIO_MODE_OUTPUT;
    hled.Pull = GPIO_NOPULL;
    hled.Speed = GPIO_SPEED_FREQ_HIGH;
    
    HAL_GPIO_Init(&hled);
}

void LED_On(void) {
    HAL_GPIO_WritePin(&hled, GPIO_PIN_5, GPIO_PIN_SET);
}

void LED_Off(void) {
    HAL_GPIO_WritePin(&hled, GPIO_PIN_5, GPIO_PIN_RESET);
}

void LED_Toggle(void) {
    HAL_GPIO_TogglePin(&hled, GPIO_PIN_5);
}

bsp_buzzer.h

#ifndef __BSP_BUZZER_H
#define __BSP_BUZZER_H

#include "stm32f4xx_hal.h"

void Buzzer_Init(void);
void Buzzer_On(void);
void Buzzer_Off(void);
void Buzzer_Toggle(void);

#endif /* __BUZZER_H */

bsp_buzzer.c

#include "bsp_buzzer.h"

GPIO_HandleTypeDef hbuzzer;

void Buzzer_Init(void) {
    hbuzzer.Instance = GPIOA;
    hbuzzer.Pin = GPIO_PIN_6;
    hbuzzer.Mode = GPIO_MODE_OUTPUT;
    hbuzzer.Pull = GPIO_NOPULL;
    hbuzzer.Speed = GPIO_SPEED_FREQ_HIGH;
    
    HAL_GPIO_Init(&hbuzzer);
}

void Buzzer_On(void) {
    HAL_GPIO_WritePin(&hbuzzer, GPIO_PIN_6, GPIO_PIN_SET);
}

void Buzzer_Off(void) {
    HAL_GPIO_WritePin(&hbuzzer, GPIO_PIN_6, GPIO_PIN_RESET);
}

void Buzzer_Toggle(void) {
    HAL_GPIO_TogglePin(&hbuzzer, GPIO_PIN_6);
}

bsp_button.h

#ifndef __BSP_BUTTON_H
#define __BSP_BUTTON_H

#include "stm32f4xx_hal.h"

void Button_Init(void);
uint8_t Button_GetState(void);

#endif /* __BUTTON_H */

bsp_button.c

#include "bsp_button.h"

GPIO_HandleTypeDef hbutton;

void Button_Init(void) {
    hbutton.Instance = GPIOC;
    hbutton.Pin = GPIO_PIN_13;
    hbutton.Mode = GPIO_MODE_INPUT;
    hbutton.Pull = GPIO_NOPULL;
    hbutton.Speed = GPIO_SPEED_FREQ_HIGH;
    
    HAL_GPIO_Init(&hbutton);
}

uint8_t Button_GetState(void) {
    return HAL_GPIO_ReadPin(&hbutton, GPIO_PIN_13);
}

main.c

#include "./drv/drv_timer.h"
#include "./led/bsp_led.h"
#include "./buzzer/bsp_buzzer.h"
#include "./button/bsp_button.h"

int main(void) {
    // 初始化外设
    LED_Init();
    Buzzer_Init();
    Button_Init();
    Timer_Init();
    
    // 默认停止定时器
    Timer_Stop();
    LED_Off();
    Buzzer_Off();
    
    while (1) {
        // 按键按下时启动定时器
        if (Button_GetState() == 1) {
            Timer_Start();
            LED_On();
        }
        
        // 按键释放时停止定时器
        if (Button_GetState() == 0) {
            Timer_Stop();
            LED_Off();
        }
        
        // 定时器中断触发时,蜂鸣器响起
        if (TIM3->SR & TIM_SR_UIF) {
            Buzzer_Toggle();
            TIM3->SR &= ~TIM_SR_UIF;
        }
    }
}

使用示例

  1. 硬件连接

    • LED连接到PA5
    • 蜂鸣器连接到PA6
    • 按键连接到PC13
  2. 软件配置

    • 在Keil中创建新项目
    • 添加所有源文件和头文件
    • 配置系统时钟为168MHz
    • 编译并下载程序
  3. 功能测试

    • 按下按键,观察LED点亮
    • 定时器触发时,蜂鸣器响起
    • 松开按键,定时器停止,LED熄灭

7. 流程图

按键按下
定时器触发
按键释放
启动定时器
初始化外设
配置定时器
按键检测
蜂鸣器响起
停止定时器
End

总结

通过本教程,您学会了如何配置STM32F407的通用定时器,并结合LED、蜂鸣器和按键实现交互功能。这种模块化的代码结构使得代码易于维护和扩展,您可以根据需要添加更多功能模块。

希望这个对您有所帮助!如果有任何问题,请随时告诉我。

你可能感兴趣的:(【星云,Orbit•STM32F4】,stm32,嵌入式硬件,单片机)