STM32F407 的通用定时器与串口配置深度解析

在 STM32F407 芯片的开发过程中,通用定时器和串口的配置与使用是极为关键的技能点。本文将结合提供的代码示例,深入剖析这两个模块的配置流程、工作原理以及实际应用,助力开发者更好地掌握相关技术。

一、通用定时器

(一)定时器时钟频率规则

在使用 STM32F407 芯片的定时器时,其时钟频率的设定遵循特定规则。对于 STM32F405xx/07xx 和 STM32F415xx/17xx 系列,定时器时钟频率由硬件自动设置,具体分为两种情况:

  1. 当 APB 预分频器为 1 时,定时器时钟频率等于 APB 域的频率。

  2. 若 APB 预分频器不为 1,定时器时钟频率则是 APB 域频率的两倍。

(二)通用定时器配置步骤

  1. 使能定时器时钟 :使用RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);语句开启定时器 3 的时钟。这是定时器工作的基础,只有使能时钟,后续操作才有意义。

  2. 配置定时器参数

    • TIM_TimeBaseStructure.TIM_Period 用于设置自动重装载寄存器的值,也就是计数值。例如,期望定时时间为 1ms,若定时器分频后的工作频率为 10000Hz(对应 100us 计数周期),那么为实现 1ms 定时,需要计数 10 次,TIM_Period的值应设置为 (10000/1000) - 1 = 9 (从 0 开始计数,所以减 1)。

    • **TIM_TimeBaseStructure.TIM_Prescaler:**用于设置预分频器的值。如设置为 8400 - 1,意味着将定时器的输入时钟(假设为 84MHz)分频为 84MHz/(8400)=10kHz ,从而调整定时器的计数频率。

    • TIM_TimeBaseStructure.TIM_ClockDivision 用于设置时钟分频。TIM_CKD_DIV1表示不分频,它影响定时器内部某些信号的分频关系,在本示例中选择不分频,方便后续代码的移植和理解。

    • TIM_TimeBaseStructure.TIM_CounterMode 设置计数模式,TIM_CounterMode_Up表示向上计数模式,即从 0 开始计数,计数值达到TIM_Period设定值时触发溢出事件。

  3. 配置 NVIC 参数

    • NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);:用于设置中断优先级分组,这里选择分组 2,确定抢占优先级和子优先级的分配方式。

    • NVIC_InitStructure.NVIC_IRQChannel 指定中断通道,如TIM3_IRQn表示定时器 3 的中断通道。

    • **NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority:**设置抢占优先级,示例中设为 0 。

    • **NVIC_InitStructure.NVIC_IRQChannelSubPriority:**设置子优先级,示例中设为 0 。

    • **NVIC_InitStructure.NVIC_IRQChannelCmd:**使能中断通道。

  4. 定时器中断配置TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); 用于使能定时器 3 的更新中断,当定时器计数值达到TIM_Period设定值并溢出时,会触发更新中断。

  5. 使能定时器工作 :**TIM_Cmd(TIM3, ENABLE);**启动定时器 3,使其按照配置参数开始计数工作。

  6. 定义定时器中断函数 :在**TIM3_IRQHandler** 函数中,通过**TIM_GetITStatus(TIM3,TIM_IT_Update)==SET** 检测是否发生更新中断事件。若发生,进行相应处理,如示例中每 1000 次中断(即 1 秒)通过串口发送 "hello\r\n" 字符串,并使用**TIM_ClearITPendingBit(TIM3, TIM_IT_Update);**清空中断标志位,告知 CPU 中断已处理完毕。

二、串口配置

(一)串口配置目的及整体流程

配置串口的主要目的是为了方便调试定时器。在本代码示例中,对串口 1 进行了详细配置,主要步骤如下:

  1. 使能端口和串口时钟

    • **RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);:**使能 GPIOA 端口时钟,因为串口 1 的引脚复用在 GPIOA 上。

    • **RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);:**使能串口 1 的时钟。

  2. 引脚复用功能映射GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); 和**GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);**将 GPIOA9 和 GPIOA10 分别复用为串口 1 的 TX 和 RX 引脚。

  3. 端口配置

    • GPIO_InitStructure.GPIO_Pin 设置为GPIO_Pin_9 | GPIO_Pin_10,即配置 GPIOA9 和 GPIOA10 引脚。

    • GPIO_InitStructure.GPIO_Mode 设置为GPIO_Mode_AF,表示复用功能模式。

    • GPIO_InitStructure.GPIO_Speed 设置为GPIO_Speed_50MHz,满足串口通信速率要求。

    • GPIO_InitStructure.GPIO_OType 设置为GPIO_OType_PP,推挽复用输出模式。

    • GPIO_InitStructure.GPIO_PuPd 设置为GPIO_PuPd_UP,上拉模式,确保引脚在未输入时处于稳定的高电平状态。

    • **GPIO_Init(GPIOA,&GPIO_InitStructure);:**初始化 GPIOA9 和 GPIOA10 引脚。

  4. 串口参数配置

    • USART_InitStructure.USART_BaudRate:设置波特率为 115200。

    • USART_InitStructure.USART_WordLength:设置字长为 8 位。

    • USART_InitStructure.USART_StopBits:设置一个停止位。

    • USART_InitStructure.USART_Parity:设置无奇偶校验位。

    • USART_InitStructure.USART_HardwareFlowControl:设置无硬件数据流控制。

    • USART_InitStructure.USART_Mode :设置为USART_Mode_Tx|USART_Mode_Rx,即收发模式。

    • USART_Init(USART1, &USART_InitStructure);:初始化串口 1。

  5. 中断配置

    • NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);:设置中断优先级分组为 2 。

    • NVIC_InitStructure.NVIC_IRQChannel:指定为USART1_IRQn,即串口 1 的中断通道。

    • NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority:设置抢占优先级为 1 。

    • NVIC_InitStructure.NVIC_IRQChannelSubPriority:设置子优先级为 1 。

    • NVIC_InitStructure.NVIC_IRQChannelCmd:使能中断通道。

    • USART_Cmd(USART1, ENABLE);:使能串口 1。

(二)重定向 printf 函数到串口

通过重定向fputc函数,实现将printf函数的输出重定向到串口。这样在代码中使用printf函数时,输出内容会通过串口发送出去,方便调试信息的查看。

cpp 复制代码
int fputc(int ch, FILE *f) {
    /* 发送一个字节数据到串口 */
    USART_SendData(USART1, (uint8_t)ch);
    /* 等待发送完毕 */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); 
    return (ch);
}

三、注意事项

  1. 时钟配置修改 :需要修改**system_stm32f4xx.c** 中的时钟配置。在**stm32f407.h** 中,将**HSE_VALUE** 修改为实际使用的晶振频率,以确保系统时钟和定时器时钟等的准确性。例如,如果实际晶振频率为 8MHz,就需要将**HSE_VALUE**的值设置为 8000000。

  2. 代码优化与扩展:在实际项目中,可根据需求进一步优化和扩展代码。比如,在定时器中断函数中,可以添加更多复杂的业务逻辑,而不仅仅是发送固定字符串;串口配置部分,可根据不同的通信需求调整波特率、数据位、停止位和校验位等参数。

通过上述对 STM32F407 通用定时器和串口配置的详细解析,开发者可以更加深入地理解这两个模块的工作机制和应用方法,为开发更复杂、更高效的嵌入式系统奠定坚实基础。希望本文能对大家在 STM32F407 开发过程中有所帮助

相关推荐
少年、潜行1 小时前
【开源】STM32HAL库驱动ST7789_240×240(硬件SPI+软件SPI)
stm32·嵌入式硬件·开源·hal库·st7789·软件spi
承接电子控制相关项目1 小时前
单片机与FPGA的核心差异、优缺点、编程差异、典型应用场景、选型等对比分析
单片机·嵌入式硬件·fpga开发
YHPsophie1 小时前
面向高可靠场景的RISC-V低功耗MCU硬件安全设计
单片机·嵌入式硬件·risc-v
狄加山6752 小时前
STM32 外部中断
stm32·单片机·嵌入式硬件
承接电子控制相关项目2 小时前
当代嵌入式硬件工程师应具备哪些能力要素
单片机·嵌入式硬件
XINVRY-FPGA3 小时前
XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
c++·嵌入式硬件·阿里云·fpga开发·云计算·硬件工程·fpga
嵌入式-老费14 小时前
Linux上位机开发实践(以MCU小系统入门嵌入式电路)
单片机·嵌入式硬件
WPG大大通15 小时前
基于意法半导体STM32G473和STDRIVE 101的电池供电BLDC/PMSM电动工具
stm32·单片机·嵌入式硬件·方案·大大通
the sun3415 小时前
STM32---GPIO
stm32·单片机·嵌入式硬件