STM32单片机(五)-寄存器地址理解和控制LED闪烁

2019-08-23来源: eefocus关键字:STM32  单片机  寄存器地址  控制LED闪烁

芯片:stm32f103zet6


1、存储单元一般应具有存储数据和读写数据的功能,一般以8位二进制作为一个存储单元,也就是一个字节.每个单元有一个地址,是一个整数编码,可以表示为二进制整数。


2、stm32是32位单片机,说明基本的寄存器是32位的,4字节。内存地址需要4位


3、基址也就是基础地址,最开始的地址,这个查看芯片手册,是人家规定的。


4、偏移,即偏移地址,一般是正整数,也是增加的数字。比如基址是10,偏移是4,地址就是10+4=14.


下面STM32F10xxx中内置外设的起始地址。


每个外设的起始地址就是,每个外设的基址了,当然这个基址也可以再分解为基址和偏移地址。


比如,GPIOB的起始地址是0X4001 0C00,可以分解为


片上外设基地址:0x40000000    GPIO都挂载到APB2总线:APB2偏移:0x10000,RCC在APB2总线的偏移是 0x0C00


GPIOB外设上有什么寄存器呢? 


 

 

看看其中的CRL寄存器,偏移是0x00 。如果要找GPIOB的CRL寄存器,则起始地址0X4001 0C00+偏移0x00


 

ODR偏移是0x0C,如果要找GPIOB的ODR寄存器,则起始地址0X4001 0C00+偏移0x0C


 来,用用吧。


我就让我的开发板的一个LED闪烁。


电路是这样的


现在要让GPIOB0输出低电平,灯亮,高电平,灯灭。


stm32使用一个外设得使能相应的时钟,即RCC。


我现在要使用GPIOB0,首先使能GPIOB的时钟,时钟也是寄存器控制的啊,查上面的地址表,RCC的基址是


0x40021000,使能GPIOB的时钟,它是由RCC_APB2ENR控制的,因为挂在APB2总线上。偏移是0x18


则RCC_APB2ENR地址:0x40021000+0x18=0x40021018

再设置GPIOB的IO模式,CRL寄存器控制。(CRL控制低8位引脚IO的模式,CRH控制高八位IO的模式,四位控制一个io的模式,一个寄存器控制8个引脚,共32位,一个寄存器)

 设置GPIOB的电平高低,ODR寄存器控制(直接对相应的引脚,写入1或者0就行,1,高电平,0,低电平)

 工程文件结构:起始文件,头文件,源文件


/*  片上外设基地址  */

#define PERIPH_BASE              ((unsigned int)0x40000000)

 

/*  总线基地址,GPIO都挂载到APB2上 */

#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)

 

/*  GPIOB外设基地址  */

#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

 

/*  GPIOB寄存器地址,强制转换成指针  */

#define GPIOB_CRL *(unsigned int*) (GPIOB_BASE+0x00)

#define GPIOB_CRH *(unsigned int*) (GPIOB_BASE+0x04)

#define GPIOB_IDR *(unsigned int*) (GPIOB_BASE+0x08)

#define GPIOB_ODR *(unsigned int*) (GPIOB_BASE+0x0C)

#define GPIOB_BSRR *(unsigned int*) (GPIOB_BASE+0x10)

#define GPIOB_BRR *(unsigned int*) (GPIOB_BASE+0x14)

#define GPIOB_LCKR *(unsigned int*) (GPIOB_BASE+0x18)

 

/*  RCC外设基地址   */

#define RCC_BASE (0x40021000  +  0x1000) 

/* RCC的AHB1时钟使能寄存器地址,强制转换成指针  */

#define RCC_APB2ENR     *(unsigned int*)(RCC_BASE+0x18)

SystemInit()是为了骗过启动文件,这里应该配置时钟树,下次再讲。 对于那些逻辑运算不懂,看前面的stm32编程要点。


#include "stm32f1.h"

 

void SystemInit()

 

{

 

}

 

void delay(int t)

 

{

 

int i;

 

for( ;t>0; t--)

 

for(i=0;i<2000;i++);

 

}

 

int main(void)

{

RCC_APB2ENR |= (1<<3);

 

//清空控制PB0的端口

GPIOB_CRL &= ~(0x0F<<(4*0)); 

//配置PB0为通用推挽输出,速度为50M

GPIOB_CRL |= (0x03<<(4*0));

 

while(1)

{

GPIOB_ODR =0x00;

delay(1000);

GPIOB_ODR =0x01;

delay(1000);

}

}

现在我们怎么算这个偏移呢,我也是理解了好一会,只能说C语言还不够。

有了首地址  0x4002 3830  

也可以直接加偏移量,用宏定义。


在正点原子中,利用的是,结构体的内存对齐原则

**内存对齐,对齐规则是按照成员的声明顺序,依次安排内存,其偏移量为成员大小的整数倍,0看做任何成员的整数倍,最后结构体的大小为最大成员的整数倍**可以参考下面两篇文章。

https://blog.csdn.net/shi2huang/article/details/80290192

https://blog.csdn.net/weixin_40853073/article/details/81451792


好好理解 变量的地址,值,内存,之间的关系。很容易懵。下面会具体举例


再来理解  结构体  RCC_TypeDef 

因为每个寄存器变量都是32位的值,4个字节,所以占4个内存地址


所以每个变量代表的地址偏移量都是4的倍数,例如

typedef struct

{

  __IO uint32_t CR;            /*!< RCC clock control register,                                  Address offset: 0x00 */

  __IO uint32_t PLLCFGR;       /*!< RCC PLL configuration register,                              Address offset: 0x04 */

  __IO uint32_t CFGR;          /*!< RCC clock configuration register,                            Address offset: 0x08 */

  __IO uint32_t CIR;           /*!< RCC clock interrupt register,                                Address offset: 0x0C */

  __IO uint32_t AHB1RSTR;      /*!< RCC AHB1 peripheral reset register,                          Address offset: 0x10 */

  __IO uint32_t AHB2RSTR;      /*!< RCC AHB2 peripheral reset register,                          Address offset: 0x14 */

  __IO uint32_t AHB3RSTR;      /*!< RCC AHB3 peripheral reset register,                          Address offset: 0x18 */

  uint32_t      RESERVED0;     /*!< Reserved, 0x1C                                                                    */

  __IO uint32_t APB1RSTR;      /*!< RCC APB1 peripheral reset register,                          Address offset: 0x20 */

  __IO uint32_t APB2RSTR;      /*!< RCC APB2 peripheral reset register,                          Address offset: 0x24 */

  uint32_t      RESERVED1[2];  /*!< Reserved, 0x28-0x2C                                                               */

  __IO uint32_t AHB1ENR;       /*!< RCC AHB1 peripheral clock register,                          Address offset: 0x30 */

  __IO uint32_t AHB2ENR;       /*!< RCC AHB2 peripheral clock register,                          Address offset: 0x34 */

  __IO uint32_t AHB3ENR;       /*!< RCC AHB3 peripheral clock register,                          Address offset: 0x38 */

  uint32_t      RESERVED2;     /*!< Reserved, 0x3C                                                                    */

  __IO uint32_t APB1ENR;       /*!< RCC APB1 peripheral clock enable register,                   Address offset: 0x40 */

  __IO uint32_t APB2ENR;       /*!< RCC APB2 peripheral clock enable register,                   Address offset: 0x44 */

  uint32_t      RESERVED3[2];  /*!< Reserved, 0x48-0x4C                                                               */

  __IO uint32_t AHB1LPENR;     /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */

  __IO uint32_t AHB2LPENR;     /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */

  __IO uint32_t AHB3LPENR;     /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */

  uint32_t      RESERVED4;     /*!< Reserved, 0x5C                                                                    */

  __IO uint32_t APB1LPENR;     /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */

__IO uint32_t APB2LPENR; /*!< RCC APB2 per

[1] [2]

关键字:STM32  单片机  寄存器地址  控制LED闪烁

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic472351.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:移植freeRTOS V10.2.0到stm32f103zet6
下一篇:STM32单片机(三)-基本的工程文件介绍

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

第8章 自己写库-构建库函数雏形—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F429规格书》虽然我们上面用寄存器点亮了 LED,乍看一下好像代码也很简单,但是我们别侥幸以后就可以一直用寄存器开发。在用寄存器点亮 LED 的时候,我们会发现 STM32 的寄存器都是 32 位的,每次配置的时候都要对照着《STM32F4xx参考手册》中寄存器的说明,然后根据说明对每个控制的寄存器位写入特定参数,因此在配置的时候非常容易出错,而且代码还很不好理解,不便于维护。所以学习 STM32 最好的方法是用软件库,然后在软件库的基础上了解底层,学习遍所有寄存器。8.1 什么是STM32函数库以上所说的软件库是指"STM32标准函数库",它是
发表于 2019-09-18
第8章 自己写库-构建库函数雏形—零死角玩转STM32-F429系列

第9章 初识STM32固件库—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx参考手册》、《STM32F4xx规格书》、《Cortex-M3权威指南》, STM32标准库帮助文档:《stm32f4xx_dsp_stdperiph_lib_um.chm》。在上一章中,我们构建了几个控制GPIO外设的函数,算是实现了函数库的雏形,但GPIO还有很多功能函数我们没有实现,而且STM32芯片不仅仅只有GPIO这一个外设。如果我们想要亲自完成这个函数库,工作量是非常巨大的。ST公司提供的标准软件库,包含了STM32芯片所有寄存器的控制操作,我们直接学习如何使用ST标准库,会极大地方便控制STM32芯片。9.1 CMSIS标准及库层次关系因为基于Cortex系列芯片采用的内核都是相同
发表于 2019-09-18
第9章 初识STM32固件库—零死角玩转STM32-F429系列

第14章 启动文件详解—零死角玩转STM32-F429系列

本章参考资料《STM32F4xx 中文参考手册》第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表;MDK中的帮助手册—ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令。14.1 启动文件简介启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:1、初始化堆栈指针SP=_initial_sp2、初始化PC指针=Reset_Handler3、初始化中断向量表4、配置系统时钟5、调用C库函数_main初始化用户堆栈,从而最终调用main函数去到C的世界14.2 查找ARM汇编指令在讲解启动代码的时候,会涉及到ARM的汇编指令
发表于 2019-09-18
第14章 启动文件详解—零死角玩转STM32-F429系列

第15章 RCC—使用HSE/HSI配置时钟—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx中文参考手册》RCC章节。学习本章时,配合《STM32F4xx中文参考手册》RCC章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。RCC :reset clock control  复位和时钟控制器。本章我们主要讲解时钟部分,特别是要着重理解时钟树,理解了时钟树,F429的一切时钟的来龙去脉都会了如指掌。1.1 RCC主要作用—时钟部分设置系统时钟SYSCLK、设置AHB分频因子(决定HCLK等于多少)、设置APB2分频因子(决定PCLK2等于多少)、设置APB1分频因子(决定PCLK1等于多少)、设置各个外设的分频因子;控制AHB、APB2和APB1这三条总线时钟的开启、控制
发表于 2019-09-18
第15章 RCC—使用HSE/HSI配置时钟—零死角玩转STM32-F429系列

第16章 STM32中断应用概览—零死角玩转STM32-F429系列

本章参考资料《STM32F4xx 中文参考手册》第十章-中断和事件、《 ARM Cortex™-M4F 技术参考手册》-4.3 章节:NVIC和4.4章节:SCB—4.4.5的AIRCR。STM32中断非常强大,每个外设都可以产生中断,所以中断的讲解放在哪一个外设里面去讲都不合适,这里单独抽出一章来做一个总结性的介绍,这样在其他章节涉及到中断部分的知识我们就不用费很大的篇幅去讲解,只要示意性带过即可。本章如无特别说明,异常就是中断,中断就是异常,请不要刻意钻牛角尖较劲。16.1 异常类型F429在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常有10个,外部中断有91个。除了个别异常的优先级被定死外
发表于 2019-09-18
第16章 STM32中断应用概览—零死角玩转STM32-F429系列

第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx中文参考手册》系统配置控制器以及中断和事件章节。上一章节我们已经详细介绍了NVIC,对STM32F4xx中断管理系统有个全局的了解,我们这章的内容是NVIC的实例应用,也是STM32F4xx控制器非常重要的一个资源。学习本章时,配合《STM32F4xx中文参考手册》系统配置控制器以及中断和事件章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。特别说明,本书内容是以STM32F42xxx系列控制器资源讲解。17.1 EXTI简介外部中断/事件控制器(EXTI)管理了控制器的23个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI可以实现
发表于 2019-09-18
第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列

小广播

何立民专栏

单片机及嵌入式宝典

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

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