打印
[STM32F4]

UART串口通信详解

[复制链接]
楼主: 突然下起雨
手机看帖
扫描二维码
随时随地手机跟帖
21
突然下起雨|  楼主 | 2022-11-17 11:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
举例:    HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,1);   //中断接收一个字符,存储到value中

使用特权

评论回复
22
突然下起雨|  楼主 | 2022-11-17 11:42 | 只看该作者
串口中断函数



HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  //串口中断处理函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);  //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);  //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();串口接收错误函数

使用特权

评论回复
23
突然下起雨|  楼主 | 2022-11-17 11:43 | 只看该作者
串口接收中断回调函数:

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);  

使用特权

评论回复
24
突然下起雨|  楼主 | 2022-11-17 11:44 | 只看该作者
功能:HAL库的中断进行完之后,并不会直接退出,而是会进入中断回调函数中,用户可以在其中设置代码,

           串口中断接收完成之后,会进入该函数,该函数为空函数,用户需自行修改,

使用特权

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

UART_HandleTypeDef *huart      UATR的别名    如 :   UART_HandleTypeDef huart1;   别名就是huart1  
举例:   HAL_UART_RxCpltCallback(&huart1){           //用户设定的代码               }

使用特权

评论回复
26
突然下起雨|  楼主 | 2022-11-17 11:47 | 只看该作者
串口中断处理函数

HAL_UART_IRQHandler(UART_HandleTypeDef *huart);  

使用特权

评论回复
27
突然下起雨|  楼主 | 2022-11-17 11:49 | 只看该作者
功能:对接收到的数据进行判断和处理  判断是发送中断还是接收中断,然后进行数据的发送和接收,在中断服务函数中使用

使用特权

评论回复
28
突然下起雨|  楼主 | 2022-11-17 13:27 | 只看该作者
如果接收数据,则会进行接收中断处理函数

/* UART in mode Receiver ---------------------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  {
    UART_Receive_IT(huart);
  }

使用特权

评论回复
29
突然下起雨|  楼主 | 2022-11-17 13:27 | 只看该作者
如果发送数据,则会进行发送中断处理函数

  /* UART in mode Transmitter ------------------------------------------------*/
  if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
  {
    UART_Transmit_IT(huart);
    return;

使用特权

评论回复
30
突然下起雨|  楼主 | 2022-11-17 13:28 | 只看该作者
串口查询函数

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

  举例:     

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

使用特权

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



重新定义printf函数

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

使用特权

评论回复
32
突然下起雨|  楼主 | 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;
}

使用特权

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

使用特权

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

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

使用特权

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

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

使用特权

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

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

具体流程:

1、初始化串口

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

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

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

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

使用特权

评论回复
37
突然下起雨|  楼主 | 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里的回调函数。

使用特权

评论回复
38
突然下起雨|  楼主 | 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;                //接收缓冲计数

使用特权

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

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

使用特权

评论回复
40
突然下起雨|  楼主 | 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 */

使用特权

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

本版积分规则