历史上的今天

今天是:2024年08月26日(星期一)

正在发生

2018年08月26日 | STM32寄存器操作简单介绍

发布者:Meilin8888 来源: eefocus关键字:STM32  寄存器操作 手机看文章 扫描二维码
随时随地手机看文章

STM32单片机可以使用库函数进行操作,再加上现在越来越强大的MDK ARM编译环境,使用库函数开发简直是不二的选择,但是工具越来越强大的同时意味着对编程人员降低了要求,在很大程度上降低了准入门槛,我们因此高兴吗?我倒是觉得这很像温水煮青蛙,所以库函数固然好用却也不应该抛弃最初的做法——寄存器操作。

先从启动文件开始介绍:这里介绍比较常见的一种启动方式(从内部的的FLASH启动,至于另外两个是否常用本人不甚了解),在启动代码了首先对栈和堆的大小进行定义,并在代码的起始处建立中断向量表,其第一个表项是栈顶(__initial_sp )地址,第二个表项是复位中断服务( Reset_Handler )入口地址。然后在复位中断服务程序中跳转C/C++标准实时库的__main函数,完成用户堆栈等的初始化后,跳转.c文件中的main函数开始执行C程序。STM32从内部FLASH启动,中断向量表起始地位为0x8000000,则栈顶地址存放于0x8000000处,而复位中断服务入口地址存放于0x8000004处。当STM32遇到复位信号后,则从0x80000004处取出复位中断服务入口地址,继而执行复位中断服务程序,然后跳转__main函数,完成这些事情在才始进入最耗费我们精力的main函数。以上内容是否重要,因项目而异,不过栈大小和堆大小可能会需要改动的,如果有机会学习cortex-A系列的SoC,比如三星的S5PV210之类一定会接触到启动文件(bootloader)的。

一个插曲,就是systeminit ,这个函数在官方提供的3.5版本的固件库的启动文件里是在main函数之前运行的,也就是说在官方给的库函数里面是有这个函数的,并且里面的内容是官方给出的,目的是设置系统的频率,一般是72M,但是我希望直接操作寄存器一定要写这个函数吗,或者一定要在main函数之前执行吗,答案是不一定,一个简单粗暴的办法就是直接写一个空的systeminit函数,写一个空的并不建议因为毕竟要调整这个SoC各个总线的频率,不如添加上。直接在启动文件里删去关于systeminit的代码也是可以的,在之后的操作里面写main函数的时候先调用systeminit函数,自己设置频率。

进入主题,说说寄存器,从官方给出的存储器映像可以看出各个外设的的基地址,这些基地址在加上相应的偏移量就是我们希望的寄存器的地址,之后修改寄存器的内容就可以,原理就是这样,关键是如何构造好的数据结构对这些寄存器进行操作。下面通过实例介绍三种方法:

实例:让GPIOB0置位,方式推挽输出,思路是1、开GPIOB的时钟 2、设置输出方式 3、端口置位


第一种:直接宏定义精确到各个具体的寄存器。GPIOB开始的地址是0X40010C00,其中端口配置低寄存器(GPIOx_CRL)偏移地址是0x00,这样(0X40010C00+0x00)就是CRL寄存器的地址,使用(long *)(0X40010C00+0x00),将这个地址强制转换成指针类型,在利用*((long *)(0X40010C00+0x00))操作(0X40010C00+0x00)地址里的内容。


#define GPIOB_CRL    (*((long *)(0X40010C00+0x00)))

#define RCC_APB2ENR  (*((long *)(0x40021000+0x18)))

#define GPIOB_ODR    (*((long *)(0X40010C00+0x0C)))

这样就可以像上面的思路操作了。


RCC_APB2ENR|=(1<<3);//开GPIOB的时钟

GPIOB_CRL=3;//设置输出方式

GPIOB_ODR=0XFFFF;//端口置位

这样操作直观,但是需要的宏太多,容易出现问题,稍不留神偏移量写错就前功尽弃了。

第二种:构造结构体,将GPIO的寄存器全部写进结构体,相比上面的方法让编译器帮我们进行计算,减少出错的可能,本来像上面那样体现不出C语言这个工具的强大。首先构造


typedef struct

{

  int CRL;

  int CRH;

  int IDR;

  int ODR;

  int BSRR;

  int BRR;

  int LCKR;

} GPIO_TypeDef;

之后


#define GPIOB ((GPIO_TypeDef*)(0X40010C00))

这样就可以用指针的方式操作GPIOB的各个寄存器了,这里的GPIO_TypeDef类型的数据结构保证操作的寄存器全是GPIO的寄存器不会越界,具体的原因是C语言的问题,这里不做过多的解释,以免跑题。下面按照最开始的操作思路进行:


RCC->APB2ENR|=(1<<3);//开GPIOB的时钟

GPIOB->CRL=3;//设置输出方式

GPIOB->ODR=0XFFFF;//端口置位

显然这种方式借助C语言这个工具和编译器帮我们解决了很多的问题。

第三种方法:查看库文件stm32f10x.h有以下的宏定义


#define PERIPH_BASE           ((uint32_t)0x40000000)

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)

#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)

要知道define定义就是简单的字符串替换,替换之后的结果是


#define GPIOB   ((GPIO_TypeDef *) 0x40000000 + 0x10000 + 0x0C00)

可以看出就是第二种方法里面的


#define GPIOB ((GPIO_TypeDef*)(0X40010C00))

所以既然官方已经帮我们做好了我们为什么不用呢。所以直接包含头文件#include “stm32f10x.h” 就可以了。说到这里似乎又回到了起点,这不是还是使用了官方的库函数吗?但是这和#include 是一样的道理,只是用到了官方已经做好的寄存器名字的定义,以及一种简单的调用寄存器的方法。

使用库函数还是直接操作寄存器更好,以上的例子并没有说明问题,我们看到的只是库函数无外乎是操作寄存器,没有看到的是库函数的函数多级调用,这里不做说明。

最后一句,对于我们使用的人来说一定不要被层层的外包装所迷惑。


关键字:STM32  寄存器操作 引用地址:STM32寄存器操作简单介绍

上一篇:STM32 GPIO几个寄存器的理解
下一篇:STM32库函数和寄存器操作的思考

推荐阅读

四年成就行业黑马哈工大机器人集团(HRG)成立于2014年12月,由黑龙江省政府、哈尔滨市政府、哈尔滨工业大学联合创建,现在哈工大机器人集团已经由一个行业新人一跃成为了排头兵。销售额从第一年的3亿元,到后来的6亿元,再到2017年的10亿元。如今,企业市场估值已达40多亿元。除了上述产品,哈工大机器人集团在智慧工厂、工业机器人、服务机器人、特种机...
为了提高电网的功率因数,减少干扰,平板电视的大多数电源都采用了有源PFC电路,尽管电路的具体形式繁多,不尽相同,工作模式也不一样(CCM电流连续型、DCM不连续型、BCM临界型),但基本的结构大同小异,都是采用BOOST升压拓扑结构。如下图所示,这是一典型的升压开关电源,基本的思想就是把整流电路和大滤波电容分割,通过控制PFC开-关管的导通使输入电流...
Galaxy S20 FE(粉丝版) 5G(将是 Galaxy S20 的低配版本)是三星正在开发的新手机,预计将于今年第四季度推出。近日,该手机的高分辨率渲染图与一些关键细节一起曝光了。消息来源来自 OnLeaks,与标准版 Galaxy S20 一样,Galaxy S20 FE 5G 将采用平面的屏幕,AMOLED 面板,采用居中的打孔设计,边框并不窄。据报道,该手机将采用金属中...
8月24日晚间,中京电子披露2021年半年度报告,报告期内公司实现营业收入13.35亿元,同比增长36.34%;实现归属于上市公司股东净利润9614.08万元,同比增长74.93%;实现扣非净利润8710.79万元,同比增长100.72%;经营活动产生的现金流量净额为1.48亿元,同比上升253.55%。公告显示,报告期内,中京电子HDI、FPC等产品持续维持较高景气度,现有惠州仲恺基地(...

史海拾趣

问答坊 | AI 解惑

IC制造工艺与光刻对准特性关系的研究

马万里,赵建明,吴纬国    (电子科技大学 微电子与固体电子学院, 成都 610054)    摘 要:主要针对光刻对准特性,从单项工艺和工艺集成的角度,分析了影响光刻对准的各个主要因素,主要包括对准标记、工艺层、 ...…

查看全部问答∨

论文

基于FPGA的多路开关稳压电源的设计…

查看全部问答∨

帮我看看12864的读数据操作写得对不对

void LcdWriteData(unsigned char data) { CheckBusy();           //忙检查 DDRB=0xff;             //数据端口设置为输出 SET_RD;     ...…

查看全部问答∨

寻找负载电路的设计

我有一个电路板,输出为直流24V,3A左右。现在想设计一个电路充当电路板负载的电路,实际应用中的负载为电磁阀和继电器。请教大师们有没有合适的电路推荐或者给点建议,先谢过。…

查看全部问答∨

基于LPC和GPS的汽车防盗系统

想用NXP LPC1000来设计一个基于LPC1114和GPS的汽车防盗系统。…

查看全部问答∨

求教debug 调试程序出现 has exited with code 0 (0x0).

第一次在开发板上测试就遇到这种奇怪问题... build 已经成功,在PPC2003模拟器上也运行正常,但是接到开发板上就出现问题,程序无法打开。 用网线联调 发现output 内容如下: Load module: /FlashDrv/My_PJtest/My_PJtest-armv4i-IngenicMedia (M ...…

查看全部问答∨

1602a与计算器

怎样将万年历与计算器和为一体用液晶1602a单独的程序已编制好。…

查看全部问答∨

ST将在9月份在全国10个城市举办STM32的技术研讨会!最新消息

ST将在9月份在全国10个城市举办STM32的技术研讨会,这次研讨会的一个主要目的是对大家在使用STM32过程中的一些疑问进行解答和澄清。目前我们正在准备一些技术方面的文档,为了更广泛的满足大家的要求,在这里我请大家提出一些建议,包括:-你 ...…

查看全部问答∨

请教音频输出用普通模拟电缆最远能传多远?

请教大家个问题,音频输出用普通模拟电缆最远能传多远?谢谢!…

查看全部问答∨

msp430+拓普微液晶屏问题。

430能直接驱动拓普微LM320240型号的液晶屏吗?能的话怎么驱动呀,望能解答。。。谢谢!…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved