一.通信的基本概念
1.串行通信和并行通信
2.全双工、半双工和单工
3.针对串行通信的同步通信和异步通信
4.通信速率
二.UART配置
UART常用HAL库函数
//UART_HandleTypeDef *huart是句柄
typedef struct
{
//初始化看前面两个就可以了
USART_TypeDef *Instance; /* UART 寄存器基地址 */
UART_InitTypeDef Init; /* UART 通信参数 */
uint8_t *pTxBuffPtr; /* 指向 UART 发送缓冲区 */
uint16_t TxXferSize; /* UART 发送数据的大小 */
__IO uint16_t TxXferCount; /* UART 发送数据的个数 */
uint8_t *pRxBuffPtr; /* 指向 UART 接收缓冲区 */
uint16_t RxXferSize; /* UART 接收数据大小 */
__IO uint16_t RxXferCount; /* UART 接收数据的个数 */
DMA_HandleTypeDef *hdmatx; /* UART 发送参数设置(DMA) */
DMA_HandleTypeDef *hdmarx; /* UART 接收参数设置(DMA) */
HAL_LockTypeDef Lock; /* 锁定对象 */
__IO HAL_UART_StateTypeDef gState; /* UART 发送状态结构体 */
__IO HAL_UART_StateTypeDef RxState; /* UART 接收状态结构体 */
__IO uint32_t ErrorCode; /* UART 操作错误信息 */
}UART_HandleTypeDef;
typedef struct
{
uint32_t BaudRate; /* 波特率 */
uint32_t WordLength; /* 字长 */
uint32_t StopBits; /* 停止位 */
uint32_t Parity; /* 校验位 */
uint32_t Mode; /* UART 模式 */
uint32_t HwFlowCtl; /* 硬件流设置 */
uint32_t OverSampling; /* 过采样设置 */
}UART_InitTypeDef;
typedef enum
{
HAL_OK = 0x00U,//初始化完成
HAL_ERROR = 0x01U,//初始化错误
HAL_BUSY = 0x02U,//忙
HAL_TIMEOUT = 0x03U //超时
} HAL_StatusTypeDef;
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);//用于开启以中断(干完了跟我说,中途可以干其他事情)的方式接收指定字节。数据接收在中断处理函数里面实现。
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);//用阻塞(干不完不准出来)的方式发送指定字节数据
void HAL_UART_MspInit(UART_HandleTypeDef *huart) /* 串口MSP回调函数 */
HAL库对USART的初始化流程
uint8_t g_rx_buffer[1]; /* HAL库使用的串口接收数据缓冲区 */
uint8_t g_usart1_rx_flag = 0; /* 串口接收到数据标志 */
UART_HandleTypeDef g_uart1_handle; /* UART句柄 */
/* 串口1初始化函数 */
void usart_init(uint32_t baudrate)
{
g_uart1_handle.Instance = USART1;
g_uart1_handle.Init.BaudRate = baudrate;
g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
g_uart1_handle.Init.StopBits = UART_STOPBITS_1;
g_uart1_handle.Init.Parity = UART_PARITY_NONE;
g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
g_uart1_handle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&g_uart1_handle);
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}
/* 串口MSP回调函数 HAL_UART_MspInit 函数来完成对串口底层的初始化,包括:串口
及 GPIO 时钟使能、GPIO 模式设置、中断设置等。 */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef gpio_init_struct;
if(huart->Instance == USART1) /* 如果是串口1,进行串口1 MSP初始化 */
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_9;
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽式复用输出 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的TX引脚 */
gpio_init_struct.Pin = GPIO_PIN_10;
gpio_init_struct.Mode = GPIO_MODE_AF_INPUT; /* 输入 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
HAL_GPIO_Init(GPIOA, &gpio_init_struct); /* 初始化串口1的RX引脚 */
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
/* 串口1中断服务函数 */
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&g_uart1_handle);//这个函数会清除中断
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);//重新使能
}
/* 串口数据接收完成回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
g_usart1_rx_flag = 1;
}
}
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
led_init(); /* 初始化LED */
usart_init(115200); /* 波特率设为115200 */
printf("请输入一个英文字符:\r\n\r\n");
while(1)
{
if(g_usart1_rx_flag == 1)//判断串口接收到数据标志
{
printf("您输入的字符为:\r\n");
HAL_UART_Transmit(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1, 1000);
while(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_TC) != 1);
printf("\r\n");
g_usart1_rx_flag = 0;
}
else
{
delay_ms(10);
}
}
}
三.cubeMX配置USART
Asynchronous 异步 Synchronous 同步 single wire 单线 IrDA 红外数据传输
参数配置
使能和配置中断
HAL_UART_Transmit();串口发送数据,使用超时管理机制
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
发送数据是主观上的,所以用HAL_UART_Transmit();,接收数据是被动的,一般利用中断完成接收。
//stm32f1xx_it.c里面有中断服务函数的代码(可以配置各部分的中断服务函数)
uint8_t StaMessages[] = "Please enter 10 characters:\r\n";
uint8_t RxBuffer[20];
int main(void)
{
/*其余代码省略*/
MX_GPIO_Init();
MX_USART1_UART_Init();
HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)StaMessages,sizeof(StaMessages));
//发送完成产生中断,执行中断回调
HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);
while(1){}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
HAL_UART_Transmit(&huart1,(uint8_t*)RxBuffer,10,0xFFFF);
HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);//重新使能
}
四.制定协议