目录
UART传输方式
UART(Universal Asynchronous Receiver Transmitter),异步串口没有时钟信号,也没有硬件控制流信号。只有Tx(串行输出信号)与Rx(串行输入信号)。
在STM32F407中,串口数据传输有两种方式:阻塞与非阻塞。
1)阻塞:轮询的方式,就是发送缓冲器的数据,直到数据传输完成或者超时后,函数才返回;
2)非阻塞:启动发送缓冲区数据后,立即返回,传输完成后可以触发中断。
注:在51单片机中的UART通方式类似,也是通常使用阻塞发送数据, 而非阻塞通常用来接收数据。
PC端与STM32进行串口通讯
在当前的PC(个人电脑),基本上已将不支持串口了。因此需要PC端与STM32开发板进行UART通讯,需要将串口转换为USB信号(PC接收-RX)以及USB转串口(PC发送-TX),通过虚拟串口的方式进行通讯。STM32 的PA9、PA10分别作为UART_TX ,UART_RX与 CHG340的RXD,TXD连接。
CHG340 | STM32 |
RXD | PA9(UART_TX) |
TDX | PA10(UART_RX) |
注:如果开发板上没有串口与USB转换的电路,可以在某宝购买一条串口线。串口线上带有串口与USB转换的电路即可。
STM32CubeMx配置UART1
开启UART
设置通讯参数
设置中断
因为我们不知道PC什么时候会发送数据过来,因此设置中断用于Rx中断接收。当然我们也可以用来触发STM32发送数据完成,但通常我们的串口中断用于Rx接收,TX则是阻塞发送即可。
代码功能实现
PC发STM32发送字符‘1’,STM32收到后对LED1进行翻转,并且向PC发送串口数据“LED 翻转”。
因此使用UART中断接收PC的字符,判断字符是否为1,然后使用阻塞串口函数发送“LED 翻转”。
SMT32Cube自动生成的串口初始化
自定义变量
定义接收变量,接收上位机发送的数据。当然啦,很多时候用数组。这个例子为了简单。
自添加UART中断接收
main函数中需要开启串口中断接收
重写UART回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1 )
{
if( '1' == rxBuff)//如果接收到字符1
{
LED1_Toggle();
HAL_UART_Transmit(&huart1, (uint8_t *)"LED1 翻转 \r\n",12,100); //"LED1 翻转 \r\n" 12个字符
}
}
HAL_UART_Receive_IT(&huart1,&rxBuff,1); //重新开启中断
}
串口调试助手设置
1)串口调试助手的参数需要与串口初始化的代码参数一致(按默认就行);
2)当点击发送“1” 时,就可以看到LED翻转,并且会接收框中会接收到STM32发送过来的数据;
3)如果我们设置了定时发送,就可以看到LED每隔1s翻转一次。
printf串口重定向
使用sprintf函数格式化字符串与HAL_UART_Transmit函数 可以通过阻塞的方式向PC端发送格式化的字符串数据,但是我们可以使用更简单的方法,就是使用printf函数直接发送数据给PC端,为了达到这个目的,可以重定向printf。
printf函数调用了fputc,也就是说我们改写该函数即可。在usart.c中添加以下代码。
/* USER CODE BEGIN 1 */
#ifdef __GNUC__
/* With GCC/RAISONANCE, 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__ */
struct __FILE
{
int handle;
};
FILE __stdout;
/**
* @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 EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 1 */