STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收

参考资料:1、ST HAL库官网资料

                  2、https://blog.csdn.net/u014470361/article/details/79206352#comments

 

一、STM32CubeMX配置外部时钟

注意在进行外部时钟配置时,即“High Speed Clock”和“Low Speed Clock”需配置成“Crytal/Ceramic Resonator(低温/陶瓷谐振器)”不能配置为"BYASS Clock Source(时钟脉冲源)",否则系统起不来。

 

 

二、SWD下载接口配置

如果用HAL库不进行SWD或JTAG配置,单片机只能进行下载一次程序,要进行第二次或更多次程序下载,需要按复位键(如果你的单片机有复位按键的话),或者用镊子夹住复位线路上的电容使其短路,点击Keil下载,再松开镊子。

 

三、串口1(USART1)配置

 

四、时钟树配置(外部低速晶振32.768kHz,外部高速晶振8MHz)

 

 

五、串口DMA配置

 

六、软件配置

#define BUFFER_SIZE  100

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma;

uint8_t rx_len = 0;             //接收一帧数据的长度
uint8_t recv_end_flag = 0;    //一帧数据接收完成标志
uint8_t rx_buffer[100]={0};   //接收数据缓存

/*
*********************************************************************************************************
*    函 数 名: MX_GPIO_Init
*    功能说明: /GPIO时钟初始化函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void MX_GPIO_Init(void)  //GPIO时钟初始化
{
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
}

/*
*********************************************************************************************************
*    函 数 名: MX_DMA_Init
*    功能说明: 串口DMA时钟初始化函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
  /* DMA2_Stream7_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}


/*
*********************************************************************************************************
*    函 数 名: MX_USART1_UART_Init
*    功能说明: 串口功能初始化函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void MX_USART1_UART_Init(void)             //串口初始化
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;                     //波特率
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }    
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);          //使能IDLE中断
    HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//使能接收中断
}

/*
*********************************************************************************************************
*    函 数 名: HAL_UART_MspInit
*    功能说明: 串口DMA功能初始化函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    /**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 DMA Init */
    /* USART1_TX Init */
    hdma_usart1_tx.Instance = DMA2_Stream7;
    hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_tx.Init.Mode = DMA_NORMAL;
    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);

    /* USART1_RX Init */
    hdma_usart1_rx.Instance = DMA2_Stream2;
    hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_NORMAL;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }

    __HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
}

/*
*********************************************************************************************************
*    函 数 名: DMA_Usart_Send
*    功能说明: 串口发送功能函数
*    形    参: buf,len
*    返 回 值: 无
*********************************************************************************************************
*/
void DMA_Usart_Send(uint8_t *buf,uint8_t len)//串口发送封装
{
   if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK)
        {
            Error_Handler();
        }
    /*##-3- Wait for the end of the transfer ###################################*/  
    while (UartReady != SET){}
    /* Reset transmission flag */
    UartReady = RESET;
}

/*
*********************************************************************************************************
*    函 数 名: DMA_Usart1_Read
*    功能说明: 串口接收功能函数
*    形    参: Data,len
*    返 回 值: 无
*********************************************************************************************************
*/
void DMA_Usart1_Read(uint8_t *Data,uint8_t len)//串口接收封装
{
   HAL_UART_Receive_DMA(&huart1,Data,len);//重新打开DMA接收
}

/*
*********************************************************************************************************
*    函 数 名:main
*    功能说明: main主函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  
  while (1)
  {
    if(recv_end_flag == 1)   //接收完成标志
    {
        DMA_Usart_Send(rx_buffer, rx_len);
        rx_len = 0;//清除计数
        recv_end_flag = 0;//清除接收结束标志位
        memset(rx_buffer,0,sizeof(rx_buffer));
    }    
  }
}

/*
*********************************************************************************************************
*    函 数 名:DMA2_Stream2_IRQHandler
*    功能说明: 串口DMA接收中断函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void DMA2_Stream2_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_usart1_rx);
}

/*
*********************************************************************************************************
*    函 数 名:DMA2_Stream7_IRQHandler
*    功能说明: 串口DMA发送中断函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void DMA2_Stream7_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_usart1_tx);
}


/*
*********************************************************************************************************
*    函 数 名:USART1_IRQHandler
*    功能说明: 串口中断函数
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
void USART1_IRQHandler(void)    //串口中断
{
    uint32_t tmp_flag = 0;
    uint32_t temp;
    
    HAL_UART_IRQHandler(&huart1);
    if(USART1 == huart1.Instance){
        tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
            
        if((tmp_flag != RESET))//idle标志被置位
        { 
            recv_end_flag = 1;  // 接受完成标志位置1 
            __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位     
            HAL_UART_DMAStop(&huart1); //                     
            temp = UartHandle.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
            temp = UartHandle.Instance->DR; //读取数据寄存器中的数据
            temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数                     
            rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
               
            HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
        }
    }

 

 

七、串口调试助手打印

 

 

下面链接可下载具体的源码:

https://download.csdn.net/download/euxnijuoh/10606293,写的不好,请见谅!

转载于:https://www.cnblogs.com/jinxueHou/p/9483413.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈自记忆函数

浅谈自记忆函数 最近阅读《JavaScript忍者秘籍》看到了一种有趣的函数:自记忆函数。 简介 何为自记忆函数?书中提到: 记忆化(memoization)是一种构建函数的处理过程,能够记住上次计算结果 通过这句话可以…

pyqt5 qlabel无法显示图片_实战PyQt5: 011-单选框控件QRadioButton

单选框QRadioButton简介QRadioButton为单选按钮, 可以选中(打开)或者取消选中(关闭)。在一组单选按钮中,一次只能选中其中的一个按钮。选中或者取消选中QRadioButton, 都会发出toggled()信号。使用isChecked()可以查看是否选择了某个QRadioBu…

matlab数据游标不能使用,启用数据游标模式

文本解释器,指定为下列值之一:tex - 使用 TeX 标记子集解释字符。latex - 使用 LaTeX 标记解释字符。none - 显示字面字符。TeX 标记默认情况下,MATLAB 支持一部分 TeX 标记。使用 TeX 标记可添加下标和上标,修改字体类型和颜色&a…

MySQL 快速定位性能问题

一、性能查看几款小工具:Top 查看:观察 load average :1分钟,5分钟,15分钟的平均负载值1. us% 用户使用的 CPU 占比,如果 us% 太高, 极有可能索引使用不当。2. sy% 系统内核使用的CPU占比&#…

使用Google GSON:额外的赠品:第二部分

如果您错过了系列的第一篇文章 ,我们将继续上一篇文章的“使用GSON ” ,这里是link 。 因此,这里我们进行另一系列的讨论。 版本支持 如果要维护一个对象的多个版本以进行JSON转换,则Google GSON库具有不错的Since注释。 该注释可…

Python开发【第2节】【Python运算符】

Python语言支持以下类型的运算符: 算术运算符比较(关系)运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级1、算术运算符 假设变量a 10,变量b 21: 运算符描述实例加 - 两个对象相加a b 输出结果 31-减 - 得…

mybatis-plus分页查询_SpringBoot + MyBatisPlus 快速入门

Hello,大家好!前面与大家分享了一次如何搭建Java项目脚手架,并且送给大家一个基础项目模板。那今天与大家分享如何使用这个基础项目,也就是快速上手 SpringBoots ➕ MyBatisPlus。 项目 / 目录结构 天津商业大学学院信息 这是一张天津商业大学…

php 获取每年的节假日,shell获取每年农历节日的日期

原创内容,转载请注明出处:https://www.myzhenai.com.cn/post/3711.html我打算自己写一个每年节日就自动在网站上展示灯笼的源码功能,但是这里最重要的是要获得每年春节、端午节、中秋节等节日的日期,因为要自己写这判断这些日期的…

AJAX跨域问题解决方法(1)——禁止浏览器进行跨域限制

思路:通过命令行修改浏览器启动参数,使得浏览器不进行跨域检查,从而允许跨域 方法:命令行参数启动浏览器后添加参数--disable-web-security 例:chrome --disable-web-security --disabl-web-security参数的作用是禁…

Android Studio 管理所有程序退出

import android.app.Activity; import java.util.ArrayList; import java.util.List;public class fa {public static List<Activity> activitieanew ArrayList<>();public static void add(Activity act){activitiea.add(act);//在创建活动是加入}public static v…

项目学生:Web服务集成

这是Project Student的一部分。 其他职位包括带有Jersey的 Web服务 客户端&#xff0c;带有Jersey的 Web服务服务器 &#xff0c; 业务层 &#xff0c; 具有Spring数据的持久性和分片集成测试数据 。 早些时候&#xff0c;我们成功地针对持久性/业务层&#xff08;使用嵌入式H…

python爬虫requests实战_Python爬虫之requests库网络爬取简单实战

实例1&#xff1a;直接爬取网页 实例2 &#xff1a; 构造headers&#xff0c;突破访问限制&#xff0c;模拟浏览器爬取网页 实例3 &#xff1a; 分析请求参数&#xff0c;构造请求参数爬取所需网页 实例4&#xff1a; 爬取图片 实例5&#xff1a; 分析请求参数&#xff0c;构造…

某制冷设备制造厂商

某制冷设备制造厂商 该公司是一家以钣金加工&#xff0c;制冷设备制造、销售为主的公司&#xff0c;其产品广泛应用于高级宾馆、饭店及大型餐饮设施等。销售网点遍及日本、北美、欧洲及东南亚&#xff0c;产品深受世界各地用户的欢迎。 该公司原先使用的是TPICS生产管理系统&am…

原生JS实现的DOM操作笔记(草稿整理)

原生JS实现的DOM一系列操作参考&#xff1a; 原生JavaScript封装DOM库siblings: 原生JS-查找相邻的元素-siblings方法的实现addClass,removeClass,hasClass,toggleClass&#xff1a;原生js添加删除class原生js添加删除class 代码如下&#xff1a; var dom {/** 功能说明&…

简单的Gradle Java插件自定义

正如我在“ 用Gradle构建Java的初步了解”一文中所展示的那样&#xff0c;当人们使用Java插件并将文件和目录放置在该插件期望的位置时&#xff0c; Gradle尤其适用于构建Java应用程序的基础知识&#xff08;惯例-基于项目的布局 &#xff09;。 但是&#xff0c;并非总是有一种…

k8s 重点

这几个月参与了几场面试&#xff0c;设计了多道面试题&#xff0c;觉得可以综合考察应聘人对 kubernetes的掌握情况。在这里分享下&#xff0c;供应聘人自查以及其他面试官参考。 这些面试题的设计初衷并不是考察 kubernetes 的使用。这种笔者认为较为流于表面&#xff0c;因为…

python中print的用法_python中print用法

print用法 参考文档&#xff1a; https://blog.csdn.net/sinat_28576553/article/details/81154912 目录 一、print()函数概述 二、变量的输出 三、数据的格式化输出 3.1 %字符 3.2 最小字段宽度和精度 3.3 转换标志 3.4 格式字符归纳 四、换行与防止换行 一、print()函数概述 …

java 播放.pcm文件,java播发PCM文件

java播放PCM文件import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioSystem;import javax.sound.sa…

02 re模块

# re的工作是在python中执行正则表达式 import re# # find # result re.findall("\d", "baby的电话号是: 185123456789") # print(result) # # it re.finditer("\d", "baby123456789的电话号是: 185123456789") # for el in it: # …

网页中二维码识别规则

识别规则 这里采用的逻辑是截屏识别&#xff0c;当客户端发现用户在网页的img标签内进行长按操作时&#xff0c;会立刻截屏并且启动二维码识别算法。所以这里用于二维码识别的图片是截屏&#xff0c;而不是之前有人提到的img标签中的图片。 为什么要用截屏&#xff0c;这也是…