ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:18.55KB ,
资源ID:12068082      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12068082.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(解析STM32的库函数.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

解析STM32的库函数.docx

1、解析STM32的库函数以最常用的GPIO设备的初始化函数为例,如下程序段一:GPIO_InitTypeDef GPIO_InitStructure; 1GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 2GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz; 3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 4GPIO_Init(GPIOA , &GPIO_InitStructure 5这是一个在STM32的程序开发中经常使用到的GPIO初始化程序段,其功能是将GPIO

2、A.4口初始化为推挽输出状态,并最大翻转速率为50MHz。下面逐一分解: 首先是1,该语句显然定义了一个GPIO_InitTypeDef类型的变量,名为GPIO_InitStructure,则找出GPIO_InitTypeDef的原型位于“stm32f10x_gpio.h”文件,原型如下:typedef structu16 GPIO_Pin;GPIOSpeed_TypeDef GPIO_Speed;GPIOMode_TypeDef GPIO_Mode;GPIO_InitTypeDef; 由此可知GPIO_InitTypeDef是一个结构体类型同义字,其功能是定义一个结构体,该结构体有三个成员分

3、别是u16类型的GPIO_Pin、GPIOSpeed_TypeDef 类型的GPIO_Speed和GPIOMode_TypeDef 类型的GPIO_Mode。继续探查GPIOSpeed_TypeDef和GPIOMode_TypeDef类型,在“stm32f10x_gpio.h”文件中找到对GPIOSpeed_TypeDef的定义:typedef enumGPIO_Speed_10MHz = 1,GPIO_Speed_2MHz,GPIO_Speed_50MHzGPIOSpeed_TypeDef;则可知GPIOSpeed_TypeDef枚举类型同一只,其功能是定义一个枚举类型变量,该变量可表示GP

4、IO_Speed_10MHz、GPIO_Speed_2MHz和GPIO_Speed_50MHz三个含义(其中GPIO_Speed_10MHz已经定义为1,读者必须知道GPIO_Speed_2MHz则依次被编译器赋予2,而GPIO_Speed_50MHz为3)。同样也在“stm32f10x_gpio.h”文件中找到对GPIOMode_TypeDef的定义:typedef enumGPIO_Mode_AIN = 0x0,GPIO_Mode_IN_FLOATING = 0x04,GPIO_Mode_IPD = 0x28,GPIO_Mode_IPU = 0x48,GPIO_Mode_Out_OD =

5、0x14,GPIO_Mode_Out_PP = 0x10,GPIO_Mode_AF_OD = 0x1C,GPIO_Mode_AF_PP = 0x18GPIOMode_TypeDef;这同样是一个枚举类型同义字,其成员有GPIO_Mode_AIN、GPIO_Mode_AF_OD等(也可以轻易判断出这表示GPIO设备的工作模式)。至此对程序段一的1解析可以做一个总结:该行定义一个结构体类型的变量GPIO_InitStructure,并且该结构体有3个成员,分别为GPIO_Pin、GPIO_Speed和GPIO_Mode,并且GPIO_Pin表示GPIO设备引脚GPIO_Speed表示GPIO设备速

6、率和GPIO_Mode表示GPIO设备工作模式。接下来是2,此句是一个赋值语句,把GPIO_Pin_4赋给GPIO_InitStructure结构体中的成员GPIO_Pin,可以在“stm32f10x_gpio.h”文件中找到对GPIO_Pin_4做的宏定义:#define GPIO_Pin_4 (u16)0x0010)因此2的本质是将16位数0x0010赋给GPIO_InitStructure结构体中的成员GPIO_Pin。3语句和2相似将GPIO_Speed_50MHz赋给GPIO_InitStructure结构体中的成员GPIO_Speed,但注意到此处GPIO_Speed_50MHz只

7、是一个枚举变量,并非具体的某个值。4语句亦和2语句类似,把GPIO_Mode_Out_PP赋给GPIO_InitStructure结构体中的成员GPIO_Mode,从上文可知GPIO_Mode_Out_PP的值为0x10。5是一个函数调用,即调用GPIO_Init函数,并提供给该函数2个参数,分别为GPIOA和&GPIO_InitStructure,其中&GPIO_InitStructure表示结构体变量GPIO_InitStructure的地址,而GPIOA则在“stm32f10x_map.h”文件中找到定义:#ifdef _GPIOA#define GPIOA (GPIO_TypeDef

8、*) GPIOA_BASE)#endif此三行代码是一个预编译结构,首先判断是否定义了宏_GPIOA。可以在“stm32f10x_conf.h”中发现对_GPIOA的定义为:#define _GPIOA这表示编译器会将代码中出现的GPIOA全部替换为(GPIO_TypeDef *) GPIOA_BASE)。从该句的C语言语法可以判断出(GPIO_TypeDef *) GPIOA_BASE)的功能为将GPIOA_BASE强制类型转换为指向GPIO_TypeDef类型的结构体变量。如此则需要找出GPIOA_BASE的含义,依次在“stm32f10x_map.h”文件中找到:#define GPIO

9、A_BASE (APB2PERIPH_BASE + 0x0800)和:#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)还有:#define PERIPH_BASE (u32)0x40000000)明显GPIOA_BASE表示一个地址,通过将以上3个宏展开可以得到:GPIOA_BASE = 0x40000000 + 0x10000 + 0x0800此处的关键便在于0x40000000、0x10000和0x0800这三个数值的来历。读者应该通过宏名猜到了,这就是STM32微控制器的GPIOA的设备地址。通过查阅STM32微控制器开发手册可以得知,STM

10、32的外设起始基地址为0x40000000,而APB2总线设备起始地址相对于外设基地址的偏移量为0x10000,GPIOA设备相对于APB2总线设备起始地址偏移量为0x0800。对5句代码进行一个总结:调用GPIO_Init函数,并将STM32微控制器的GPIOA设备地址和所定义的结构体变量GPIO_InitStructure的地址传入。以上是对GPIOA初始化库函数的剖析,现继续转移到函数内部分析,GPIO_Init函数原型如程序段二:void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)u32 curre

11、ntmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;u32 tmpreg = 0x00, pinmask = 0x00;assert_param(IS_GPIO_ALL_PERIPH(GPIOx);assert_param(IS_GPIO_MODE(GPIO_InitStruct-GPIO_Mode);assert_param(IS_GPIO_PIN(GPIO_InitStruct-GPIO_Pin);currentmode = (u32)GPIO_InitStruct-GPIO_Mode) & (u32)0x0F);if (

12、u32)GPIO_InitStruct-GPIO_Mode) & (u32)0x10) != 0x00)assert_param(IS_GPIO_SPEED(GPIO_InitStruct-GPIO_Speed);currentmode |= (u32)GPIO_InitStruct-GPIO_Speed;if (u32)GPIO_InitStruct-GPIO_Pin & (u32)0x00FF) != 0x00)tmpreg = GPIOx-CRL;for (pinpos = 0x00; pinpos 0x08; pinpos+)pos = (u32)0x01) GPIO_Pin) & p

13、os;if (currentpin = pos)pos = pinpos 2;pinmask = (u32)0x0F) pos;tmpreg &= pinmask;tmpreg |= (currentmode GPIO_Mode = GPIO_Mode_IPD)GPIOx-BRR = (u32)0x01) GPIO_Mode = GPIO_Mode_IPU)GPIOx-BSRR = (u32)0x01) CRL = tmpreg;if (GPIO_InitStruct-GPIO_Pin 0x00FF)tmpreg = GPIOx-CRH;for (pinpos = 0x00; pinpos 0

14、x08; pinpos+)pos = (u32)0x01) GPIO_Pin) & pos);if (currentpin = pos)pos = pinpos 2;pinmask = (u32)0x0F) pos;tmpreg &= pinmask;tmpreg |= (currentmode GPIO_Mode = GPIO_Mode_IPD)GPIOx-BRR = (u32)0x01) GPIO_Mode = GPIO_Mode_IPU)GPIOx-BSRR = (u32)0x01) CRH = tmpreg;这段程序的流程是:首先检查由结构体变量GPIO_InitStructure所传

15、入的参数是否正确,然后对GPIO寄存器进行“保存修改写入”的操作,完成对GPIO设备的设置工作。显然,结构体变量GPIO_InitStructure所传入参数的目的是设置对应GPIO设备的寄存器。而STM32的参考手册对关于GPIO设备的设置寄存器的描述如下图1和表1(仅列出低八位引脚寄存器描述,高八位引脚类同):attach65378/attach该寄存器为32位,其中分为8份,每份4位,对应低八位引脚的设置。每一个引脚的设置字分为两部分,分别为CNF和MODE,各占两位空间。当MODE的设置字为0时,表示将对应引脚配置为输入模式,反之设置为输出模式,并有最大翻转速率限制。而当引脚配置为输出

16、模式时,CNF配置字则决定引脚以哪种输出方式工作(通用推挽输出、通用开漏输出等)。通过对程序的阅读和分析不难发现,本文最初程序段中GPIO_InitStructure所传入参数的对寄存器的作用如下:1、GPIO_Pin_4被宏替换为0x0010,对应图1可看出为用于选择配置GPIOx_CRL的19:16位,分别为CNF41:0、MODE41:0。2、GPIO_Speed_50MHz为枚举类型,包含值0x03,被用于将GPIOx_CRL位中的MODE41:0配置为b11(此处b意指二进制)。3、GPIO_Mode亦为枚举类型,包含值0x10,被用于将GPIOx_CRL位中的MODE41:0配置为

17、b00。事实上GPIO_Mode的值直接影响寄存器的只有低四位,而高四位的作用可以从程序段二中看出,是用于判断此参数是否用于GPIO引脚输出模式的配置。至此应不难知道STM32的固件库最后是怎样影响最底层的寄存器的。总结起来就是:固件库首先将各个设备所有寄存器的配置字进行预先定义,然后封装在结构或枚举变量中,待用户调用对应的固件库函数时,会根据用户传入的参数从这些封装好的结构或枚举变量中取出对应的配置字,最后写入寄存器中,完成对底层寄存器的配置。可以看到,STM32的固件库函数对于程序开发人员来说是十分便利的存在,只需要填写言简意赅的参数就可以在完全不关心底层寄存器的前提下完成相关寄存器的配置,具有相当不错的通用性和易用性,也采取了一定措施保证库函数的安全性(主要引入了参数检查函数assert_param)。但同时也应该知道,通用性、易用性和安全性的代价是加大了代码量,同时增加了一些逻辑判断代码造成了一定的时间消耗,在对时间要求比较苛刻的应用场合需要评估使用固件库函数对程序运行时间所带来的影响。读者在使用STM32的固件库函数进行程序开发时,应该意识到这些问题。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1