精华内容
下载资源
问答
  • 2018.1.19 HAL库详解见STM32之HAL库详解 及 手动移植 STM32 Embedded Software ...前两者都是常用的库,后面的LL库是ST最近才添加,随HAL源码包一起提供,目前支持的芯片也偏少。各库如下所示:   其
    • 2020.2.4: 更新内容

    STM32 Embedded Software

      工作以来一直使用 ST 的 STM32 系列芯片,ST 为开发者提供了非常方便的开发库。到目前为止,有标准外设库(SPL 库)、HAL 库、LL 库 三种。前两者都是常用的库,后面的 LL 库是 ST 最近才添加,随 HAL 源码包一起提供,目前支持的芯片也偏少。各库如下所示:
    库
      其中,SPL 库 和 HAL 库两者相互独立,互不兼容。几种库的比较如下:
    库比较
      目前几种库对不同芯片的支持情况如下:
    在这里插入图片描述
      ST 中文官网上有一篇《关于ST库函数的代码性能对比》的文章,其中对比了各种库的性能如下:
    在这里插入图片描述

    STM32 Snippets

      它是代码示例的集合,直接基于 STM32 外设寄存器,可在文档和软件包中使用。由于处在最底层,因此需要开发者直接操作外设寄存器,对开发者要求比较高,通常针对于对汇编程序比较了解的资深嵌入式工程师!
      这个库使用比较少,目前只在 STM32F0 和 STM32L0 系列中有提供。两个库都有各自的说明文档。主要就是下图所示的这些:
    在这里插入图片描述
    严格来说,它不能称为库,仅仅就是将 MCU 中的寄存器进行了结构化的封装,库文件主要就是一些 .h 文件。如下是对 ADC 的封装

    /**
      * @brief Analog to Digital Converter
      */
    
    typedef struct
    {
      __IO uint32_t ISR;          /*!< ADC Interrupt and Status register,                          Address offset:0x00 */
      __IO uint32_t IER;          /*!< ADC Interrupt Enable register,                              Address offset:0x04 */
      __IO uint32_t CR;           /*!< ADC Control register,                                       Address offset:0x08 */
      __IO uint32_t CFGR1;        /*!< ADC Configuration register 1,                               Address offset:0x0C */
      __IO uint32_t CFGR2;        /*!< ADC Configuration register 2,                               Address offset:0x10 */
      __IO uint32_t SMPR;         /*!< ADC Sampling time register,                                 Address offset:0x14 */
      uint32_t   RESERVED1;       /*!< Reserved,                                                                  0x18 */
      uint32_t   RESERVED2;       /*!< Reserved,                                                                  0x1C */
      __IO uint32_t TR;           /*!< ADC watchdog threshold register,                            Address offset:0x20 */
      uint32_t   RESERVED3;       /*!< Reserved,                                                                  0x24 */
      __IO uint32_t CHSELR;       /*!< ADC channel selection register,                             Address offset:0x28 */
      uint32_t   RESERVED4[5];    /*!< Reserved,                                                                  0x2C */
       __IO uint32_t DR;          /*!< ADC data register,                                          Address offset:0x40 */
    }ADC_TypeDef;
    
    typedef struct
    {
      __IO uint32_t CCR;
    }ADC_Common_TypeDef;
    

    在实际使用时,我们就可以结构化的访问 MCU 的寄存器,如下是配置 ADC 的函数实现:

    /**
      * @brief  This function configure the ADC to convert the internal reference voltage (VRefInt)
      *         The conversion frequency is 14MHz 
      * @param  None
      * @retval None
      */
    __INLINE void ConfigureADC(void)
    {
        /* (1) Select the clock mode (refer ADC_PRESCALER definition :
             HSI14 by writing 00 in CKMODE (reset value)
             DIV2 or DIV 4 */
        /* (2) Select the auto off mode */
        /* (3) Select CHSEL17 for VRefInt */
        /* (4) Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater than 17.1us */
        /* (5) Wake-up the VREFINT (only for VBAT, Temp sensor and VRefInt) */
        ADC1->CFGR2 |= ADC_PRESCALER;                                   /* (1) */
        ADC1->CFGR1 |= ADC_CFGR1_AUTOFF;                                /* (2) */
        ADC1->CHSELR = ADC_CHSELR_CHSEL17;                              /* (3) */
        ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2; /* (4) */
        ADC->CCR |= ADC_CCR_VREFEN;                                     /* (5) */
    }
    

    标准外设库(Standard Peripheral Libraries)

      标准外设库(Standard Peripherals Library)是对 STM32 芯片的一个完整的封装,包括所有标准器件外设的器件驱动器。这应该是目前使用最多的 ST 库。几乎全部使用 C 语言实现。但是,标准外设库也是针对某一系列芯片而言的,没有可移植性。
    在这里插入图片描述
      相对于 HAL 库,标准外设库仍然接近于寄存器操作,主要就是将一些基本的寄存器操作封装成了 C 函数。开发者需要关注所使用的外设是在哪个总线之上,具体寄存器的配置等底层信息。
      相对于 STM32 Snippets,标准外设库对各外设的进行了一次封装,而不是仅仅局限在对寄存器的封装。实现了各外设的基本操作接口。
      在文档方面,我只发现了针对 F2 系列和 F3 系列的详细说明文档,如下图所示:
    在这里插入图片描述
    标准外设库的文件基本架构并不复杂。下图显示了 STM32F10xx 标准外设库文件的基本架构
    在这里插入图片描述
    其他系列的库文件结构和上图基本都是一致的!
      ST 为各系列提供的标准外设库稍微有些区别。例如,STM32F1x 的库和 STM32F3x 的库在文件结构上就有些不同,此外,在内部的实现上也稍微有些区别,这个在具体使用(移植)时,需要注意一下!但是,不同系列之间的差别并不是很大,而且在设计上是相同的。STM32 的标准外设库涵盖以下 3 个抽象级别:

    • 包含位,位域和寄存器在内的完整的寄存器地址映射
    • 涵盖所有外围功能(具有公共API的驱动器)的例程和数据结构的集合。
    • 一组包含所有可用外设的示例,其中包含最常用的开发工具的模板项目。

      关于更详细的信息,可以参考 ST 的官方文档,文档中对于标准外设库函数命名、文件结构等都有详细的说明。

    STM32Cube

      ST 为新的标准库注册了一个新商标:STMCube™。并且,ST专门为其开发了配套的桌面软件 STMCubeMX,开发者可以直接使用该软件进行可视化配置,大大节省开发时间。
    在这里插入图片描述
      这其中就包含了 HAL 库和最近新增的 LL 库。如下图:
    STM32Cube
      从上图不难看出,LL 库和 HAL 库两者相互独立,只不过 LL 库更底层。而且,部分 HAL 库会调用LL库(例如:USB驱动)。同样,LL 库也会调用 HAL 库
      用户可以使用 STMCubeMX 直接生成对应芯片的整个项目(目前主流开发工具的项目基本全支持),STMCubeMX 负责给整理各种需要的源码文件。

    注意:
      1. 个人感觉STMCubeMX生成的项目并不够简洁,源码的组织结构也并不是很好。
      2. STMCubeMX在生产项目时,可以选择使用HAL库或者LL库。但是部分组件的HAL库会调用LL库

    HAL 库

      HAL是 Hardware Abstraction Layer 的缩写,中文名:硬件抽象层。HAL 库是 ST 为 STM32 最新推出的抽象层嵌入式软件,可以更好的确保跨 STM32 产品的最大可移植性。该库提供了一整套一致的中间件组件,如 RTOS,USB,TCP/IP 和 图形 等。
      HAL 库是基于一个非限制性的 BSD 许可协议(Berkeley Software Distribution)而发布的开源代码。 ST 制作的中间件堆栈(USB 主机和设备库,STemWin)带有允许轻松重用的许可模式, 只要是在 ST 公司的 MCU 芯片上使用,库中的中间件(USB 主机/设备库,STemWin)协议栈即被允许随便修改,并可以反复使用。至于基于其它著名的开源解决方案商的中间件(FreeRTOS,FatFs,LwIP和PolarSSL)也都具有友好的用户许可条款。
      作为目前 ST 主推的外设库,HAL库相关的文档还是非常详细的。
    在这里插入图片描述
      可以说HAL 库就是用来取代之前的标准外设库的。相比标准外设库,STM32Cube HAL 库表现出更高的抽象整合水平,HAL API 集中关注各外设的公共函数功能,这样便于定义一套通用的用户友好的API函数接口,从而可以轻松实现从一个STM32产品移植到另一个不同的STM32系列产品。HAL库是ST未来主推的库,从前年开始ST新出的芯片已经没有STD库了,比如 F7 系列。目前,HAL库已经支持STM32全线产品。

      使用HAL库编程,最好尽量符合HAL库编程的整体架构。关于HAL库的详细介绍,可以参考后文 STM32 HAL库详解 及 手动移植

    LL 库

      LL库(Low Layer)是 ST 最近新增的库,与 HAL 库捆绑发布,文档也是和 HAL 库文档在一起的,比如:在STM32F3x 的 HAL 库说明文档中,ST 新增了LL库这一章节,但是在 F2x 的HAL文档中就没有。
      LL 库更接近硬件层,对需要复杂上层协议栈的外设不适用,直接操作寄存器。其支持所有外设。使用方法:

    • 独立使用,该库完全独立实现,可以完全抛开 HAL 库,只用LL库编程完成。在使用STM32CubeMX生成项目时,直接选LL库即可。如果使用了复杂的外设,例如 USB,则会调用 HAL 库
    • 混合使用,和 HAL 库结合使用。

    目前,CubeMX 在生成项目时,可以选择采用 LL 库。

      LL 库文件的命名方式和 HAL 库基本相同。个人感觉,LL 库就是原来的标准外设库移植到 Cube下的新的实现,但是其实现方法更加高效、简洁。使用 LL 库编程和使用标准外设库的方式基本一样,但是确会得到比标准外设库更高的效率。

    更详细的介绍,请参见博文《STM32 之十一 LL 库详解 及 移植使用说明

    参考

    1. STM32 Embedded Software Overview.pdf
    2. STM32库函数性能对比.pdf
    3. STM32F0xx Snippets firmware package.pdf
    展开全文
  • 标准库转LL库工具

    2018-06-26 14:25:11
    从网上下载的stm32标准库转LL库工具,亲测真实可用,但是该工具存在局限性,很多代码不能转化,所以该工具适合作为学习参考,开阔思路使用。
  • STM32标准库转LL库

    2017-09-15 10:29:06
    STM32标准库转LL库工具。需要JAVA和PERL。附带代码转换帮助手册,比较方便。 LL库资源很少,这个可以帮助少走一些弯路。
  • stm32 LL库对比标准库资料 stm32 LL库对比标准库资料 stm32 LL库对比标准库资料 stm32 LL库对比标准库资料
  • STM32 LL库使用指南PDF

    2019-01-18 15:04:55
    STM32 LL库使用指南,最新版的LL库,PDF高清版。直接操作寄存器。。
  • stm32ll库(law_layer)

    2018-12-17 15:43:21
    stm32 ll库使用手册,和ll库与hal库差异对比,和ll库如何建立工程等
  • 曾几何时想过使用LL库来降低程序固件大小,但是翻看了官方自带的参考例程发现LL库的例程少之又少,而且CubeMX生成的也是基于HAL库的,奈何一直没有找到如何生成LL库的选项。今天无意随手都点了点,看了看,结果就...

    前言

    以前听闻过LL库相比HAL精简,HAL库很臃肿。曾几何时想过使用LL库来降低程序固件大小,但是翻看了官方自带的参考例程发现LL库的例程少之又少,而且CubeMX生成的也是基于HAL库的,奈何一直没有找到如何生成LL库的选项。今天无意随手都点了点,看了看,结果就发现了这张图:
    在这里插入图片描述


    哇咔咔,原来CubeMX中所用到的外设是可以选择使用HAL库还是LL库的,但是仔细看了一下,并不是所有外设都有LL库支持,但是HAL库是所有外设全部支持的,而且默认选择的都是HAL库。下面请看这张图:
    在这里插入图片描述

    展开全文
  • HAL和LL库实验程序.zip

    2021-04-10 22:55:11
    蓝桥杯嵌入式比赛开发板:STM32G431RBT6 HAL和LL库实验程序
  • STM32F103之EC11驱动LL库源码/**/
  • 随着st系列芯片的升级,之前的工程基本使用标准库开发,但是之后的芯片只支持HAL库和LL库,就涉及到项目的迁移,虽然官方资料都提供了,但是很难针对性的找到需要的文档。想从标准库移植到LL库需要以上文档就够了...
  • STM32LL库使用指南,使用手册的工程模板,演示如何使用STM32LL库写STM32底层驱动
  • LL库串口+DMA

    千次阅读 2020-04-22 18:10:07
    由于工作中测试发现串口传输数据延时有点大,传输35个字节,115200,理论值应该在3ms左右,然而实际测试却有40ms,所以首先想到会不会是hal库执行效率低得原因,所以采用LL库,但是LL库的资料少之又少啊!...

           由于工作中测试发现串口传输数据延时有点大,传输35个字节,115200,理论值应该在3ms左右,然而实际测试却有40ms,所以首先想到会不会是hal库执行效率低得原因,所以采用LL库,但是LL库的资料少之又少啊!自己做个记录。

          使用cubemx可以直接生产LL库的代码(我的工程里是hal库和LL库混用的),LL库串口硬件初始化部分会自动生成,但是传输地址及DMA传输长度并没有设置,需要手动设置。设置步骤可参考标准库设置

           初始化代码使用DMA+IDLE接收数据,

    void bsp_usart_init()
    {
    
       
        LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_5, (uint32_t)bsp_usart.aRxBuffer);
        LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_5, (uint32_t)(&USART2->DR));
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, bsp_usart.buf_len);
        LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
    
        LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_6, (uint32_t)bsp_usart.aTxBuffer);
        LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_6, (uint32_t)(&USART2->DR));
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_6, 0);
    
        //LL_USART_EnableIT_TC(USART2);
        //LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_6);
    
        LL_USART_EnableIT_IDLE(USART2);
        LL_USART_EnableDMAReq_RX(USART2);
        LL_USART_EnableDMAReq_TX(USART2);
    }

    中断接收函数

    void bsp_usart_IRQ()
    {
    
        if (LL_USART_IsActiveFlag_IDLE(USART2))
        {
            LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_5); //¹Ø±ÕDMA
    
            int cnt = LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_5);
            bsp_usart.rx_len = bsp_usart.buf_len - cnt; //总计数减去未传输的数据个数,得到已经接收的数据个数
            bsp_usart.recv_end_flag = 1;                // 接受完成标志位置1
    
            LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, USART_BUF_MAX_LEN);
            LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
            LL_USART_ClearFlag_IDLE(USART2);
        }
        else if (LL_USART_IsActiveFlag_TC(USART2))
        {
            LL_USART_DisableIT_TC(USART2);
            LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_6);
        }
    }

    DMA发送函数

    uint8_t bsp_usart_send(uint8_t *data, uint32_t len)
    {
    
        while (LL_USART_IsActiveFlag_TC(USART2) == 0)
        {
    		
        }
        LL_DMA_ClearFlag_TC6(DMA1);
    
        memcpy(bsp_usart.aTxBuffer, data, len);
    
        LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_6);
        LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_6, len);
        LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_6);
    
        return 0;
    
    }

    在使用LL库时,串口接收还比较容易实现,和hal库除了初始化设置DMA地址外,其他大同小异。但是DMA发送却没有那么顺利,第一次调用发送函数时,是可以正常接收到的,但是后面就没有了。最后发现是没有清除DMA发送完成中断,使用LL库特别要注意中断及标志位的清除

    展开全文
  • STM32L011F4U 基于LL库驱动代码
  • 不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个 LL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin(); __STATIC_INLINE void LL_GPIO_...

    不知道为为什么,STM32 LL库并没有FLASH的库函数,于是决定写一个

    LL库的特色,就是一个函数,只占用一个指令周期,比如,设置GPIO输出的状态,就是LL_GPIO_SetOutputPin();

    __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
    {
      WRITE_REG(GPIOx->BSRR, PinMask);
    }
    

    于是我根据这种风格,已经常用的操作写了一个.h和.c文件

    头文件代码

    #ifndef __STM32F0xx_LL_FLASH_EX_H
    #define __STM32F0xx_LL_FLASH_EX_H
    
    #include "stm32f0xx.h"
    
    
    #define FLASH_FLAG_BSY             FLASH_SR_BSY            /*!< FLASH Busy flag                           */ 
    #define FLASH_FLAG_PGERR           FLASH_SR_PGERR          /*!< FLASH Programming error flag    */
    #define FLASH_FLAG_WRPERR          FLASH_SR_WRPERR         /*!< FLASH Write protected error flag          */
    #define FLASH_FLAG_EOP             FLASH_SR_EOP            /*!< FLASH End of Operation flag               */
    
    #define FLASH_TYPEERASE_PAGES          FLASH_CR_PER         /*!< FLASH_CR_PER          */
    #define FLASH_TYPEERASE_MASSERASE      FLASH_CR_MER            /*!< MASSERASE              */
    
    
    #if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \
     || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6)
    #define FLASH_PAGE_SIZE          0x400U
    #endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */
    
    #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \
     || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
    #define FLASH_PAGE_SIZE          0x800U
    #endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */
    
    typedef enum {
    	ProgaraType_DATA64,
    	ProgaraType_DATA32,
    	ProgaraType_DATA16
    }ProgaramDataType;
    
    typedef enum {\
    	FLASH_Lock=1U,Flash_Unlock=!FLASH_Lock\
    }FlashStates;
    
      /* Set the OBL_Launch bit to launch the option byte loading */
    __STATIC_INLINE void LL_FLASH_SET_OBL_Launch(FLASH_TypeDef *FLASHx)
    {
      SET_BIT(FLASHx->CR, FLASH_CR_OBL_LAUNCH);
    }
    __STATIC_INLINE void LL_FLASH_Lock(FLASH_TypeDef *FLASHx)
    {
      SET_BIT(FLASHx->CR, FLASH_CR_LOCK);
    }
    
    
      /* @brief  Set flash erase type.
      * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
      *          This parameter can be any combination of the following values:
      *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase
      *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag 
      * @retval none*/
    
    __STATIC_INLINE void LL_FLASH_SetTypeErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
    {
      SET_BIT(FLASHx->CR, FLASH_TYPEERASE);
    }
      /* @brief  Set flash erase ADDR.
      *          This parameter can be any combination of the following values:
      *            @arg @ref EraseADDR         uint32_t value
      * @retval none*/
    
    __STATIC_INLINE void LL_FLASH_SetEraseADDR(FLASH_TypeDef *FLASHx,uint32_t EraseADDR)
    {
      WRITE_REG(FLASHx->AR, EraseADDR);
    }
      /* @brief  Set flash erase ADDR.
      *          This parameter can be any combination of the following values:
      *            @arg @ref EraseADDR         uint32_t value
      * @retval none*/
    
    __STATIC_INLINE void LL_FLASH_StartErase(FLASH_TypeDef *FLASHx)
    {
      SET_BIT(FLASHx->CR, FLASH_CR_STRT);
    }
    
      /* @brief  Clear the specified FLASH flag.
      * @param  __FLAG__ specifies the FLASH flags to clear.
      *          This parameter can be any combination of the following values:
      *            @arg @ref FLASH_FLAG_EOP         FLASH End of Operation flag 
      *            @arg @ref FLASH_FLAG_WRPERR      FLASH Write protected error flag 
      *            @arg @ref FLASH_FLAG_PGERR       FLASH Programming error flag
      * @retval none*/
    
    __STATIC_INLINE void LL_FLASH_ClearFlag(FLASH_TypeDef *FLASHx,uint32_t STATE_FLAG)
    {
      WRITE_REG(FLASHx->SR, STATE_FLAG);
    }
    
      /*get bit flash bsy*/
    __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_BSY(FLASH_TypeDef *FLASHx)
    {
      return (READ_BIT(FLASHx->SR, FLASH_SR_BSY) == (FLASH_SR_BSY));
    }
    /*get end of operation bilt*/
    __STATIC_INLINE uint32_t LL_FLASH_IsActiveFlag_EOP(FLASH_TypeDef *FLASHx)
    {
      return (READ_BIT(FLASHx->SR, FLASH_SR_EOP) == (FLASH_SR_EOP));
    }
    /*clear end of operation bilt*/
    __STATIC_INLINE void LL_FLASH_ClearFlag_EOP(FLASH_TypeDef *FLASHx)
    {
      SET_BIT(FLASHx->SR, FLASH_SR_EOP);//EOP bit Set clear
    }
      /* @brief  Set flash erase type.
      * @param  FLASH_TYPEERASE specifies the FLASH flags to clear.
      *          This parameter can be any combination of the following values:
      *            @arg @ref FLASH_TYPEERASE_PAGES         PAGES Erase
      *            @arg @ref FLASH_TYPEERASE_MASSERASE      FLASH Write protected error flag 
      * @retval none*/
    __STATIC_INLINE void LL_FLASH_DisenableErase(FLASH_TypeDef *FLASHx,uint32_t FLASH_TYPEERASE)
    {
      CLEAR_BIT(FLASHx->CR, FLASH_TYPEERASE);
    }
    
    /*EnableProgram*/
    __STATIC_INLINE void LL_FLASH_EnableProgram(FLASH_TypeDef *FLASHx)
    {
      SET_BIT(FLASHx->CR,FLASH_CR_PG);
    }
    /*DisenableProgram*/
    __STATIC_INLINE void LL_FLASH_DisenableProgram(FLASH_TypeDef *FLASHx)
    {
      CLEAR_BIT(FLASHx->CR,FLASH_CR_PG);
    }
    /*read flash's states of lock or unlock*/
    __STATIC_INLINE FlashStates LL_FLASH_LockState(FLASH_TypeDef *FLASHx)
    {
    	return (FlashStates)(READ_BIT(FLASHx->CR,FLASH_CR_LOCK));
    }
    /*set key for flash*/
    __STATIC_INLINE void LL_FLASh_SetKey(FLASH_TypeDef *FLASHx,uint32_t key)
    {
    	WRITE_REG(FLASH->KEYR,key);
    }
    
    
    LL_StatusTypeDef LL_Flash_Unlock(void);
    LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t NbPages);
    LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data);
    #endif
    

    C文件代码

    #include "stm32f0xx_ll_flash_ex.h"
    
    
    void static LL_FLASH_Program_TwoBtye(uint32_t flash_addr,uint16_t data)
    {
    	LL_FLASH_EnableProgram(FLASH);
    	*(__IO uint16_t*)(flash_addr) = data;
    }
    
    LL_StatusTypeDef LL_Flash_Unlock(void)
    {
    	while (LL_FLASH_IsActiveFlag_BSY(FLASH))  
    	{
    	} 
    	if (LL_FLASH_LockState(FLASH)) 
    	{ 
    		LL_FLASh_SetKey(FLASH,FLASH_KEY1);
    		LL_FLASh_SetKey(FLASH,FLASH_KEY2);
    	}
    	return LL_OK;
    }
    
    LL_StatusTypeDef LL_Flash_PageErase(uint32_t page_addr,uint16_t Nb)
    {
    	uint32_t End_addr =  10* FLASH_PAGE_SIZE +page_addr;
    	uint32_t Start_addr = page_addr;
    	for(;Start_addr < End_addr;(Start_addr += FLASH_PAGE_SIZE))
        {
            LL_FLASH_SetTypeErase(FLASH,FLASH_TYPEERASE_PAGES);
    		LL_FLASH_SetEraseADDR(FLASH,Start_addr);
    		LL_FLASH_StartErase(FLASH); 
    		while (LL_FLASH_IsActiveFlag_BSY(FLASH)) 
    		{ 
    		} 
    		if (LL_FLASH_IsActiveFlag_EOP(FLASH)) 
    		{ 
    			LL_FLASH_ClearFlag_EOP(FLASH);; 
    		} 
    		else
    		{ 
    			return LL_ERROR;
    		}
    		LL_FLASH_DisenableErase(FLASH,FLASH_TYPEERASE_PAGES);
        }
    	return LL_OK;
    }
    
    LL_StatusTypeDef LL_FLASH_Program(ProgaramDataType ProgramType,uint32_t flash_addr,uint64_t data)
    {
    	
    	uint8_t index = 0U;
    	uint8_t nbiterations = 0U;
    	
    	if(ProgramType == ProgaraType_DATA16)
    		nbiterations = 1U;
    	else if(ProgramType == ProgaraType_DATA32)
    		nbiterations = 2U;
    	else
    		nbiterations = 4U;
    	for(index = 0U; index < nbiterations; index++)
    	{
    		 LL_FLASH_Program_TwoBtye((flash_addr + (2U*index)), (uint16_t)(data >> (16U*index)));
    	}
    	
    	while (LL_FLASH_IsActiveFlag_BSY(FLASH)) 
    	{
    	}
    	if (LL_FLASH_IsActiveFlag_EOP(FLASH))	
    	{
    		LL_FLASH_ClearFlag_EOP(FLASH);
    	}
    	else
    	{
    		return LL_ERROR;
    	}
    	LL_FLASH_DisenableProgram(FLASH);
    	return LL_OK;
    }
    
    展开全文
  • CubeMx+LL库下在 RT-Thread Nano 上添加控制台与 FinSH,LL库比较接近寄存器操作,现在ST官方都在大力推广HAL和LL库,个人觉得有必要学习和适应。
  • 目前LL库的资料相对较少,网上找了一圈只有官方的手册,但是也没有对LL库有系统的介绍,本文介绍一种自己的方法,结合c和h文件,并且和《STM32中文参考手册》结合起来,进行摸索和使用。 首先下载notepad++:...
  • STM32LL库系列教程(一)—— LL库概览及资料

    千次阅读 多人点赞 2020-07-07 17:18:21
    用过STM32的朋友,对于标准 ...事实上,ST在推行HAL的时候,逐渐停止了对于标准的更新(新出的芯片以及不再提供标准了),但他们也意识到了HAL效率较低的问题,因此同时也推出了LL( *Low-layer* )****。
  • 首先使用STcubeMX配置一下...有了以上配置我们还需要手动打开中断使能等操作,LL库没有为我们打开。 LL_TIM_ClearFlag_CC1(TIM4); LL_TIM_ClearFlag_UPDATE(TIM4); LL_TIM_EnableIT_CC1(TIM4); LL_TIM_Enabl...
  • STM32官方文档关于HAL库与LL库,F1、F2、F3、F4、F7、H7、L0、L1、L4 Hal&LL文档集全。
  • STM32驱动SD卡,使用SPI方式,压缩包内包含标准库、LL库、HAL库三种库的SPI驱动SD卡代码外加HAL库版本的FatFS的代码,作者使用的是正点原子MiniSTM32开发板V2,STM32RBT6那一款,32G的mircosd卡加卡托,已经测试通过...
  • (代码中有个地方改了,在http_service.c中link线程初始化参数改为对应的link参数而不是网卡配置参数)stm32f407 hal库+ll库 lan8720a+lwip。mdk527。本工程仅仅是dhcp,工程中包含其他外设的初始化代码
  • STM32CubeMX LL库,STM32L0 KeilMDK5工程,将HAL库的IIC改成LL库实现对地磁5883芯片三轴读写。读出来的数据转成uT(微特斯拉),1特斯拉=1×10^4高斯=1×10^6微特斯拉;特斯拉英文为tesla(字首小写),符号表示为T...
  • STM32LL库 SPI全双工通信GS2962.
  • STM32 之HAL库、标准外设库、LL库HAL库、标准外设库、LL库概述STM32 Snippets标准外设库(Standard Peripheral Libraries)STM32CubeHAL 库LL 库 HAL库、标准外设库、LL库概述 ST 为开发者提供了非常方便的开发库。...
  • 使用STM32L4xx芯片,LL库配置硬件SPI,包括初始化以及收发函数;
  • STM32 LL库使用指南+新建工程模板方法,详细介绍STM32LL库以及如何新建工程模板的具体步骤
  • STM32CubeMX 实战教程:新建项目和生成 MDK_ARM 工程(LL ),具体详情可以参考博客:https://blog.csdn.net/brendon_tan/article/details/107869664
  • L053RTC时钟唤醒,LL库和HAL库
  • 实现了 两个板子通过NRF24L01 收发数据 基于LL库 发送用的是stm32f103vet6 接收采用stm32f103c8t6 模块型号AS01-ML01DC
  • 关注+星标公众号,不错过精彩内容作者| strongerHuang微信公众号|嵌入式专栏早期开发STM32,大部分工程师都是基于标准库进行开发,如果要换成LL库,且需要复用以前代码...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,774
精华内容 36,309
关键字:

LL库