STM32HAL库CubeMx——UART DMA串口 空闲中断的使用

目录

一、前期准备:

  • CubeMx软件;
  • Keil或MDK;
  • STM32F103C8T6;(Ps:其他型号单片机也行,STM32的型号用起来都差不多)

二、配置CubeMX部分:

1.配置烧录方式:

在这里插入图片描述

2.选择外部晶振:

在这里插入图片描述

3.配置时钟树:

  • 这里可以在72Mhz max那里直接输入72M然后选择自动配置时钟。
    在这里插入图片描述

4.配置串口:

  • 默认就是115200,其他设置一般不用动,默认就好。

    在这里插入图片描述

5.配置工程文件生成:

  • 设置好工程名称和路径,注意:步骤4那里需要看自己的IDE设置,我用的是Keil所以选MDK-ARM。

在这里插入图片描述

  • 第一栏选择只复制需要用到的库文件;
  • 第二栏选择生成单独的.c/.h文件;

在这里插入图片描述

  • 点击右上角生成即可;

在这里插入图片描述

  • 生成成功,打开工程;

在这里插入图片描述

三、代码部分:

1、串口printf输出:

  • 勾选Use Micro LIB;

在这里插入图片描述

  • 勾选Reset and Run,这样程序下载后可以自动重启;

在这里插入图片描述

  • 在main.h文件添加 #include <stdio.h>

在这里插入图片描述

  • main.c文件加入printf重定向函数;这里注意,如果你是串口1就用和我一样的&huart1,串口2就用&huart2,以此推类。
/* Redirect printf function */
int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
    return (ch);
}

在这里插入图片描述

  • while循环中加入延时和串口打印;

在这里插入图片描述

  • 串口成功打印;

在这里插入图片描述

2、串口接收中断配置:

  • 打开串口中断;并且重新生成一下代码;

在这里插入图片描述

  • 定义一个接收字符的变量;初始化的时候开启串口接收中断;
HAL_UART_Receive_IT(&huart1, &Rx1ch, 1);

在这里插入图片描述
在这里插入图片描述

  • main.c文件中加入串口接收中断处理函数,这里中断的功能是收到什么就回什么。最后记得要再重新开启一下串口接收中断;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    if (huart->Instance == USART1)
    {
        // HAL_UART_Transmit(&huart1, &Rx1ch, 1, 100);
        huart1.Instance->DR = Rx1ch;    /* 这里建议直接操作寄存器,不然速度慢,容易丢包 */
        HAL_UART_Receive_IT(&huart1, &Rx1ch, 1); // 因为接收中断使用了一次即关闭,所以在最后加入这行代码即可实现无限使用
    }
}
  • 编译运行,可以看到我们发送"Troubadour1-Troubadour2-Troubadou3",单片机返回同样的数据;

在这里插入图片描述

3、DMA+串口空闲中断配置:

  • CubeMX中添加DMA,速度设置最大,最后生成代码;

在这里插入图片描述

  • 把之前串口接收中断的代码注释掉或者删除,加上以下变量和DMA数据处理的代码:
#define UART_RX1_BUFFSIZE       (1024)

extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;

uint8_t Uart1Flag = 0;
uint8_t Uart1_RxBuff[UART_RX1_BUFFSIZE] = {0};
uint8_t Uart1_Data[UART_RX1_BUFFSIZE] = {0};
uint16_t uartCnt = 0;

/* uart IDLE DMAHandler interrupt */
void USART1_DMAHandler(void)
{
    if (RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) // 判断是否是空闲中断
    {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);                                     // 清除空闲中断标志
        HAL_UART_DMAStop(&huart1);                                              // 停止本次DMA传输
        uartCnt = UART_RX1_BUFFSIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 计算接收到的数据长度
        memcpy(Uart1_Data, Uart1_RxBuff, uartCnt);
        Uart1Flag = 1;
        HAL_UART_Receive_DMA(&huart1, (uint8_t *)Uart1_RxBuff, UART_RX1_BUFFSIZE); // 重启开始DMA传输
    }
}

在这里插入图片描述

  • 主函数里面把串口接收中断的部分删掉,加入空闲中断和使能DMA;while循环中检查DMA接收完成后的标志位,一旦接受完一帧数据就将这帧数据发送出去。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);    /* 开启串口空闲中断 */
HAL_UART_Receive_DMA(&huart1, (uint8_t*)Uart1_RxBuff, UART_RX1_BUFFSIZE);   /* 开启DMA传输 */

while (1)
{
    if (Uart1Flag)
    {
    Uart1Flag = 0;
    HAL_UART_Transmit(&huart1, Uart1_Data, uartCnt, 1000);  /* 将接收到的数据发送出去 */
    }
}

在这里插入图片描述

  • 最后去到stm32f1xx_it.c文件中,在串口中断函数中调用刚才添加的DMA数据处理函数,记得在这个文件声明外部调用此函数;

在这里插入图片描述
在这里插入图片描述

  • 编译运行,看看效果;这里用出师表试试,收发都没问题。

在这里插入图片描述

  • 16
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Troubadour~

觉得不错,打赏支持一下!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值