简单手机网站源码下载,规划设计公司,公司注册网站入口,win10 电脑做网站服务器目录 串口通信
概论
原理
配置
HAL库代码
1. 初始化函数
2. 数据发送和接收函数
3. 中断和DMA函数
4. 中断服务函数 串口通信
概论
我们知道#xff0c;通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。
比较常见的串…目录 串口通信
概论
原理
配置
HAL库代码
1. 初始化函数
2. 数据发送和接收函数
3. 中断和DMA函数
4. 中断服务函数 串口通信
概论
我们知道通信桥接了两个设备之间的交流。一个经典的例子就是使用串口通信交换上位机和单片机之间的数据。
比较常见的串口通信协议是下面这两个
UART通用异步收发传输器Universal Asynchronous Receiver/Transmitter这里可以看到这样的协议只有Asynchronous提示你这个协议是异步的。异步通信需要在传递数据的同时添加起始位、停止位、校验位等进行帧同步放置进行数据裁剪和区分。
USART通用同步异步收发传输器则更进一步支持了同步的通信方式在同步模式下USART通过时钟信号与从设备同步数据传输在异步模式下工作与UART相似。
原理
本质上就是数据通过数据线移动从一个设备传递到另一个设备。在串口通信中这是通过移位寄存器移位实现的。移出去的位被派发到传输线上传递出去给下一个移进来的比特腾出来位置。对于接受的设备那就是接受到来的比特给下一个到来的比特腾出位置。 仔细看这里的移位寄存器示意图就是在移动将它发送到TX端上从数据线上流出去另一端如果有来者则从RX端进入接收移位寄存器进来。
配置
上面的笼统概述没有统一问题咋个长度咋个校验收发速度如何不讨论这些问题双方无法保证数据的接受和发送是一一呼应的极易导致数据接受和发送异常。所以就有了协议协议约定了两者的动作。 波特率串口通信的速率一般需要配置波特率寄存器实现。其计算公式是 空闲一般为高电平 起始位标志一个数据帧的开始固定为低电平。当数据开始发送时产生一个下降沿。(空闲–起始位) 数据位发送数据帧1为高电平0为低电平。低位先行。 比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000 校验位用于数据验证根据数据位的计算得来。有奇校验偶校验和无校验。 奇校验Odd Parity确保数据帧中1的数量为奇数。 偶校验Even Parity确保数据帧中1的数量为偶数。 停止位用于数据的间隔固定为高电平。数据帧发送完成后产生一个上升沿。(数据传输–停止位)
HAL库代码
1. 初始化函数 HAL_UART_Init() 这个函数一般如果使用CubeMx配置的话就会给你写好了它用于初始化UART外设包括波特率、数据位、停止位、奇偶校验和硬件流控制。通常在程序开始时调用此函数以配置UART通信的基本参数。 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); 参数说明 huart指向UART句柄的指针句柄包含了UART的所有配置参数如波特率、数据位、停止位等。 返回值 HAL_OK初始化成功。 HAL_ERROR初始化失败。 使用示例 UART_HandleTypeDef huart1;
huart1.Instance USART1;
huart1.Init.BaudRate 9600;
huart1.Init.WordLength UART_WORDLENGTH_8B;
huart1.Init.StopBits UART_STOPBITS_1;
huart1.Init.Parity UART_PARITY_NONE;
huart1.Init.Mode UART_MODE_TX_RX;
huart1.Init.HwFlowCtl UART_HWCONTROL_NONE;
huart1.Init.OverSampling UART_OVERSAMPLING_16;
HAL_UART_Init(huart1);
2. 数据发送和接收函数 HAL_UART_Transmit() 用于通过UART发送数据。此函数可以在阻塞模式、非阻塞模式或中断模式下工作。 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); 参数说明 huart指向UART句柄的指针。 pData指向要发送的数据的指针。 Size要发送的数据字节数。 Timeout超时时间单位为毫秒。 返回值 HAL_OK数据发送成功。 HAL_ERROR发送失败。 使用示例 uint8_t msg[] Hello UART!;
HAL_UART_Transmit(huart1, msg, sizeof(msg)-1, 1000); HAL_UART_Receive() 用于从UART接收数据。该函数也可以在阻塞模式、非阻塞模式或中断模式下工作。 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); 参数说明 huart指向UART句柄的指针。 pData指向接收数据的缓冲区。 Size要接收的数据字节数。 Timeout超时时间单位为毫秒。 返回值 HAL_OK数据接收成功。 HAL_ERROR接收失败。 使用示例 uint8_t receivedData[10];
HAL_UART_Receive(huart1, receivedData, 10, 1000);
3. 中断和DMA函数 HAL_UART_Transmit_IT() 这种方式就是异步的执行完这个函数只是委托函数开始转发程序流继续执行。用于通过中断方式发送数据。当数据发送完成时会触发中断。 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 参数说明 huart指向UART句柄的指针。 pData指向要发送的数据的指针。 Size要发送的数据字节数。 返回值 HAL_OK数据发送任务已启动。 HAL_ERROR启动失败。 使用示例 uint8_t msg[] Hello UART!;
HAL_UART_Transmit_IT(huart1, msg, sizeof(msg)-1); HAL_UART_Receive_IT() 用于通过中断方式接收数据。接收的数据将在中断服务程序ISR中处理。 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 参数说明 huart指向UART句柄的指针。 pData指向接收数据的缓冲区。 Size要接收的数据字节数。 返回值 HAL_OK接收任务已启动。 HAL_ERROR启动失败。 使用示例 uint8_t receivedData[10];
HAL_UART_Receive_IT(huart1, receivedData, 10); HAL_UART_Transmit_DMA() 用于通过DMA直接内存访问发送数据。DMA可以使数据传输不占用CPU从而提高数据传输效率。 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 参数说明 huart指向UART句柄的指针。 pData指向要发送的数据的指针。 Size要发送的数据字节数。 返回值 HAL_OKDMA传输已启动。 HAL_ERROR启动失败。 使用示例 uint8_t msg[] Hello UART!;
HAL_UART_Transmit_DMA(huart1, msg, sizeof(msg)-1); HAL_UART_Receive_DMA() 用于通过DMA接收数据。DMA可以有效地将数据从UART缓冲区传输到内存而无需CPU干预。 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 参数说明 huart指向UART句柄的指针。 pData指向接收数据的缓冲区。 Size要接收的数据字节数。 返回值 HAL_OKDMA接收已启动。 HAL_ERROR启动失败。 使用示例 uint8_t receivedData[10];
HAL_UART_Receive_DMA(huart1, receivedData, 10);
4. 中断服务函数
在使用中断模式时需要实现中断回调函数。这些函数由HAL库调用。我们需要做的就是实现这些函数有趣的是默认的实现是__weak的意味着用户的定义隶属于强定义编译器优先采纳用户实现。 HAL_UART_TxCpltCallback() 当数据发送完成时这个回调函数会被调用。 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); HAL_UART_RxCpltCallback() 当数据接收完成时这个回调函数会被调用。 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);