打印
[STM32H7]

STM32H743ZI实现高效外部中断和定时器功能

[复制链接]
43|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Pulitzer|  楼主 | 2024-11-23 07:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32系列微控制器一直以其高性能和灵活的外设支持深受开发者喜爱。本文将以STM32H743ZI为例,介绍如何利用外部中断和定时器实现一个实用的输入检测和输出控制的功能。该功能模拟一个输入信号触发外部中断,并通过定时器控制输出信号的时序。
项目需求
  • 使用外部引脚PA0接收外部输入信号,触发中断。
  • 使用定时器TIM2生成一个固定占空比的PWM信号,通过PB3输出。
  • 在中断服务程序中启动定时器控制输出信号的持续时间。
  • 使用STM32CubeMX生成初始化代码,并在此基础上补充实现应用逻辑。
硬件环境
  • MCU型号:STM32H743ZI
  • 开发工具:STM32CubeIDE
  • 外设配置:PA0配置为外部中断输入,PB3配置为定时器输出通道。

代码实现以下是完整代码:
#include "main.h"

TIM_HandleTypeDef htim2;

/* 外部中断回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == GPIO_PIN_0) {  // 检测是否为PA0引脚的中断
        HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 开启定时器的PWM输出
        HAL_Delay(5000); // 模拟延时5秒
        HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1); // 停止PWM输出
    }
}

/* 定时器初始化函数 */
void MX_TIM2_Init(void) {
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 79;  // 1 MHz计数频率
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 999;  // 1 kHz PWM频率
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
        Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
        Error_Handler();
    }
    if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 499;  // 50%占空比
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {
        Error_Handler();
    }
}

/* 主函数 */
int main(void) {
    HAL_Init();
    SystemClock_Config();

    MX_GPIO_Init();
    MX_TIM2_Init();

    while (1) {
        // 主循环空闲等待中断
    }
}

/* GPIO初始化 */
void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();

    /* 配置PA0为外部中断输入 */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* 配置PB3为定时器输出 */
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* 中断优先级配置并使能 */
    HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
代码说明
  • 外部中断配置:PA0引脚设置为上升沿触发模式,并启用中断处理函数。
  • 定时器配置:TIM2生成1 kHz频率的PWM信号,设置50%占空比。
  • 中断逻辑:当外部信号触发中断时,启动定时器PWM输出,模拟控制信号持续5秒后停止。

项目特点
  • STM32H743ZI内置强大的外设支持,能够灵活配置中断和定时器。
  • CubeMX生成代码极大提高开发效率,手动优化后的代码更贴近实际应用。
  • 使用HAL库实现的代码具有良好的可读性和移植性。

使用特权

评论回复
沙发
公羊子丹| | 2024-11-23 07:45 | 只看该作者
这个中断和PWM结合的例子很实用啊,我正好有个类似的需求!

使用特权

评论回复
板凳
周半梅| | 2024-11-23 07:45 | 只看该作者
STM32H743ZI性能是真的强,代码看起来也挺简洁的。

使用特权

评论回复
地板
帛灿灿| | 2024-11-23 07:45 | 只看该作者
能不能用LL库写一版,这样运行效率会更高?

使用特权

评论回复
5
童雨竹| | 2024-11-23 07:46 | 只看该作者
代码里的中断延时会不会影响实时性?感觉可以优化一下。

使用特权

评论回复
6
万图| | 2024-11-23 07:46 | 只看该作者
TIM2的频率设置这一块解释得很清楚,我学到了!

使用特权

评论回复
7
Wordsworth| | 2024-11-23 07:46 | 只看该作者
下次能不能讲一下其他外设,比如ADC的使用?

使用特权

评论回复
8
Bblythe| | 2024-11-23 07:46 | 只看该作者
如果有更多GPIO输入,逻辑会复杂很多吧,这种情况下怎么办?

使用特权

评论回复
9
Uriah| | 2024-11-23 07:47 | 只看该作者
STM32H743ZI价格有点高,用F4系列也能实现类似功能吧?

使用特权

评论回复
10
Clyde011| | 2024-11-23 07:47 | 只看该作者
感觉这个项目用RTOS会更好管理时序和逻辑。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

3600

帖子

0

粉丝