stm32使用usart1串口通信以及truestudio重定向printf踩的坑

剛接觸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還是不能通過串口發送數據,最後要做的是在打印的字符串最後要加上“\r\n”,我估計stm32裏的printf是通過回車換行符確定打印結尾的,如果不加這兩個數據會先緩存在發送緩衝裏,等收到這兩個字符後,一起發送的。

4、打印浮點數,打開Properties->C/C++ Build->Settings->Tool Settings->C Linker->Miscellaneous,在other options輸入框裏填寫-u _printf_float。

到這裏就可以使用printf通過串口發送數據給上位機了!好坑啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章