当前位置: 首页 > news >正文

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函数时,输出内容会通过串口发送出去,方便调试信息的查看。

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

相关文章:

  • Linux系统学习----概述与目录结构
  • 阿里巴巴安全工程师面试题:BAS
  • k8s 证书相关问题
  • 如何避免多任务并行导致的效率下降
  • c++下的onnx推理
  • axios 在请求拦截器中设置Content-Type无效问题
  • Ubuntu20.04下GraspNet复现流程中的问题
  • MACD红绿灯副图指标使用技巧,绿灯做多,MACD趋势线,周期共振等实战技术解密
  • JavaScript性能优化实战(3):内存管理与泄漏防范
  • Vue3-原始值的响应式方案ref
  • 配色之道:解码产品设计中的UI设计配色艺术
  • 【AI提示词】公司法律顾问
  • 从云端到边缘:云原生后端架构在边缘计算中的演进与实践
  • Linux:进程的概念
  • VSFTPD+虚拟用户+SSL/TLS部署安装全过程(踩坑全通)
  • 【Linux网络】构建类似XShell功能的TCP服务器
  • ​​OSPF核心机制精要:选路、防环与设计原理​
  • C++20 module下的LVGL模拟器
  • [实战]zynq7000设备树自动导出GPIO
  • 聊聊自动化用例的维护
  • 商务部召开外资企业圆桌会
  • 中国专家组赴缅开展地震灾害评估工作
  • 韩国检方以受贿嫌疑起诉前总统文在寅
  • 职工疗休养如何告别千篇一律?安徽含山给出新解法
  • “低头捡星光”,艺术创作直面三江源生态保护
  • 旁白丨还在寻亲路上的家长们,期待“上岸”