项目场景:
stm32单片机printf输出打印是,使用了mx485芯片输出。
问题分析
由于485多了一个收发控制开关每次在收发的时候都需要切换。
485在数据量传输过程中,在对寄存器写前打开485发送,写后关闭发送。而使用了printf输出,每次都是一个一个字节的发送。
这里由于收发控制位频繁的在切换,收到的数据会丢失,出现乱码。由于单片机到485芯片之间的数据传输需要一定的时间,在单片机发送完成后,485未必完成了转换并发送完成,这个时候单片机就进行收发切换,会导致每个字节最后的一位会丢失,出现乱码的现象。这里就需要单片机进行一定的延时后再切换485的收发。
printf重定向后的代码
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
PUTCHAR_PROTOTYPE
{
P_485RW(1);//485写
USART_SendData(PRINT_USARTx, (unsigned char) ch);// 发送
while (!(PRINT_USARTx->SR & USART_FLAG_TXE));//数据传输完毕
P_485RW(0);//485读
return ch;
}
解决方案:
解决方案:在寄存器发送完成后,再打开usart的发送中断(
USART_IT_TC
),这样可以到串口中断里去处理485收发切换。
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
PUTCHAR_PROTOTYPE
{
P_485RW(1);//485写
USART_SendData(PRINT_USARTx, (unsigned char) ch);
while (!(PRINT_USARTx->SR & USART_FLAG_TXE));//数据传输完毕
USART_ITConfig(PRINT_USARTx,USART_IT_TC,ENABLE);
return ch;
}
void PRINT_USARTx_IRQHandler(void)
{
if(USART_GetITStatus(PRINT_USARTx, USART_IT_TC) != RESET)//串口发送中断
{
// USART_ClearITPendingBit(PRINT_USARTx, USART_IT_TC);
// USART_ClearFlag(PRINT_USARTx,USART_IT_TC);
//关闭发送完成中断
USART_ITConfig(PRINT_USARTx, USART_IT_TC, DISABLE);//关闭发送
USART_ITConfig(PRINT_USARTx, USART_IT_RXNE, ENABLE);//使能接收脚
P_485RW(0);//485读
}
}
由于多了一步串口的操作,确认了单片机TDR寄存器的数据发到移位寄存器中,并且移位寄存器已经发送完成(USART_IT_TC
置"1")。这个时候再关闭发送中断,关闭485发送。