一.hal库串口接收发送测试
1、串口的模式有3种,一是查询模式,二是中断模式,三是DMA模式
HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制
HAL_UART_Receive();串口轮询模式接收,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
2、阻塞传输是调用这个函数并在等待时间内一直等待操作完成。
HAL_UART_Transmit
HAL_UART_Receive
查询的方式一般少用,这里不做过多介绍。
3、串口中断
串口中断函数
HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用
HAL_UART_TxCpltCallback();数据完全发送完成后调用
HAL_UART_RxHalfCpltCallback();一半数据接收完成时调用
HAL_UART_RxCpltCallback();数据完全接受完成后调用
HAL_UART_ErrorCallback();传输出现错误时调用
一.在串口中定义相关变量
#define size_max 255
typedef struct uart_date_type
{
uint8_t Rx_date;//接收中断数据变量
uint8_t Uart_RxBuffer[size_max];//接收数据缓存区
uint8_t Uart_RX_Cnt;//接收中断计数
uint8_t Tx_to_RX_Buffer[size_max];//数据提取缓存区
uint8_t Flags;//提取数据标致
uint8_t Recv_end_flag;//结束标志
uint16_t remb_len;//记录实际数据长度
}UART_TP_DATE;
extern UART_TP_DATE U1D;
在main的主循环外开启中断
HAL_UART_Receive_IT(&huart1,&U1D.Rx_date,1);//开启接收中断
串口接收回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(size_max<U1D.Uart_RX_Cnt) //溢出判断
{
U1D.Uart_RX_Cnt = 0;
memset(U1D.Uart_RxBuffer,0,sizeof(U1D.Uart_RxBuffer));//清空缓存,记得#include "string.h"
printf("uart1 buffer full\r\n");
}
else
{
U1D.Uart_RxBuffer[U1D.Uart_RX_Cnt++] = U1D.Rx_date; //接收数据转存
if((U1D.Uart_RxBuffer[U1D.Uart_RX_Cnt-1] == 0x0A)&& (U1D.Uart_RxBuffer[U1D.Uart_RX_Cnt-2] == 0x0D)) //判断结束位
{
//将收到的信息发送出去
U1D.Recv_end_flag = 1; // 接受完成标志位置1
if(U1D.Recv_end_flag == 1) //接收完成标志
{
memcpy(U1D.Tx_to_RX_Buffer,U1D.Uart_RxBuffer,U1D.Uart_RX_Cnt);
U1D.Flags=U1D.Uart_RX_Cnt;
U1D.Recv_end_flag = 0;//清除接收结束标志位
U1D.remb_len=U1D.Uart_RX_Cnt+1;
U1D.Uart_RX_Cnt = 0;
memset(U1D.Uart_RxBuffer,0x00,sizeof(U1D.Uart_RxBuffer)); //清空数组
}
}
}
HAL_UART_Receive_IT(&huart1,&U1D.Rx_date,1);
}
//到这里中断方式的串口接收的数据已存入缓存中完成。
//提取缓存中的数据,传入的数组长度需要大于等于串口的缓存长度
uint8_t get_date(uint8_t *BUF)
{
if(U1D.Flags)
{
memcpy(BUF,U1D.Tx_to_RX_Buffer,U1D.remb_len);
memset(U1D.Tx_to_RX_Buffer,0,U1D.remb_len);
U1D.Flags=0;
return 1;
}
return 0;
}
二.重定向问题
函数版:
/*
* 函数功能: 重定向c库函数printf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
/*
* 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
* 在串口上输入时,最后需要加空格,才能被存储
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
寄存器版:
/*重定向Printf函数*/
int fputc(int ch,FILE *f)
{
return (SendChar(ch));
}
/*重定向Scanf函数*/
int fgetc(FILE *f)
{
return (SendChar(GetKey()));
/*调用scanf()在串口中输入数据时,必须以空格结束,否则无法完成发送*/
}
int SendChar(int ch)
{
while(!(USART1->SR & USART_FLAG_TXE));
USART1->DR = (ch & 0x1FF);
return ch;
}
int GetKey(void)
{
while(!(USART1->SR & USART_FLAG_RXNE));
return ((int)(USART1->DR & 0X1FF));
}
主函数的循环体演示:
实测代码:https://download.csdn.net/download/weixin_44386927/13772536