STM32CubeMX Hal库的一些坑

发布者:ByteChaser最新更新时间:2018-08-19 来源: eefocus关键字:STM32  CubeMX  Hal库 手机看文章 扫描二维码
随时随地手机看文章

使用的是stm32f103 V1.40版本的库


UART DMA发送的问题


发送函数 

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); 

发送完毕之后成功的回调函数也正常,可是再次发送的时候就发不出去了。一直返回错误。 

我们看下这个函数的代码


HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

{

  uint32_t *tmp;

  uint32_t tmp_state = 0;


  tmp_state = huart->State;

  if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))

  {

    if((pData == NULL ) || (Size == 0)) 

    {

      return HAL_ERROR;

    }


    /* Process Locked */

    __HAL_LOCK(huart);


    huart->pTxBuffPtr = pData;

    huart->TxXferSize = Size;

    huart->TxXferCount = Size;


    huart->ErrorCode = HAL_UART_ERROR_NONE;

    /* Check if a receive process is ongoing or not */

    if(huart->State == HAL_UART_STATE_BUSY_RX)

    {

      huart->State = HAL_UART_STATE_BUSY_TX_RX;

    }

    else

    {

      huart->State = HAL_UART_STATE_BUSY_TX;

    }


    /* Set the UART DMA transfer complete callback */

    huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;


    /* Set the UART DMA Half transfer complete callback */

    huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;


    /* Set the DMA error callback */

    huart->hdmatx->XferErrorCallback = UART_DMAError;


    /* Enable the UART transmit DMA channel */

    tmp = (uint32_t*)&pData;

    HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);


    /* Clear the TC flag in the SR register by writing 0 to it */

    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);


    /* Enable the DMA transfer for transmit request by setting the DMAT bit

       in the UART CR3 register */

    SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);


    /* Process Unlocked */

    __HAL_UNLOCK(huart);


    return HAL_OK;

  }

  else

  {

    return HAL_BUSY;

  }

}


代码中可以看出,发送之前先判断状态标志,不是在发送状态才进行发送,这也正常。但是,发送一次之后,状态就被至为发送状态,发送完毕也没有清楚,这就导致了下次再发送,判断为忙,就发不出去了。我们看下他发送成功的处理部分。


static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)     

{

  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;

  /* DMA Normal mode*/

  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )

  {

    huart->TxXferCount = 0;


    /* Disable the DMA transfer for transmit request by setting the DMAT bit

       in the UART CR3 register */

    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);


    /* Enable the UART Transmit Complete Interrupt */    

    __HAL_UART_ENABLE_IT(huart, UART_IT_TC);

  }

  /* DMA Circular mode */

  else

  {

    HAL_UART_TxCpltCallback(huart);

  }

}


代码中可以看到,并没有清除发送的状态,这就导致了下次发送不成功的问题。 

难道要自己发送之前清除一下状态,我想这应该不是库函数的本意。 

我们对比看下接收成功是如何处理的


static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  

{

  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;

  /* DMA Normal mode*/

  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )

  {

    huart->RxXferCount = 0;


    /* Disable the DMA transfer for the receiver request by setting the DMAR bit 

       in the UART CR3 register */

    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);


    /* Check if a transmit process is ongoing or not */

    if(huart->State == HAL_UART_STATE_BUSY_TX_RX) 

    {

      huart->State = HAL_UART_STATE_BUSY_TX;

    }

    else

    {

      huart->State = HAL_UART_STATE_READY;

    }

  }

  HAL_UART_RxCpltCallback(huart);

}


接收成功之后有正确清除状态标志,发送成功应该也是同样的,所以可能是漏掉了。我们加上即可


static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)     

{

  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;

  /* DMA Normal mode*/

  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )

  {

    huart->TxXferCount = 0;


    /* Disable the DMA transfer for transmit request by setting the DMAT bit

       in the UART CR3 register */

    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);


    /* Enable the UART Transmit Complete Interrupt */    

    __HAL_UART_ENABLE_IT(huart, UART_IT_TC);


      /* Check if a transmit process is ongoing or not */

    if(huart->State == HAL_UART_STATE_BUSY_TX_RX) 

    {

      huart->State = HAL_UART_STATE_BUSY_RX;

    }

    else

    {

      huart->State = HAL_UART_STATE_READY;

    }

  }

  /* DMA Circular mode */

  else

  {

    HAL_UART_TxCpltCallback(huart);

  }

}


测试,可以正常发送了····


Flash读写保护


HAL的库flash对比标准库变化还是挺大的,写保护这块需要手动去配置。 

上代码


FLASH_OBProgramInitTypeDef obProgram;


    __HAL_FLASH_PREFETCH_BUFFER_DISABLE();


    HAL_FLASHEx_OBGetConfig(&obProgram);


    if (obProgram.RDPLevel == OB_RDP_LEVEL_0)

    {

        obProgram.OptionType = OPTIONBYTE_WRP;  //读写保护

        obProgram.WRPState = OB_WRPSTATE_ENABLE;    //使能

        obProgram.WRPPage = OB_WRP_ALLPAGES;    //所有页

        obProgram.Banks = FLASH_BANK_1;         

        obProgram.RDPLevel = OB_RDP_LEVEL_1;


        HAL_FLASH_Unlock();

        HAL_FLASH_OB_Unlock();

        HAL_FLASHEx_OBProgram(&obProgram);

        HAL_FLASH_OB_Lock();

        HAL_FLASH_Lock();

    }

    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();


关键字:STM32  CubeMX  Hal库 引用地址:STM32CubeMX Hal库的一些坑

上一篇:结合固件库探讨STM32读写FLASH步骤、HardFault问题
下一篇:STM32 BootLoader升级固件

推荐阅读最新更新时间:2024-03-16 16:11

STM32驱动语音模块播报实时时间
前几天有个学生在用一个语音模块,遇到了点困难,为了方便调试,自己也买了两个一起玩了一下。 今天就来简单分享一下这个模块。 模块概述 DY-SV17F 语音模块,包括IO 分段触发,UART 串口控制, ONE_line 单总线控制,标准 MP3 等 7 种工作模式; 板载 5W D 类功放,可直接驱动 4Ω, 3~5W 喇叭; 支持 MP3,WAV 解码格式; 板载4MBte flash 存储,可通过 USB 数据线连接模块上的MicroUSB接口,电脑可以将模块识别为一个U盘,打开此存储更新音频文件即可。 工作模式配置 硬件连接 原理图 为了测试方便,各位也可以画一个PCB板,这样就可以避免使用一堆杜邦线进
[单片机]
STM32学习:串口通讯
前言 本次通过CubeMx+proteus进行stm32串口仿真 具体功能: 1、开机后,向串口1发送“Welcome” 2、串口1接收字节指令“0xa1 ,打开LED1,回传“LED1 OPEN!” 3、串口1接收字节指令“0xa2 ,关闭LED1,回传“LED1 Close!” 4、在串口发送过程中,打开LED2作为发送数据指示灯 一、相关知识点 二、电路搭建与硬件配置 1、proteus电路搭建 1、COMPIM元件 作用:把仿真电路中的数字量映射到计算机的物理端口 接法:将stm32的TX与COMPIM的TX相连,RX与RX相连,而不是像实物那样交叉相连(RX连TX,TX连RX)。 2、VIRTUAL
[单片机]
<font color='red'>STM32</font>学习:串口通讯
STM32总结一 STM32三种点亮LED灯方式的不同之处
STM32点亮LED灯有很多种方法。 第一种是操作寄存器来点亮LED灯,(以GPIOC的第一个LED为例)操作的方法是首先在中文手册,首先要声明的是,手册里面看到的地址,都是字节,表示第多少多少个字节,然后这个数字对应一个字节位,所以每一个32位的寄存器占四个字节,找到block2(这个是外设区,所有的外设地址都在这个区)的基地址,然后加上第一段偏移地址,就越过APB1总线的内存区,到达了APB2总线这个区的基地址。然后再加上相对于APB2的偏移地址就可以定位出某个特定外设的基地址,这里所指的是GPIOC端口的基地址,然后再在这个端口外设基地址的基础上,加上相应的偏移地址,就可以定义出这个端口的寄存器地址,这些寄存器是紧紧的挨
[单片机]
<font color='red'>STM32</font>总结一 <font color='red'>STM32</font>三种点亮LED灯方式的不同之处
HAL库 STM32CubeMX教程五----看门狗(独立看门狗,窗口看门狗)
前言: 今天我们来学习看门狗的配置与函数,看门狗可以有效解决程序的跑飞,在使用过程中比较常见,是防止芯片故障的有效外设,我们一起来学习下HAL库 STM32CubeMX的独立看门狗,窗口看门狗的使用。本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 知识概括: 通过本篇博客您将学到: STM32CubeMX创建看门狗例程 独立看门狗,靠窗看门狗 工作原理 看门狗 在由单片机构成的微型计算机系统中单片
[单片机]
<font color='red'>HAL库</font> STM32<font color='red'>CubeMX</font>教程五----看门狗(独立看门狗,窗口看门狗)
基于stm32的can总线彻底研究
1、CAN总线的初始化 void can_init(void) { CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; /* CAN register init */ CAN_DeInit(); CAN_StructInit(&CAN_InitStructure); /* CAN cell init */ CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式 CAN_InitStructure.CAN_ABOM=DISA
[单片机]
基于<font color='red'>stm32</font>的can总线彻底研究
STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
一.预备知识 使用51单片机控制IO口相对来说要简单得多,最小系统搭建完毕后直接通过软件往各IO口写“1”或者写“0”即可。但使用STM32控制IO口输入输出却远没有这么容易,经过一个下午的查阅文献及探索后,略微有了头绪。 个人所使用的STM32F103VBT6有100个引脚,其中有五组GPIO(GPIOA…GPIOE),每组有16个GPIO端口(GPIOx_Pin0…GPIOx_Pin15)共80个,每个GPIO端口都有: 两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH); 两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR); 一个32位置位/复位寄存器(GPIOx_BSRR); 一个16位复位寄存器(
[单片机]
<font color='red'>STM32</font>学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
STM32组合设备实现USB转双串口
串口及其中断初始化 void USART1Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
[单片机]
意法半导体发布STM32 MCU图形界面设计软件TouchGFX 4.20版
STM32 用户界面设计环境新增屏幕旋转和纹理映射功能,支持性能强大的 Neochrom 图形加速器 中国,2022年8月16日---- 服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST;) 公布了STM32 微控制器图形用户界面设计软件TouchGFX 4.20版。最新的软件更新支持意法半导体新推出的 Neochrom 图形加速器。新款图形加速器集成在意法半导体的先进微控制器产品中,例如STM32U5系列。 意法半导体 Chrom-ART Accelerator™ 图形加速技术可以处理像素和形状,源自这项技术的Neochrom支持全屏旋转到任何角度,并支持纹理
[单片机]
意法半导体发布<font color='red'>STM32</font> MCU图形界面设计软件TouchGFX 4.20版
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved