大致有以下几个步骤
1 串口输出重定义
需要重定义一下fputc
int fputc(int ch, FILE *f) //重定义串口输出,即printf()
{
while((USART1->ISR & 0X40) == 0);//循环发送,直到发送完毕
USART1->TDR=(u8)ch;
}
如果有多个串口,则需要判断一下:
u8 usart_cur_flag;
int fputc(int ch, FILE *f) //重定义串口输出,即printf()
{
if (usart_cur_flag == 1)
{ //连电脑调试
while((USART1->ISR & 0X40) == 0);//循环发送,直到发送完毕
USART1->TDR=(u8)ch;
}
else if (usart_cur_flag == 2)
{ // WIFI
while((USART2->ISR & 0X40) == 0);//循环发送,直到发送完毕
USART2->TDR=(u8)ch;
}
}
并在调用printf之前先设置相应的串口标识 usart_cur_flag。
当然,波特率啥的要先设置好。
此时串口就可以输出数据了。
2 开启中断,以接收数据
HAL_UART_Receive_IT(&huart1, data1, 1);
HAL_UART_Receive_IT(&huart2, data2, 1);
现在串口可以在中断中接收数据了
但是,现在只能接收1个字节,进1次中断。
3 在串口中断中重新使能中断
在串口中断中取出RDR的 数据,并重新使能串口中断
receive_char = huart1.Instance->RDR;
存放到别的数组啥的自己搞一下
重新使能接收中断,下面2句都需要
huart1.Instance->CR1 |= USART_CR1_PEIE;
huart1.Instance->CR1 |= USART_CR1_RXNEIE;
现在可以接收多个字节了。
4 超时定时器
现在虽然可以接收多个字节,但是什么时候算是接收完成呢?
以波特率115200为例,每一位需要8.68us,一个字节加上起始停止位,需要86.8us,4舍5入按100us算,取10个字节间隙,那就是1ms。即10个字节的时间还没收到数据,就认为这一波数据发送结束。
由于串口中断的优先级较低,在发送数据时,有可能被其他的中断函数打断,为此也可以设置更长的超时时间。
设置超时定时器,周期设置为1ms,不设置自动重装载。在其中断函数内设置接收完成的标志,然后在主程序中查询这个标志,一旦置位,就代表一波数据接收完成