如何快速上手使用STM32库函数

发布者:chaochen最新更新时间:2016-12-26 来源: eefocus关键字:快速上手  STM32  库函数 手机看文章 扫描二维码
随时随地手机看文章

一、背景

    如前文所述,利用标准库函数的好处在于,可以快速开发,不用去对着数据手册,小心翼翼的一位一位的配置那

些繁复的寄存器,因为这些工作意法半导体已经找了一些顶级的工程师帮你做了,杰作既是其库函数。当然,有些代码

考虑到低功耗,或者需要极小的ROM,就不能使用库函数,而这即是通常说的,"高度定制化",牺牲开发时间来获取更

高代码效率,这个需要自己权衡。

    本文以STM32之DMA库函数为例,即如何快速使用STM32库函数做个简述及记录。


二、正文

    首先去官网或者论坛下载STM32的官方库,解压出来,会发现里面是各种".c"".h",文件,不需要所有文件

   一股脑的照单全收,只需要复制一些自己需要的即可,

    1、 新建一个可用的工程(废话:-D),然后将库函数的".c"".h"文件加入到自己的工程内,并使其编译通过;

        最基本的工程所需要的库函数文件有:

        "startup_stm32f10x_hd.s" --> 启动文件;

        "system_stm32f10x.c" --> 常用来设置初始化时钟,里面的“SystemInit()”函数在启动文件内调用;

        "misc.c" --> Cotex-M3内核常用的配置文件,譬如其内包含NVIC配置库函数等等; 

        "stm32f10x_rcc.c" --> 时钟配置相关文件,里面包含了时钟配置库函数; 


        以DMA函数为例,将"stm32f10x_dma.c","stm32f10x_dma.h"文件放入指定文件夹内,然后加入已有

     工程,在主函数内尝试调用最简单的一个库函数,并编译通过,然后主函数删除测试调用的库函数。


    2、 先别急着去看库函数有哪些具体的库函数,更别急着去跟库函数的代码,首先去看STM32的技术手册关于DMA

     的内容,弄清楚DMA是一个什么结构,寄存器大概需要配置哪些,了解寄存器的时候不需要深究每一位,只需要

     明白每个寄存器控制哪些功能即可。


    3、 看完了STM32手册内关于DMA的介绍,就可以去解析库函数代码了。

        一般库函数代码的参数都是一个地址,一个包含配置信息的结构体参数,如DMA初始化库函数:

        /**

          * @brief  Initializes the DMAy Channelx according to the specified

          *         parameters in the DMA_InitStruct.

          * @param  DMAy_Channelx: where y can be 1 or 2 to select the DMA and 

          *   x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.

          * @param  DMA_InitStruct: pointer to a DMA_InitTypeDef structure that

          *         contains the configuration information for the specified DMA Channel.

          * @retval None

          */

        void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

        每个库函数之前都会有说明该库函数的功能是什么,传入的参数值得作用是什么,传入什么参数会被认定为有效

     参数以及返回值等等信息。

        对于传入的参数,有些会比较复杂,往往不是开头的只言片语就能介绍完整,此时你需要深入跟进库函数代码,

     看它拿这个参数具体做了什么。还是以此函数为例,第一个参数结构体如下:

        typedef struct

        {

          __IO uint32_t CCR;

          __IO uint32_t CNDTR;

          __IO uint32_t CPAR;

          __IO uint32_t CMAR;

        } DMA_Channel_TypeDef;

        此时就很明了了,每个DMA通道都会有单独独立的寄存器,第一个参数即包含了这些独立寄存器的地址。

        而那些所有DMA通道共用的寄存器则不在该参数内,也不需要在该参数内。所以其在参数说明中做了如下

        说明:

        /*

         * @param  DMAy_Channelx: where y can be 1 or 2 to select the DMA and 

         *   x can be 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.

         */


        接着分析第二个参数结构体,一般该结构体包含了配置DMA的所有参数信息,具体如下:

        typedef struct

        {

            uint32_t DMA_PeripheralBaseAddr;

            uint32_t DMA_MemoryBaseAddr;    

            uint32_t DMA_DIR;               

            uint32_t DMA_BufferSize;        

            uint32_t DMA_PeripheralInc;     

            uint32_t DMA_MemoryInc;         

            uint32_t DMA_PeripheralDataSize;

            uint32_t DMA_MemoryDataSize;    

            uint32_t DMA_Mode;              

            uint32_t DMA_Priority;          

            uint32_t DMA_M2M;               

        }DMA_InitTypeDef;

        这个一眼望去,真的是俩眼懵逼,还是按着套路来(23333),进入库函数看每个参数做了什么。

        tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |

                  DMA_InitStruct->DMA_PeripheralInc | 

           DMA_InitStruct->DMA_MemoryInc |

                  DMA_InitStruct->DMA_PeripheralDataSize | 

           DMA_InitStruct->DMA_MemoryDataSize |

                  DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;

        /* Write to DMAy Channelx CCR */

        DMAy_Channelx->CCR = tmpreg;

        看到这里,这里这么多参数,全部设置给了一个叫CCR的寄存器,接着我们查查这个CCR寄存器都设置了什么:

        DMA通道x配置寄存器(DMA_CCRx),定位到这个寄存器,再加上每个参数32位所处的位数则可以确定该结构体

     每个成员代表了什么,其他参数亦如此。

     确定了所有的参数所控制的功能后,这时就可以按照自己的需求去传入正确的参数做相应的配置。

        这里我想插一句,既有些新学STM32的朋友,我也曾算是一个,就觉着使用库函数而不去配置每个寄存器,会觉

     着心里不踏实,不能学到真正的STM32技术,而就刚刚所做的一系列动作来看,其实是误解了,利用库函数,同

     样的你也得去深入的了解STM32的技术手册,所以并不存在不能学到实际技术之说。

     技术一直在更新,老的技术也一直在沉淀稳定,我们只需站在巨人的肩膀上,就可以看的更高更远,何苦还需要

     浪费时间和精力自己去做别人已经做好的事情呢。:-D


    4、 解析完所有的函数后,此时即可以利用库函数去实现自己的功能逻辑啦。


三、参考文献:

  STM32F10x Standard Perpheral Libary (V3.5.0)

    http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries/stsw-stm32054.html


  STM32F10x Description of STM32F1XX Standard Perpheral Libary Documentation

    http://stm32.kosyak.info/doc/


    至此,记录完毕。


关键字:快速上手  STM32  库函数 引用地址:如何快速上手使用STM32库函数

上一篇:STM32f103之外部中断
下一篇:STM32F103xx bxCAN(Basic Extended CAN) 滤波机制

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

STM32 FLASH擦除、写入以及防止误擦除程序代码
编译环境:(Keil)MDK4.72.10 stm32库版本:STM32F10x_StdPeriph_Driver_3.5.0 一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。   对STM32 内部FLASH进行编程操作,需要遵循以下流程:   1、FLASH解锁;   2、清除相关标志位;   3、擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便);   4、写入FLASH;   5、锁定FLASH; 实例: #define FLASH_PAGE_SIZE ((uint16_t)0x400) //如果一页为1K大小 #define WRITE_START_ADDR ((uin
[单片机]
<font color='red'>STM32</font> FLASH擦除、写入以及防止误擦除程序代码
stm32 外部中断 按键的误触发
最近在调试按键作为外部中断exti进行触发动作,发现每次按键按下和按键抬起都会多次进入中断函数,造成程序不稳定,经过反复调试和查阅资料,最后终于已经把这个问题解决,现在总结一下: 1、EXTI重复配置两次导致误触发中断的问题 如果重复两次配置EXTI的话,由于第一次已经打开中断,当进行第二次配置中断的时候,会把中断引脚首先配置成默认引脚,然后在配置成目的引脚,这样由于默认引脚是低电平,所以在切换的过程中就会进入一次中断!!具体请参见:http://bbs.elecfans.com/jishu_942011_1_1.html 2、STM32F401 外部中断误触发问题 现象:调试STM32F411低功耗的时候,使用的
[单片机]
实用STM32的串口控制平台的实现
1. 前言 玩过Linux的朋友, 是不是对Linux无所不能的串口Shell命令控制台羡慕不已, 要是自己做的STM32F系列低档次的MCU也有这种控制交互能力, 会给调试/维护和配置省下多少麻烦事呀, 比如启动/关闭调试或自检模式, 打印调试信息, 配置系统参数, 传输文件等等, 也有相当多的朋友凭借自己出色的编程能力可以实现这些功能, 这里提出我的这个解决方案, 以作交流. 本平台(xc_shell)具备以下性能特点: 1) 大量主要代码, 和具体硬件无关, 移植性强,代码文件少. 2) 只有在处理用户的输入命令时, 才占用CPU资源, 且代码可裁剪到1KB SRAM和4KB Flash; 3) 用户可以非常灵活的添加按
[单片机]
实用<font color='red'>STM32</font>的串口控制平台的实现
STM32学习记录9:STM32F10X_XX宏定义的选择
如果你使用stm32f10x_stdperiph_lib,会发现在stm32f10x.h文件会有一段关于宏选择的代码,如: view plain copy #if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL) /* #define STM32F10X_LD */ /*! STM32F10X_LD: STM32 Low density devices */ /* #define STM32F10X_MD */ /*! STM32F10
[单片机]
<font color='red'>STM32</font>学习记录9:STM32F10X_XX宏定义的选择
[STM32] 关于USART接收中断的BUG和注意事项
今天在使用USART模块,遇到了一些问题并解决了,于是发贴共享。 问题描述: 在使用USART做串口通讯时,我只把接收中断打开,并设置抢占优先级为最低一个级别,而接收中断上一个优先级处理事情比较多,可能占用了2ms时间。当我使用9600波特率往下位机发送数据,速度非常快,就是一直按回车发!问题就出来,不到1分钟时间,通讯没有反应了。USART配置代码如下: void uart_config(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = UART_GetBaud(BaudRate); USART_In
[单片机]
STM32----GT9157触摸IC驱动
一、硬件环境 野火F429第一代开发板,5寸触摸屏,触摸IC为GT9157,支持5点触控(但IC是支持10点触控的) 二、GT9157初始化 总的流程:1、初始化GPIO -- 2、初始化I2C -- 3、复位GT9157以确定IC从地址 -- 4、写配置寄存器(0x8047~0x8100) (1)初始化GPIO与I2C 这个不详述,I2C可用模拟,也可用硬件I2C。STM32F4的硬件I2C稳定性还行,最重要的是,需要设置I2C等待时间 与等待次数,超时跳出等待防止卡死。野火的I2C读取移植自GT9157的Linux驱动,使用一个i2c_msg结构体控制读写 static
[单片机]
STM32----GT9157触摸IC驱动
STM32学习笔记(5) 串口通讯-接收与发送
一 通信的基本概念 串口并行与串行 数电课讲过,并行速度快但占用的门电路多,耗费空间 串行速度慢但节约空间 数据通信方向 全双工:TX,RX同时收发数据 半双工:不能同时收发数据,可分时收发数据 单工:任何时刻都只能往某一个固定的方向传输数据 数据同步方式 同步 异步 通信速率 比特率:每秒钟传输的二进制位数,单位(bit/s) 波特率:每秒中传输的码元个数 一个码元就是一个脉冲信号,一个脉冲信号有可能携带1bit数据,也有可能携带2bit数据、4bit数据!你发送一个脉冲信号,如果就可以携带4bit数据,肯定发送速率更快啊! 那么怎么实现一个脉冲信号就能携带多个bit数据呢?就需要一定
[单片机]
<font color='red'>STM32</font>学习笔记(5) 串口通讯-接收与发送
使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信
本篇详细的记录了如何使用STM32CubeMX配置STM32F103C8T6的硬件SPI外设与DW1000通信,为移植DW1000官方驱动打下基础。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): DW1000模块 这里我连接到DW1000官方评估板上,直接与DW1000芯片通信: 连接方法 首先查看DW1000官方评估板预留的外接控制器SPI接口(J6接口)的引脚说明: 外部供电接口(J7)的引脚说明: ① 首先将DW1000官方评估板上的S1、S2拨码开关全部拨为OFF,这样配置之后才可以外接控制器。 ② 按照下图选择端子,配置为外部供电
[单片机]
使用<font color='red'>STM32</font>硬件SPI+STM32cubeMX+HAL库测试DW1000通信
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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