第一节、同步通信与异步通信的概念:
1.异步通信:
即通信双方,均独立工作,即有各自的时钟源。
发送方发出数据后,不需要等待接收方即时反馈与确认,可以继续进行其他操作。
因为异步通信没有使用同步的时钟,所以通常需要额外的控制信息,如:起始位,停止位,校验位,来标识数据的开始和结束,确定数据的正确传输和解析。
常见于有两个有独立时钟源的设备间的通信。
如:UART就是一种异步通信方式。
2.同步通信:
即通信双方,在共享的同一时钟下工作,使用同一时钟源。
发送方发出数据后,会等待接收方确认或反馈,然后才能进行继续下一步操作。
因为同步通信使用同一时钟,所以收发双方需要严格按照约定好的时序进行操作。
常见于在同一MCU或MPU下与多个外设设备的通信。
如:I2C,SPI就是一种同步通信方式。
3.工作模式:全双工与半双工式:
全双工是指:在同一时刻即可发送数据,亦可接收数据。所以一般情况为有两条数据线,发送线与接收线。
半双工是指:在同一时刻只能发送数据或接收数据,所以只需要一条数据线即可。
UART串口是一个全双工的异步的通信接口.
第二节、UART串口
1. UART通信协议的时序:从低到高字节发(LSB -->MSB)
2.UART控制器硬件接口及内部框图:
2.1接口连接:
通过三个引脚与其他设备连接在一起(见图248)。
任何USART双向通信至少需要两个脚:接
收数据输入(RX)和发送数据输出(TX)。
RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。
2.2UART控制器硬件框图:
2.3使用CubMX快速配置UART硬件相关的寄存器:
第三节、UART串口驱动的HAL库API:
1. 阻塞版收发数据接口函数:
1.1阻塞版发送数据:
HAL_StatusTypeDef HAL_UART_Transmit (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size,
uint32_t Timeout)
功能:通过 UART(通用异步收发传输器)发送数据
参数:
UART_HandleTypeDef *huart:一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含指定 UART 模块的配置信息。
这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData:一个指向数据缓冲区的指针,缓冲区中包含要发送的数据。
uint16_t Size:要发送的数据的字节数。
uint32_t Timeout:等待传输完成的超时时间(以毫秒为单位)。
如果在这个时间内传输没有完成,函数将返回超时错误。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
HAL_TIMEOUT: 在操作完成前函数超时。
1.2阻塞版接收数据:
HAL_StatusTypeDef HAL_UART_Receive (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size,
uint32_t Timeout)
函数功能:通过 UART(通用异步收发传输器)接收数据.
参数说明
UART_HandleTypeDef *huart:一个指向 UART_HandleTypeDef 结构体的指针,
该结构体包含指定 UART 模块的配置信息。这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData:一个指向数据缓冲区的指针,接收的数据将存储在这个缓冲区中。
uint16_t Size:要接收的数据的字节数。
uint32_t Timeout:等待接收完成的超时时间(以毫秒为单位)。
如果在这个时间内接收没有完成,函数将返回超时错误。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
HAL_TIMEOUT: 在操作完成前函数超时。
1.3阻塞版uart收发数据实例应用:
驱动:uart_driver.c:
#include "uart_driver.h"
#include <stdint.h>
#include "FreeRTOS.h"
#include "main.h"
#include "task.h"
#include "usart.h"
#include <stdbool.h>
extern UART_HandleTypeDef huart1;
//阻塞方式发送数据:
int uart_send_by_block(void* buf, int size)
{
return HAL_UART_Transmit(&huart1,buf, size, portMAX_DELAY);
}
//阻塞方式接收数据:
int uart_recv_by_block(void* buf, int maxSize)
{
HAL_StatusTypeDef status;
char* ptr = (char*)buf;
int len = 0;
while(true)
{
status = HAL_UART_Receive(&huart1, (uint8_t*)ptr, 1, portMAX_DELAY);
if(*ptr == '\0' || *ptr == '\n' || *ptr == '\r')
{
break;
}
ptr++;
len++;
if(len > maxSize - 1)//应该是len > maxSize -1 才对,有点疏忽了。
{
break;
}
}
return status;
}
应用测试:uart_app.c:
#include "uart_app.h"
#include "uart_driver.h"
#include <string.h>
#include <stdbool.h>
//uart测试任务回调函数:
void uart_task_function(void* arg)
{
const char* str = "Welcome uart_test,Plase input CMD: \n";
uart_send_by_block((void*)str,strlen(str));
char buf[128] = {0};
while (true)
{
/* 测试uart串口收发数据 */
memset(buf, 0,sizeof(buf));
uart_recv_by_block(buf,sizeof(buf)-1);
//发给串口,在PC串口终端进行显示:
uart_send_by_block(buf,strlen(buf));
}
}
2.中断非阻塞版收发数据接口函数:
2.1中断非阻塞版发送数据:
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
功能:用于通过 UART(通用异步收发传输器)以中断方式发送数据。
参数说明
UART_HandleTypeDef *huart:一个指向 UART_HandleTypeDef 结构体的指针,
该结构体包含指定 UART 模块的配置信息。这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData:一个指向数据缓冲区的指针,缓冲区中包含要发送的数据。
uint16_t Size:要发送的数据的字节数。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
该函数是非阻塞的,数据传输将在后台进行。
函数调用后立即返回,传输过程由中断驱动,传输完成后会产生一个完成中断。
需要在相应的 UART 中断服务程序(ISR)中处理传输完成事件。
通常在串口中断会调用 HAL_UART_IRQHandler 句柄。在这个句柄中回调处理完成的中断ISR:
在传输完成后会调用 HAL_UART_TxCpltCallback 回调函数,用户可以在该回调函数中执行后续处理。
1.重新实现HAL_UART_TxCpltCallback 回调函数,处理完成后的逻辑:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
// 传输完成后的处理代码
if (huart->Instance == USART1)
{
// UART1 传输完成后的处理
}
}
发送Transmit_IT中断调用路径:
2.2中断非阻塞版接收数据:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
功能:用于通过 UART(通用异步收发传输器)以中断方式接收数据
参数说明
UART_HandleTypeDef *huart:一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含指定 UART 模块的配置信息。这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData:一个指向数据缓冲区的指针,接收的数据将存储在这个缓冲区中。
uint16_t Size:要接收的数据的字节数。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
该函数是非阻塞的,传输过程由中断驱动,数据接收将在后台进行。
函数调用后立即返回,接收完成后会产生一个完成中断。
需要在相应的 UART 中断服务程序(ISR)中处理接收完成事件。通常在 ISR 中调用 HAL_UART_IRQHandler 函数来处理中断。
在接收完成后会调用 HAL_UART_RxCpltCallback 回调函数,用户可以在该回调函数中执行后续处理。
1.重新实现HAL_UART_RxCpltCallback 回调函数,处理完成后的逻辑:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
f // 接收完成后的处理代码
if (huart->Instance == USART1)
{
// UART1 接收完成后的处理
}
}
接收非阻塞中断的调用路径:
2.3中断非阻塞版uart收发实例应用:
驱动:
//非阻塞方式发送数据:
//实现完整数据的同步:
SemaphoreHandle_t send_sem;
int uart_send_by_interrupt(void* buf, int size)
{
HAL_StatusTypeDef status;
send_sem = xSemaphoreCreateBinary();
status = HAL_UART_Transmit_IT(&huart1, buf, size);
//获取信号量:
xSemaphoreTake(send_sem,portMAX_DELAY);
//删除信号量:
vSemaphoreDelete(send_sem);
return status;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
BaseType_t status;
//归还信号量:
xSemaphoreGiveFromISR(send_sem, &status);
if(status == pdTRUE)
{
portYIELD_FROM_ISR(status);
}
}
//非阻塞方式接收数据:
SemaphoreHandle_t recv_sem;
char* ptr = NULL;
int maxlen = 0;
int uart_recv_by_interrupt(void* buf, int maxSize)
{
HAL_StatusTypeDef status;
ptr = buf;
maxlen = maxSize;
//先申请信号量
recv_sem = xSemaphoreCreateBinary();
//再调用非阻塞中断接收函数:
status = HAL_UART_Receive_IT(&huart1, buf, 1);
//获取信号量:
xSemaphoreTake(recv_sem, portMAX_DELAY);
//删除信号量:
vSemaphoreDelete(recv_sem);
return status;
}
//接受中断中的完成时的中断回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static int len = 0;
BaseType_t status;
if(*ptr == '\0' || *ptr == '\n' || *ptr == '\r' || len > maxlen - 1)
{
//归还信号量:
xSemaphoreGiveFromISR(recv_sem, &status);
if(status == pdTRUE)
{
portYIELD_FROM_ISR(status);
}
//len归0
len = 0;
//一定要在此返回
return;
}
len++;
ptr++;
HAL_UART_Receive_IT(&huart1, (uint8_t*)ptr, 1);
}
应用测试:
#include "uart_app.h"
#include "uart_driver.h"
#include <string.h>
#include <stdbool.h>
//uart测试任务回调函数:
void uart_task_function(void* arg)
{
const char* str = "Welcome uart_test,Please input CMD: \n";
uart_send_by_interrupt((void*)str,strlen(str));
char buf[128] = {0};
while (true)
{
/* 测试uart串口收发数据 */
memset(buf, 0,sizeof(buf));
uart_recv_by_interrupt(buf, sizeof(buf)-1);
//发给串口,在PC串口终端进行显示:
uart_send_by_interrupt(buf,strlen(buf));
}
}
3.DMA版收发数据接口函数:
1. DMA简述:
1. 什么是DMA,作用是什么?
由于很多外设的数据都由CPU进行拷贝,为了提高CPU实时性,进行更加重要的数据逻辑的处理,对于数据拷贝的工作,交于一个专门进行定向内存拷贝工作的Soc内部组件,就是DMA.
F103这个MCU有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。每个通道用来处理来自一个或多个外设对存储器的访问。
DMA的作用:对于代替CPU执行一些简单的数据拷贝工作,拷贝完成之后产生一个中断通知,不需要CPU介入传输的具体过程。
2.DMA框图:
2.DMA版串口收发数据:
2.1 DMA版发送数据:
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
功能:用于通过 UART(通用异步收发传输器)以 DMA(直接存储器访问)方式发送数据
参数说明
UART_HandleTypeDef *huart:一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含指定 UART 模块的配置信息。这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData:一个指向数据缓冲区的指针,缓冲区中包含要发送的数据。
uint16_t Size:要发送的数据的字节数。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
该函数是非阻塞的,数据传输将在后台进行。函数调用后立即返回,传输完成后会产生一个 DMA 中断。
需要在相应的 UART 和 DMA 中断服务程序(ISR)中处理传输完成事件。通常在 ISR 中调用 HAL_UART_IRQHandler 函数来处理中断。
在传输完成后会调用 HAL_UART_TxCpltCallback 回调函数,用户可以在该回调函数中执行后续处理。
与中断版一样。也可以处理完成之后的回调函数。
在传输完成后会调用 :HAL_UART_TxCpltCallback 回调函数,用户可以在该回调函数中执行后续处理。
2.2 DMA版接收数据:
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
功能:用于通过 UART(通用异步收发传输器)以 DMA(直接存储器访问)方式接收数据
参数说明
UART_HandleTypeDef *huart
:一个指向 UART_HandleTypeDef 结构体的指针,该结构体包含指定 UART 模块的配置信息。这个结构体包括 UART 外设的实例,以及其配置和状态信息。
uint8_t *pData
:一个指向数据缓冲区的指针,接收的数据将存储在这个缓冲区中。
uint16_t Size
:要接收的数据的字节数。
返回值
该函数返回一个 HAL_StatusTypeDef 类型的值,可以是以下几种之一:
HAL_OK: 函数执行成功。
HAL_ERROR: 执行过程中发生错误。
HAL_BUSY: UART 当前正忙于之前的操作。
该函数是非阻塞的,数据接收将在后台进行。函数调用后立即返回,接收完成后会产生一个 DMA 中断。
需要在相应的 UART 和 DMA 中断服务程序(ISR)中处理接收完成事件。
通常在 ISR 中调用 HAL_UART_IRQHandler 函数来处理中断。
在接收完成后会调用 HAL_UART_RxCpltCallback 回调函数,用户可以在该回调函数中执行后续处理。
2.3调用路径:以发送为例:
2.4工程配置DMA:
2.5 HAL库中的uart全局实例与dma全局实例之间的关系:
2.6 DMA版uart收发应用实例:
驱动:
#include "uart_driver.h"
#include <string.h>
#include <stdio.h>
extern UART_HandleTypeDef huart1;
// 阻塞方式发送数据:
int uart_send_by_block(void *buf, int size)
{
return HAL_UART_Transmit(&huart1, buf, size, portMAX_DELAY);
}
// 阻塞方式接收数据:
int uart_recv_by_block(void *buf, int maxSize)
{
HAL_StatusTypeDef status;
char *ptr = (char *)buf;
int len = 0;
while (true)
{
status = HAL_UART_Receive(&huart1, (uint8_t *)ptr, 1, portMAX_DELAY);
if (*ptr == '\0' || *ptr == '\n' || *ptr == '\r')
{
break;
}
ptr++;
len++;
if (len > maxSize - 1)
{
break;
}
}
return status;
}
// 非阻塞方式发送数据:
// 实现完整数据的同步:
SemaphoreHandle_t send_sem;
int uart_send_by_interrupt(void *buf, int size)
{
HAL_StatusTypeDef status;
send_sem = xSemaphoreCreateBinary();
status = HAL_UART_Transmit_IT(&huart1, buf, size);
// 获取信号量:
xSemaphoreTake(send_sem, portMAX_DELAY);
// 删除信号量:
vSemaphoreDelete(send_sem);
return status;
}
// 非阻塞方式接收数据:
SemaphoreHandle_t recv_sem;
char *ptr = NULL;
int maxlen = 0;
int uart_recv_by_interrupt(void *buf, int maxSize)
{
HAL_StatusTypeDef status;
ptr = buf;
maxlen = maxSize;
// 先申请信号量
recv_sem = xSemaphoreCreateBinary();
// 再调用非阻塞中断接收函数:
status = HAL_UART_Receive_IT(&huart1, buf, 1);
// 获取信号量:
xSemaphoreTake(recv_sem, portMAX_DELAY);
// 删除信号量:
vSemaphoreDelete(recv_sem);
return status;
}
// 5.非阻塞DMA方式的发送数据:
SemaphoreHandle_t send_dma_sem;
int uart_send_by_dma(void *buf, int size)
{
HAL_StatusTypeDef status;
// 先创建信号量:
send_dma_sem = xSemaphoreCreateBinary();
status = HAL_UART_Transmit_DMA(&huart1, buf, size);
// 获取信号量:
xSemaphoreTake(send_dma_sem, portMAX_DELAY);
//删除信号量:
vSemaphoreDelete(send_dma_sem);
return status;
}
// 发送完成之后的中断回调函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
BaseType_t status;
if (huart1.hdmatx != NULL)
{
// 归还信号量:
xSemaphoreGiveFromISR(send_dma_sem, &status);
if (status == pdTRUE)
{
portYIELD_FROM_ISR(status);
}
}
else{
// 归还信号量:
xSemaphoreGiveFromISR(send_sem, &status);
if (status == pdTRUE)
{
portYIELD_FROM_ISR(status);
}
}
}
// 6.非阻塞中断方式接收数据:
SemaphoreHandle_t recv_dma_sem;
int uart_recv_by_dma(void *buf, int maxSize)
{
HAL_StatusTypeDef status;
ptr = buf;
maxlen = maxSize;
// 先申请信号量
recv_dma_sem = xSemaphoreCreateBinary();
// 再调用非阻塞中断接收函数:
status = HAL_UART_Receive_DMA(&huart1, buf, 1);
// 获取信号量:
xSemaphoreTake(recv_dma_sem, portMAX_DELAY);
// 删除信号量:
vSemaphoreDelete(recv_dma_sem);
return status;
}
// 接受中断中的完成时的中断回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static int len = 0;
BaseType_t status;
if (*ptr == '\0' || *ptr == '\n' || *ptr == '\r' || len > maxlen - 1)
{
// 归还信号量:
if(huart->hdmarx != NULL)
{
xSemaphoreGiveFromISR(recv_dma_sem, &status);
}else{
xSemaphoreGiveFromISR(recv_sem, &status);
}
if (status == pdTRUE)
{
portYIELD_FROM_ISR(status);
}
// len归0
len = 0;
// 一定要在此返回
return;
}
len++;
ptr++;
if(huart->hdmarx != NULL)
{
HAL_UART_Receive_DMA(&huart1, (uint8_t *)ptr, 1);
}
else{
HAL_UART_Receive_IT(&huart1, (uint8_t *)ptr, 1);
}
}
应用测试:
#include "uart_app.h"
#include "uart_driver.h"
#include <string.h>
#include <stdbool.h>
//uart测试任务回调函数:
void uart_task_function(void* arg)
{
const char* str = "Welcome uart_test,Please input CMD: \n";
uart_send_by_dma((void*)str,strlen(str));
char buf[128] = {0};
while (true)
{
/* 测试uart串口收发数据 */
memset(buf, 0,sizeof(buf));
uart_recv_by_dma(buf, sizeof(buf)-1);
//发给串口,在PC串口终端进行显示:
uart_send_by_dma(buf,strlen(buf));
}
}
第四节、UART空闲idle中断:
1.idle中断是什么?意义是什么?
1.1什么是idle中断?
idle,空闲的定义是:总线上在一个字节(一个完整帧即10个bit)的时间内没有再接收到数据。
问:UART 的 IDLE 中断何时发生呢?
RxD 引脚一开始就是空闲的啊,难道 IDLE 中断一直产生?
答:不是的。当我们使能 IDLE 中断后,它并不会立刻产生,而是:至少收到 1 个数据后,发现:在一个字节的时间里,都没有接收到新数据,才会产生 。
1.2 idle中断意义是什么?
idle的意义:有了idle中断,我们对完整的数据边界就有了更好的判断,而不需要CPU参与到数据的判断中来,大大节约了CPU的资源。
2.idle中断的相关API:都是与接收数据相关的:
因为只有接收至少一个字节后,发现一个字节的数据帧的时间后没有接到数据,就会产生idle中断,通过idle中断我们来的处理相应的数据逻辑。
1.HAL_UARTEx_ReceiveToIdle
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout);
功能:用于在接收数据时,当检测到 UART 接口的 IDLE 中断时停止接收,并返回已经接收到的数据长度。
这个函数用于处理不定长数据接收场景,在数据接收完成后自动触发回调,从而避免了需要预先知道数据长度的问题。
参数说明
huart:UART 句柄。
pData:指向接收数据缓冲区的指针。
Size:预期接收的数据大小。
RxLen:指向一个变量的指针,该变量在函数返回时包含实际接收的数据长度。
Timeout:指定超时时间。
返回值
HAL_OK:操作成功。
HAL_ERROR:操作失败。
HAL_BUSY:UART 正忙。
HAL_TIMEOUT:操作超时。
2.HAL_UARTEx_ReceiveToIdle_IT
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout);
功能:结合了 IDLE 中断和中断驱动的接收机制,适用于处理不定长数据接收的场景。
参数说明
huart
:指向 UART 句柄的指针,用于指定使用的 UART 外设。
pData
:指向接收数据缓冲区的指针。数据将被接收到该缓冲区中。
Size
:接收缓冲区的大小。指定了缓冲区可以容纳的最大数据量。
返回值
HAL_OK:函数执行成功,数据接收已启动。
HAL_ERROR:发生了错误。
HAL_BUSY:UART 外设当前忙碌。
HAL_TIMEOUT:超时错误。
出现空闲时,回调中断处理函数:
实现 HAL_UARTEx_RxEventCallback 回调函数,以在 IDLE 中断时处理接收到的数据。
3.HAL_UARTEx_ReceiveToIdle_DMA
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout);
功能:结合了 DMA 的高效数据传输和 IDLE 中断的检测机制,适合处理不定长的数据接收场景。
参数说明
huart:指向 UART 句柄的指针,用于指定使用的 UART 外设。
pData:指向接收数据缓冲区的指针。DMA 将数据从 UART 外设传输到此缓冲区中。
Size:接收缓冲区的大小。指定了缓冲区可以容纳的最大数据量。
返回值
HAL_OK:函数执行成功,DMA 接收已启动。
HAL_ERROR:发生了错误。
HAL_BUSY:UART 外设当前忙碌。
HAL_TIMEOUT:超时错误。
出现空闲时,回调中断处理函数:
实现 HAL_UARTEx_RxEventCallback 回调函数,以在 IDLE 中断时处理接收到的数据。
4.HAL_UARTEx_RxEventCallback回调函数:
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size);
作用是: STM32 HAL 库中用于处理 UART 接收事件的回调函数,特别是处理 IDLE 中断事件。
这一回调函数在 UART 外设接收到一段数据后并检测到数据传输结束时被调用
参数
UART_HandleTypeDef *huart:指向 UART 外设句柄的指针,包含了 UART 外设的配置信息和状态。
uint16_t Size:接收到的数据的长度,以字节为单位。
3.使用idle接收任意长度数据的实例,本想此实例为冲电朋友专属,感谢支持。本实例为冲电朋友专享内容。因为冲电与不冲电的朋友应该有不一样的待遇。
驱动:
测试:
#include "uart_app.h"
#include "uart_driver.h"
#include <string.h>
#include <stdbool.h>
//uart测试任务回调函数:
void uart_task_function(void* arg)
{
const char* str = "Welcome uart_test,Please input CMD: \n";
uart_send_by_dma((void*)str,strlen(str));
char buf[128] = {0};
while (true)
{
/* 测试uart串口收发数据 */
memset(buf, 0,sizeof(buf));
uart_recv_by_dmaToIdle(buf, sizeof(buf)-1);
//发给串口,在PC串口终端进行显示:
uart_send_by_dma(buf,strlen(buf));
}
}
第五节、uart总结:
1.uart知识点结构:
2.uart终端的printf实现:
工程编译使用MicroLib库:重新实现fputc函数即可。用于后续课程中的DeBug调试。
//重写putchar:
int fputc(int c, FILE* file)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&c, 1, portMAX_DELAY);
return c;
}