使能串口,设置如下
打开串口中断
预先定义接受数据缓存,rx_buf[MAX_LEN]
在代码开始处使用
HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t*)rx_buf_1,sizeof(rx_buf_1)-1);
该语句将中断地检测串口总线是否空闲,如果数据传输完成后,总线便会空闲,从而进入回调函数(void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)),由此避开了定长接受的问题。
由于该回调函数是弱定义,所以我们可以在任何地方重写回调函数,重写如下
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart==&huart1)
{
rx_buf_1[Size] = '\0';
osMessageQueuePut(myQueue01Handle,rx_buf_1,NULL,0);
HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t*)rx_buf_1,sizeof(rx_buf_1)-1);
}
}
该回调函数被调用时,会传回该数据流的长度,在数据流末尾处加入‘\0’,形成合法的字符串,
最后再次调用HAL_UARTEx_ReceiveToIdle_IT()函数重新检测总线空闲,继而实现串口接受功能。在此处的osMessageQueuePut函数可以理解为用来像其他任务发送“已经完整接受数据串”的信号,其他任务收到该信号也能开始处理数据串了。
我这里处理数据串是这样写的
if(osMessageQueueGet(myQueue01Handle,buf_1,NULL,10)==osOK)
{
/*处理数据串*/
}
我这里的消息队列长度为1,单个数据内存占100个字节,所以osMessageQueuePut函数将100个字符放入消息队列,接受时也是将100个字节取出。
下面说一下发送
发送一般就是使用HAL_UART_Transmit或HAL_UART_Transmit_IT.
这里特别说一下重定向,可以直接使用printf进行发送。
在任意处可以加入以下代码
先包含头文件#include"stdio.h",加入以下代码
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1, (uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
int fgetc(FILE *f){
uint8_t ch;
HAL_UART_Receive(&huart1, (uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
之后勾选USB_MicroLIB
多串口的使用
可以将任意串口当作类似于printf使用
#include <stdarg.h>
void usartx_printf(const char *format,...)
{
va_list args;
uint32_t length;
uint8_t txbuf[MAXLEN] = {0};
va_start(args, format);
length = vsnprintf((char *)txbuf, sizeof(txbuf), (char *)format, args);
va_end(args);
HAL_UART_Transmit(&huartx, (uint8_t *)txbuf, length, HAL_MAX_DELAY);
memset(txbuf, 0, MAXLEN);
}