发新帖我要提问
123
返回列表
打印
[STM32F4]

UART串口通信详解

[复制链接]
楼主: 突然下起雨
手机看帖
扫描二维码
随时随地手机跟帖
41
突然下起雨|  楼主 | 2022-11-17 13:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
串口查询函数

  HAL_UART_GetState();  判断UART的接收是否结束,或者发送数据是否忙碌

  举例:     

while(HAL_UART_GetState(&huart4) == HAL_UART_STATE_BUSY_TX)   //检测UART发送结束

使用特权

评论回复
42
突然下起雨|  楼主 | 2022-11-17 13:28 | 只看该作者
USART接收与发送



重新定义printf函数

在 stm32f4xx_hal.c中包含#include <stdio.h>
#include "stm32f4xx_hal.h"
#include <stdio.h>
extern UART_HandleTypeDef huart1;   //声明串口

使用特权

评论回复
43
突然下起雨|  楼主 | 2022-11-17 13:29 | 只看该作者
在 stm32f4xx_hal.c 中重写fget和fput函数
/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

使用特权

评论回复
44
突然下起雨|  楼主 | 2022-11-17 13:31 | 只看该作者
在main.c中添加
#define RXBUFFERSIZE  256
char RxBuffer[RXBUFFERSIZE];

使用特权

评论回复
45
突然下起雨|  楼主 | 2022-11-17 13:32 | 只看该作者

  while (1)
  {
    /* USER CODE END WHILE */
                        printf("Z小旋测试\n");
                        HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }

使用特权

评论回复
46
突然下起雨|  楼主 | 2022-11-17 13:37 | 只看该作者
本帖最后由 突然下起雨 于 2022-11-17 13:55 编辑

之后便可以使用Printf函数和Scanf,getchar函数

使用特权

评论回复
47
突然下起雨|  楼主 | 2022-11-17 13:38 | 只看该作者
UART接收中断

因为中断接收函数只能触发一次接收中断,所以我们需要在中断回调函数中再调用一次中断接收函数

具体流程:

1、初始化串口

2、在main中第一次调用接收中断函数

3、进入接收中断,接收完数据  进入中断回调函数

4、修改HAL_UART_RxCpltCallback中断回调函数,处理接收的数据,

5  回调函数中要调用一次HAL_UART_Receive_IT函数,使得程序可以重新触发接收中断

使用特权

评论回复
48
突然下起雨|  楼主 | 2022-11-17 13:40 | 只看该作者
函数流程图:

HAL_UART_Receive_IT(中断接收函数)    ->  USART2_IRQHandler(void)(中断服务函数)    ->    HAL_UART_IRQHandler(UART_HandleTypeDef *huart)(中断处理函数)    ->    UART_Receive_IT(UART_HandleTypeDef *huart) (接收函数)   ->    HAL_UART_RxCpltCallback(huart);(中断回调函数)

HAL_UART_RxCpltCallback函数就是用户要重写在main.c里的回调函数。

使用特权

评论回复
49
突然下起雨|  楼主 | 2022-11-17 13:41 | 只看该作者
代码实现:

    并在main.c中添加下列定义:

#include <string.h>

#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;                        //接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;                //接收缓冲计数

使用特权

评论回复
50
突然下起雨|  楼主 | 2022-11-17 13:42 | 只看该作者
在main()主函数中,调用一次接收中断函数

/* USER CODE BEGIN 2 */
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */

使用特权

评论回复
51
突然下起雨|  楼主 | 2022-11-17 13:43 | 只看该作者
在main.c下方添加中断回调函数

/* USER CODE BEGIN 4 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */

        if(Uart1_Rx_Cnt >= 255)  //溢出判断
        {
                Uart1_Rx_Cnt = 0;
                memset(RxBuffer,0x00,sizeof(RxBuffer));
                HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);        
        
        }
        else
        {
                RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;   //接收数据转存
       
                if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
                {
                        HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
            while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
                        Uart1_Rx_Cnt = 0;
                        memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
                }
        }
       
        HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}
/* USER CODE END 4 */

使用特权

评论回复
52
突然下起雨|  楼主 | 2022-11-17 13:44 | 只看该作者
本帖最后由 突然下起雨 于 2022-11-17 13:54 编辑

发送数据被正常返回

使用特权

评论回复
53
OKAKAKO| | 2024-6-25 15:53 | 只看该作者
配置、程序ST的生态非常完善

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则