STM32 串口通信

串口发原理

在stm32每个串口内部有发送寄存器和发送移位寄存器。

当调用HAL_UART_Transmit 时,cpu会将发送的数据放入发送寄存器中。发送移位寄存器会将数据转换成电平的高低,从TX发出。

1、轮询模式配置、发送与接收

轮询模式时cpu会不断检测发送数据寄存器的数据是否已经发送到发送移位寄存器。直到把本次数据全部发完,或者超时。 CPU会一直处于忙碌状态。

1.1、配置

1.2、发送

c 复制代码
char message[] = "hello world\r\n";
HAL_UART_Transmit(&huart1, (uint8_t *)message, strlen(message), 1000);

1.3、接收

c 复制代码
uint8_t rxbuf[1];
HAL_UART_Receive(&huart1, rxbuf, 1, HAL_MAX_DELAY);

2、中断模式

采用中断的串口发送接收模式,不会一直占用cpu。

2.1、配置

2.2、发送

与轮询的代码区别就是在函数后加了-IT

c 复制代码
char message[] = "hello world\r\n";
HAL_UART_Transmit_IT(&huart1, (uint8_t *)message, strlen(message));
HAL_Delay(1100);

2.3、接收

中断接收三字节数据:

c 复制代码
HAL_UART_Receive_IT(&huart1, rxbuf, 3);

2.4、中断接收串口命令控制小灯亮灭

调用HAL_UART_Receive_IT(&huart1, rxbuf, 3)函数后,如果串口接收到3字节的数据后就会调用HAL_UART_RxCpltCallback表示数据接收完成,我们在这里解析数据,控制小灯亮灭即可。

c 复制代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Transmit_IT(&huart1, (uint8_t *)rxbuf, 3);
	if(rxbuf[0]=='A'){
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
	}
	if(rxbuf[0]=='B'){
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
	}
	HAL_UART_Receive_IT(&huart1, rxbuf, 3);
}

3、串口的DMA模式

DMA (Direct Memory Acess)模式可以减少cpu的负载,帮助cpu来搬运数据。

3.1 串口DMA配置

点击add按钮添加即可

3.2 DMA代码

DMA模式还是有中断参与的(DMA传输完成中断),代码和普通中断(串口接收完成中断,串口发送完成中断)模式的区别就是把IT改为DMA即可,如下,可以完成对小灯的控制:

c 复制代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)rxbuf, 3);
	if(rxbuf[0]=='A'){
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
	}
	if(rxbuf[0]=='B'){
	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
	}

	HAL_UART_Receive_DMA(&huart1, rxbuf, 3);
}

4、串口实现收发不定长数据

该功能的实现主要依靠串口的空闲中断,此中断的触发条件与接收的字节数无关,只有当RX引脚上无数据进入时,也就是串口从忙碌转为空闲时才会触发。

所以我们可认为触发空闲中断时,一帧数据完成,在此中断服务函数中编写我们的代码即可。

这里HAL库给我们提供了一个扩展函数:HAL_UARTEx_ReceiveToIdle_DMA可以帮我们实现接收不定长数据,当由忙碌到空闲时会触发中断进入HAL_UARTEx_RxEventCallback函数。

4.1、接收不定长数据代码实现

将接收到的数据再通过串口发送出来

c 复制代码
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxbuf, 100);

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)rxbuf, Size);
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxbuf, 10);
}

4.3、DMA传输过半中断

DMA传输过半中断指的是当串口接收到指定最大长度的一半时也会触发中断导致进入HAL_UARTEx_RxEventCallback函数。上面没出现这种情况是因为我们receive时设置的参数较大100,当该值设的较小时就会出现问题。

关闭DMA传输过半中断的函数是:__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);

相关推荐
Saniffer_SH40 分钟前
NAND技术(二):从 Channel、Die/LUN、P/E Cycle 到 LDPC,一次讲透 NAND 里那些最容易误解的概念
人工智能·驱动开发·嵌入式硬件·测试工具·fpga开发·计算机外设·压力测试
辰哥单片机设计2 小时前
STM32音乐播放器
stm32·单片机·嵌入式硬件
周洲08302 小时前
STM32 串口指令控制系统|上位机下发命令控制 LED、继电器,通用指令解析框架
stm32·嵌入式硬件·mongodb
集芯微电科技有限公司2 小时前
PC3100H 专为TFT-LCD面板偏置电源设计双输出100m电流
人工智能·单片机·嵌入式硬件·神经网络·生成对抗网络
广州灵眸科技有限公司3 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) 系统操作-线进程操作
数据库·单片机·嵌入式硬件·算法·php
集芯微电科技有限公司5 小时前
各种大小尺寸TFT-LCD面板供电偏压电源方案IC
人工智能·单片机·嵌入式硬件·神经网络·生成对抗网络
FREEDOM_X5 小时前
嵌入式——定时器工作原理
linux·c语言·单片机·嵌入式硬件·ubuntu
2401_827501285 小时前
51单片机(三)串口通信(UART)、Modbus协议
单片机·嵌入式硬件·51单片机
振浩微433射频芯片6 小时前
5个IO控制20个LED?查理复用实战拆解
网络·单片机·物联网·学习·智能家居
2601_958352907 小时前
从智能安防到矿山预警:AR1105声源定位模组的行业应用与架构解析
人工智能·嵌入式硬件·架构·机器人·回音消除·声源定位