stm32使用usart1串口通信以及truestudio重定向printf踩的坑
2019-07-23 来源:eefocus
刚接触stm32,这些天一直被stm32的串口通信困扰,先是收不到数据,后来收到数据了但printf函数不能通过串口发送到上位机。问题来自于多方面,有硬件上的也有软件上的,我在这里总结一下,希望能对大家有帮助避免踩坑。
我使用的是stm32f103rct6的板子,使用hal库在turestudio9.3环境下开发,主机是ubuntu18系统。
硬件问题:
1、有一个usb转ttl线有问题,短接rx和tx后,用cutecom发送和接收的数据会不一致,换成其他线则没问题。
2、usb转ttl线的rx端要接stm32板子的rx端,usb转ttl线的rx端接板子的tx端,我之前刚好是rx-rx、tx-tx,因些收不到数据。
软件问题:
1、系统时钟没配好,这个不是很确定,刚开始对时钟树不太懂,就按stm32cubemx默认生成的,后来网上查了很多资料说是先配好时钟,就又研究了一番把时钟配好了。记的是硬件问题排除完之后,同时系统时钟也重新配置好才收到了串口数据。
2、printf的重定向问题是困扰我最久的,printf的调用流程是先调用_write函数,再调用__io_putchar或fputc函数(根据是否定义__GNUC__),所以要重写这些函数,把输出的内容通过串口发送出来,下面是代码,要把这些代码加入到项目中,我用的最新的truestudio版本,系统自动生成了syscalls.c,如果没有的话,要手动生成,在新建菜单项里。
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
int _write(int32_t file, uint8_t *ptr, int32_t len)
{
/* Implement your write code here, this is used by puts and printf for example */
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
/* return len; */
}
3、把上面这里全做完之后,printf还是不能通过串口发送数据,最后要做的是在打印的字符串最后要加上“rn”,我估计stm32里的printf是通过回车换行符确定打印结尾的,如果不加这两个数据会先缓存在发送缓冲里,等收到这两个字符后,一起发送的。
4、打印浮点数,打开Properties->C/C++ Build->Settings->Tool Settings->C Linker->Miscellaneous,在other options输入框里填写-u _printf_float。
到这里就可以使用printf通过串口发送数据给上位机了!好坑啊!