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 开发过程中有所帮助

相关推荐
智商偏低5 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen6 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森8 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白8 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D8 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术11 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt12 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘12 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang12 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n15 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件