STM32F103代码:USART与DMA集成及中断处理
本文还有配套的精品资源,点击获取简介:本文深入探讨了STM32F103微控制器实现USART、DMA和中断集成的过程。介绍了如何利用USART进行串行通信,配置DMA以减轻CPU负担,以及使用中断响应USART事件。提供了具体的代码实现步骤,包括初始化USART、配置DMA通道、链接USART与DMA,以及设置中断服务例程。这对于嵌入式系统设计者掌握STM32F103外设...
简介:本文深入探讨了STM32F103微控制器实现USART、DMA和中断集成的过程。介绍了如何利用USART进行串行通信,配置DMA以减轻CPU负担,以及使用中断响应USART事件。提供了具体的代码实现步骤,包括初始化USART、配置DMA通道、链接USART与DMA,以及设置中断服务例程。这对于嵌入式系统设计者掌握STM32F103外设使用具有重要价值。
1. STM32F103微控制器简介
1.1 STM32F103的特性与架构
1.1.1 核心特性概览
STM32F103系列微控制器基于ARM® Cortex®-M3核心,提供高性能与低功耗的完美结合。其主频高达72MHz,具备丰富的外设接口,支持多种通信协议和接口,包括I2C, SPI, USART和USB等。内嵌Flash存储器和SRAM,以及多种低功耗模式,非常适合于工业控制、医疗设备、安全系统等领域。
1.1.2 内存与外设资源布局
该微控制器拥有不同的内存和外设资源版本,从64KB Flash和20KB SRAM到128KB Flash和20KB SRAM不等。各种版本支持最高112个通用I/O口,11个定时器,3个ADC等丰富外设。其内存布局和资源分配非常灵活,能够适应不同的应用场景需求。
1.2 开发环境与工具链配置
1.2.1 集成开发环境(IDE)的选择
开发STM32F103应用时,建议使用Keil MDK-ARM,IAR Embedded Workbench,或者开源的System Workbench for STM32。这些IDE对ARM架构和STM32系列有很好的支持,能够提供丰富的调试、编程功能。
1.2.2 编译器与调试器的配置
大多数STM32开发板都支持ST-Link系列调试器,这是一个高效、成本低的调试和编程解决方案。编译器方面,Keil MDK-ARM和IAR Embedded Workbench提供了高质量的ARM编译器,也可以选择GCC工具链进行开发。配置完成后,就可以开始STM32F103微控制器的开发之旅了。
1.3 STM32F103的启动流程
1.3.1 系统启动模式
STM32F103启动后会运行预设的系统启动模式,包括主Flash、系统内存(如Bootloader)等。系统启动模式的选择依赖于启动引脚的状态,这允许灵活地加载程序,例如直接从用户Flash启动或执行Bootloader更新程序。
1.3.2 引导加载程序(Bootloader)
引导加载程序是微控制器启动时首先执行的一段代码,通常用于初始化硬件和提供固件升级功能。在STM32F103中,可以自定义Bootloader来满足特定的启动需求。开发人员可以利用Bootloader在产品现场更新固件,无需更换硬件即可扩展产品功能或修复缺陷。
2. USART串行通信实现
2.1 USART的基本概念
2.1.1 串行通信协议基础
在嵌入式系统设计中,串行通信是不可或缺的部分,它允许微控制器与外部设备进行数据交换。串行通信协议(如UART, USART)是一种异步通信协议,它通过两个数据线(发送和接收)和两个控制线(请求发送RTS和清除发送CTS)实现设备间的通信。数据在单个传输线上的各个位按顺序传递,每个数据位占据相同的时间片。
2.1.2 USART工作模式和配置
STM32F103的USART(通用同步/异步接收/发送器)支持多种工作模式,包括全双工异步模式、同步模式以及调制解调器接口。在配置USART时,必须设置正确的波特率(数据传输速率)、数据位数、停止位和校验位等参数。这些参数的正确设置对于确保数据准确无误地传输至关重要。
2.2 USART初始化与数据发送
2.2.1 初始化流程详解
初始化USART的步骤通常包括配置GPIO引脚为串行接口功能、配置NVIC中断(如果使用中断驱动方式)、设置USART参数和启用USART。以下是初始化流程的代码示例:
void USART1_Init(void)
{
// 1. 使能GPIOA和USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 2. 配置USART1 Tx (PA.09) 为复用推挽输出,Rx (PA.10) 为浮空输入
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 3. 配置USART1的波特率、字长、停止位和校验位等参数
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// 4. 使能USART1
USART_Cmd(USART1, ENABLE);
}
2.2.2 数据发送机制与示例代码
数据发送机制涉及发送数据的函数,如 USART_SendData() ,此函数将数据放入发送数据寄存器,并由硬件在适当的时候将其发送出去。如果使用中断方式,数据发送完成会产生中断信号。以下是一个简单的数据发送示例:
void USART1_SendData(uint8_t data)
{
// 等待发送数据寄存器为空
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// 将数据放入发送数据寄存器
USART_SendData(USART1, data);
}
int main(void)
{
USART1_Init();
while(1)
{
USART1_SendData('H');
USART1_SendData('e');
USART1_SendData('l');
USART1_SendData('l');
USART1_SendData('o');
}
}
2.3 USART数据接收与中断处理
2.3.1 接收流程与配置要点
数据接收涉及配置USART为接收模式,并指定接收缓冲区和处理逻辑。在接收过程中,通常使用中断来通知系统新数据已到达。接收流程配置要点包括设置正确的接收缓冲区大小、中断触发条件(如数据寄存器非空)和中断优先级。在中断服务程序中,应从接收数据寄存器读取数据以避免溢出。
2.3.2 中断驱动接收处理
中断驱动的接收处理可以提高程序的响应性和效率。当中断发生时,中断服务程序被调用,并从USART接收数据寄存器中读取数据。以下是中断接收处理的代码示例:
// USART1中断服务程序
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
uint8_t data = USART_ReceiveData(USART1);
// 处理接收到的数据
}
}
void USART1_Config(void)
{
// 初始化配置类似于USART1_Init
// ...
// 配置NVIC中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 使能接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
在这一章节中,我们深入探讨了USART串行通信的基础知识、初始化过程、数据发送和接收机制以及中断处理。通过对USART工作原理的理解和实际代码的运用,我们可以有效地实现微控制器与外部设备之间的可靠通信。在下一章节中,我们将探讨DMA直接内存访问配置,进一步优化数据传输过程。
3. DMA直接内存访问配置
3.1 DMA的概念与优势
3.1.1 DMA的基本原理
直接内存访问(DMA)是一种允许外围设备直接读写系统内存的技术,而无需CPU的干预。在微控制器的上下文中,DMA控制器是一种硬件模块,它独立于主CPU,可以管理数据的传输。DMA的出现是为了释放CPU,使其可以专注于执行更复杂的任务,而不是花费时间在数据传输这样的低级操作上。
3.1.2 DMA与CPU资源节约
在使用DMA时,CPU不再需要参与数据的每一个传输动作,因此可以显著降低CPU的工作负载。这不仅可以提高数据传输效率,还能增强系统的实时性能,因为CPU可以在DMA处理数据时执行其他任务。此外,使用DMA可以降低系统的功耗,因为CPU在等待数据传输完成时通常处于空闲状态,消耗能量。
3.2 DMA控制器的配置
3.2.1 DMA通道与优先级设置
DMA控制器通常拥有多个通道,每个通道可以独立配置以服务不同的数据传输需求。当多个DMA请求同时发生时,优先级设置决定了哪些请求将被优先处理。在STM32F103微控制器中,每个DMA通道的优先级都是可配置的,这通常通过设置DMA控制寄存器中的相应位来完成。
3.2.2 DMA传输模式和触发源
DMA传输模式包括内存到内存、内存到外设、外设到内存等模式。触发源可以是软件触发或硬件触发。软件触发是由代码直接发起的,而硬件触发则可以是由定时器、ADC转换完成、USART接收到数据等事件引起的。正确配置DMA传输模式和触发源对于实现高效的DMA传输至关重要。
3.3 DMA与外设集成使用
3.3.1 集成外设与DMA通道
为了使DMA工作,必须将其与相应的外设集成。例如,当使用USART进行串行通信时,可以通过配置DMA通道来实现数据的自动传输。这样,当串口接收到数据或准备发送数据时,DMA可以自动将数据从内存移动到外设或反之,而无需CPU干预。
3.3.2 DMA传输完成后的处理
DMA传输完成后,通常会有一个事件标志位被设置,用于通知CPU。在完成DMA传输后,我们可能需要执行一些清理工作,比如清除标志位、启动下一个DMA传输等。这些步骤可以通过DMA传输完成中断服务程序来实现,或者在主循环中轮询DMA状态寄存器。
以下是配置DMA传输的伪代码示例,用于说明上述概念:
// DMA配置代码示例
void DMA_Configuration(void)
{
// 1. 使能DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 2. 设置DMA源地址、目标地址和传输大小
DMA1_Channelx->CMAR = (uint32_t)&SourceAddress;
DMA1_Channelx->CPAR = (uint32_t)&DestinationAddress;
DMA1_Channelx->CNDTR = NumberOfData;
// 3. 配置传输方向、数据大小、优先级和模式
DMA1_Channelx->CCR &= ~DMA_CCR_EN; // 确保在配置前禁用DMA
DMA1_Channelx->CCR |= DMA_CCR_PL | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_DIR;
DMA1_Channelx->CCR |= DMA_CCR_TCIE; // 启用传输完成中断
// 4. 使能DMA通道
DMA1_Channelx->CCR |= DMA_CCR_EN;
}
// DMA传输完成中断服务程序
void DMA1_Channelx_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TCx)) // 检查传输完成中断标志位
{
// 处理传输完成事件
// ...
// 清除中断标志位
DMA_ClearITPendingBit(DMA1_IT_TCx);
}
}
在上述代码中,我们通过配置DMA控制寄存器的相应位来设置DMA通道。代码中使用了DMA1_Channelx表示具体的DMA通道,这在实际应用中需要替换为正确的通道标识符。此外,源地址和目标地址的赋值应当替换为实际的内存地址。传输完成后,我们通过中断服务程序来处理相关的后续动作。
4. ```
第四章:USART与DMA集成方法
4.1 USART与DMA的联合配置
4.1.1 同步与异步数据传输
在嵌入式系统中,数据的传输是实时处理的重要部分。USART(通用同步/异步收发器)是实现串行通信的关键外设,而DMA(直接内存访问)用于在不经过CPU的干预下,实现快速的数据传输。将USART与DMA联合配置,可以使串口通信更加高效,尤其是在需要处理大量数据时,能显著减少CPU的负载。
同步和异步数据传输是串口通信的两种基本工作模式。在同步模式下,数据的发送与接收是在一个固定的时钟频率下进行的,这要求通信双方必须同步。异步模式则更为灵活,数据的发送和接收可以不依赖于一个共同的时钟信号。在STM32F103微控制器中,USART既支持同步模式也支持异步模式。为了确保数据传输的正确性,在配置USART时,必须选择正确的模式并设置好相关的时序参数。
4.1.2 集成配置的关键步骤
集成USART与DMA主要涉及到硬件连接和软件配置。以下是集成配置的关键步骤:
- 硬件连接: 确保USART的TX/RX引脚正确连接到相应的外设,并且DMA通道的请求线连接到了USART。
- 软件配置:
- 配置USART工作模式、波特率、数据位、停止位和校验位等参数。
- 设置DMA通道,选择正确的内存地址、传输大小、传输方向(从内存到外设或从外设到内存)。
- 配置中断(如果需要的话),并在中断服务例程中处理数据传输完成的相关事宜。
4.2 高效数据传输的实现
4.2.1 缓冲区管理策略
为了实现高效的数据传输,通常需要使用缓冲区来暂存数据。在USART与DMA集成中,合理的缓冲区管理策略是关键:
- 环形缓冲区 :这种缓冲区形式可以避免数据的覆盖问题,当缓冲区满了后,新的数据将会覆盖最旧的数据。这适用于持续数据流的情况,如音频数据。
- 静态缓冲区 :这是一种简单的缓冲区管理方式,当缓冲区满了之后,数据传输将会停止直到缓冲区被清空。这种策略适用于数据量较小或传输速度较慢的情况。
4.2.2 错误处理与异常管理
在高效率的数据传输过程中,错误处理和异常管理是不可忽视的部分。一些常见的错误可能包括溢出错误、帧错误或校验错误。有效处理这些错误通常需要结合中断和DMA传输状态寄存器,正确识别错误类型,并采取相应的恢复措施。
4.3 实际应用案例分析
4.3.1 串口通信数据缓存机制
实际应用中,为了减少数据处理的延迟,通常会实现一种串口通信数据缓存机制。在STM32F103中,可以通过DMA将接收到的数据直接存储到内存中的缓冲区,然后通过中断服务程序或轮询方式来处理这些数据。
// DMA接收配置示例代码
DMA_InitTypeDef DMA_InitStructure;
USART_InitTypeDef USART_InitStructure;
// USART 初始化
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
// DMA 初始化,将接收到的数据直接写入内存缓冲区
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rxBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = sizeof(rxBuffer);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
// 开启DMA和USART
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
USART_Cmd(USART1, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
// DMA中断服务函数(根据实际情况设置)
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5))
{
// 处理数据接收完成后的逻辑
// ...
DMA_ClearITPendingBit(DMA1_IT_TC5);
}
}
4.3.2 数据完整性保障技术
数据完整性是数据传输中的一个重要概念,特别是在数据传输过程中,必须确保数据不被损坏或丢失。实现数据完整性的保障技术通常包括:
- 校验和校验 :发送端在数据包中加入校验和信息,接收端对收到的数据进行校验和计算,如果校验和不匹配,则数据不完整。
- 时间戳机制 :通过给每个数据包附加时间信息,接收端可以验证数据的顺序和接收间隔。
- 流控制 :确保发送方在接收方可以处理的情况下才发送数据,如硬件流控制的RTS/CTS信号。
在实际开发中,根据应用的具体需求和环境,开发者可以灵活运用上述技术来确保数据的完整性。
# 5. 中断处理机制和应用
## 5.1 中断系统概述
在嵌入式系统中,中断是一种重要的机制,它允许处理器对突发事件做出快速响应。中断可以来自内部源,如定时器溢出或外部源,如按钮按下。中断处理机制的设计是为了最小化对主程序流程的干扰,同时确保关键事件能够得到及时处理。
### 5.1.1 中断的类型与优先级
中断可以分为多种类型,包括固定优先级中断和抢占式中断。固定优先级中断一旦被触发,将会一直等待直到当前的执行周期结束。而抢占式中断允许更高优先级的中断打断当前的中断处理,实现更快的响应。
- 固定优先级中断:通常是基于中断向量表中的顺序来处理。
- 抢占式中断:需要在中断控制器中进行特别的配置。
### 5.1.2 中断向量表和中断处理流程
中断向量表是一张映射表,定义了中断号与中断服务例程(ISR)之间的关系。当中断发生时,处理器会查找向量表,直接跳转到对应的ISR执行。在ISR中,中断服务代码通常需要尽可能的短小精悍,以减少对主程序的影响。
一个典型的中断处理流程如下:
1. 中断事件发生。
2. 硬件自动保存当前程序状态。
3. 中断控制器查找中断向量表,找到对应的ISR地址。
4. 处理器跳转至ISR执行。
5. ISR执行完毕后,恢复程序状态,返回到中断前的地方继续执行。
## 5.2 中断控制器的配置与管理
中断控制器是负责管理和分配中断请求的硬件组件。通过编程中断控制器,开发者可以控制中断的使能/禁止、设置中断优先级,以及配置中断触发的方式。
### 5.2.1 中断使能与屏蔽
中断使能与屏蔽是中断管理的关键环节。开发者可以根据需要开启或关闭特定的中断源。例如,在系统初始化时,可能需要禁用某些中断以避免不期望的处理。
### 5.2.2 中断优先级配置与调整
在具有多个中断源的系统中,配置合适的中断优先级至关重要。通常,中断优先级是由软件设置的,优先级的配置可以调整中断的响应顺序和处理策略。
## 5.3 中断服务程序的实现
编写中断服务程序需要特别注意资源访问的同步和中断的嵌套问题。由于中断服务程序在执行时可能会打断主程序的执行,因此需要谨慎处理全局变量和硬件资源。
### 5.3.1 编写中断服务函数
中断服务函数应该做到快速执行,避免执行耗时的I/O操作或者复杂的计算。以下是一个简单的中断服务函数的框架:
```c
void EXTI0_IRQHandler(void) {
if(EXTI->PR & (1 << 0)) {
// 处理外部中断0
// ...
// 清除中断标志位
EXTI->PR = (1 << 0);
}
}
5.3.2 中断与轮询的对比分析
轮询方式需要主程序不断检查外设的状态,这通常会导致处理器资源的浪费。与之相比,中断机制允许处理器在空闲时执行其他任务,只在必要时响应中断,因此能够更高效地利用处理器资源。
在实际应用中,中断机制通常用于处理那些要求快速响应的事件,例如实时数据采集、键盘输入等。选择中断或轮询取决于具体应用场景以及对实时性的要求。
简介:本文深入探讨了STM32F103微控制器实现USART、DMA和中断集成的过程。介绍了如何利用USART进行串行通信,配置DMA以减轻CPU负担,以及使用中断响应USART事件。提供了具体的代码实现步骤,包括初始化USART、配置DMA通道、链接USART与DMA,以及设置中断服务例程。这对于嵌入式系统设计者掌握STM32F103外设使用具有重要价值。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐




所有评论(0)