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 peripheral clock enable in low power mode register, Address offset: 0x64 */

  uint32_t      RESERVED5[2];  /*!< Reserved, 0x68-0x6C                                                               */

  __IO uint32_t BDCR;          /*!< RCC Backup domain control register,                          Address offset: 0x70 */

  __IO uint32_t CSR;           /*!< RCC clock control & status register,                         Address offset: 0x74 */

  uint32_t      RESERVED6[2];  /*!< Reserved, 0x78-0x7C                                                               */

  __IO uint32_t SSCGR;         /*!< RCC spread spectrum clock generation register,               Address offset: 0x80 */

  __IO uint32_t PLLI2SCFGR;    /*!< RCC PLLI2S configuration register,                           Address offset: 0x84 */

  __IO uint32_t PLLSAICFGR;    /*!< RCC PLLSAI configuration register,                           Address offset: 0x88 */

  __IO uint32_t DCKCFGR;       /*!< RCC Dedicated Clocks configuration register,                 Address offset: 0x8C */

[1] [2]
关键字:STM32  单片机  寄存器地址  控制LED闪烁 引用地址:STM32单片机(五)-寄存器地址理解和控制LED闪烁

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

推荐阅读最新更新时间:2024-11-13 03:49

基于小型MCULED照明的色彩控制方案
在大趋势下,LED用于通用照明指日可待。LED在通用照明中优势很多,如寿命更长以及效率更高。然而, LED技术还面临着一些挑战。其中一个挑战就是如何产生高品质的白光。白光LED的构成包含了蓝光LED和能将光输出移至光谱的其他波段的一种荧光粉。许多白光LED都无法产生高显色指数(Color Rendering Index,CRI),该参数用于衡量光源真实重现色彩的能力。   通过混合两种或两种以上颜色的LED光,可以获得品质更高的白光系统。在这些多色系统中,每种色源的光输出会随时间和温度而漂移。光传感器和小型单片机 (MCU)可用于维持特定颜色和相关色温(CorrELated Color Temperature,CCT)。在本文中
[模拟电子]
基于小型<font color='red'>MCU</font>的<font color='red'>LED</font>照明的色彩<font color='red'>控制</font>方案
仿生液压四足机器人伺服控制器设计
引言 近年来各类军用机器人在国防领域和地缘战略中发挥着重要的作用。在我国广大西部地区,由于地形复杂、道路崎岖,传统的轮式或履带式机器人无法满足地形通过性要求,而仿生四足机器人能够较好地满足在非结构化地形条件下可靠行进的任务需求。液压驱动的仿生四足机器人是近年国内外的研究热点与主攻项目,在其关键技术群中,电液伺服控制技术则是保障仿生液压四足机器人实现稳定行进功能的核心技术。 1总体设计 1.1控制对象分析 本文依托北京理工大学特种机器人技术创新中心正在研发的一款仿生液压四足机器人展开研究,机器人每条腿具有3个主动自由度和1个被动自由度,分别为髋侧摆关节、髋正摆关节、膝关节和足部二阶弹簧减震器,全部12个主动关节均由液
[单片机]
仿生液压四足机器人伺服<font color='red'>控制</font>器设计
STM32控制步进电机源代码
单片机源程序如下: #include stm32f10x.h #include stm32f10x_rcc.h #include misc.h void RCC_Configuration(void); void GPIO_Configuration(void); void ZhengZhuan(u16 tt); void FanZhuan(u16 tt); void delay_ms(u16 nms); /**************************************************************************** * 名 称:int main(void) * 功 能:
[单片机]
<font color='red'>STM32</font><font color='red'>控制</font>步进电机源代码
全新MCX W系列MCU赋能更广阔连接
基于MCX N和MCX A系列微控制器取得的成功,恩智浦发布支持多协议无线连接的MCX W系列。作为MCX广泛产品组合的重要成员,MCX W系列具有与MCX产品其他系列相同的Arm® Cortex®-M33内核,并与MCX产品其他系列共享外设平台。 MCX W系列的亮点在于其支持多种无线标准,包括Matter、Thread、Zigbee和低功耗蓝牙等,从而为整个MCX产品组合带来无线连接的新可能。 MCX W将成为MCX产品组合无线应用的首选解决方案。 目标应用场景广泛,涵盖: 工业和物联网的边缘传感器与控制器 商业楼宇的门禁控制、分布式照明和窗帘等基础设施产品 智能家居设备,如智能锁、灯光控制系统、智能
[嵌入式]
全新MCX W系列<font color='red'>MCU</font>赋能更广阔连接
#51单片机#UART串口通信的初步认识
UART串口通信 UART,全称Universal Asynchronous Receiver/Transmitter,即通用异步收发器。 串口通信是单片机中最常用的一种技术,通常用于单片机和计算机之间以及单片机和单片机之间的通信。 UART的通信类型可分为两种,并行通信和串行通信。 并行通信:数据各个位同时传送,可实现以字节为单位来通信。缺点:通信线占用资源多,成本高。 串行通信:一次只传输一个字节的数据。 STC89C52有两个专门的UART通信引脚,P3.0(RXD)和P3.1(TXD),由它们组成的通信接口叫串行接口,简称串口。 下图体现了两个单片机相互收发信息的过程: 图中两单片机的GND互连
[单片机]
#51<font color='red'>单片机</font>#UART串口通信的初步认识
C52单片机定时器2介绍
定时器2是一个16位定时器/计数器,通过设置特殊功能寄存器T2CON中的C/T2位可将其设置为定时器或是计数器;通过设置T2CON中的工作模式选择位可将定时器2设置为三种工作模式,分别为捕获、自动重新装载(递增或是递减计数)和波特率发生器。 知识点一、定时器2的控制寄存器T2CON(可按位寻址)* D7位--TF2:定时器2溢出标志位。用于请求中断(必须由软件清0) D6位--EXF2:定时器外部标志位。当外部信号使能时,发生外部负跳变时置位请求中断(必须由软件清0) D5位--RCLK:接受时钟标志位。默认情况下串行口中模式1和模式3的时钟是由定时器1的溢出率提供,若该位置位,则由定时器2提供。 D4位--TCLK:发送时钟
[单片机]
51单片机系列知识12--串行通信(3)
二、 扩展引申 1、 多机通信 多机通信网络通常有5种网络形式:(a)星型网络结构 (b)树型网络结构(c)总线型网络结构(d)环型网络结构(e)分散型网络结构 它们各有优缺点 △ 有没有细想一下,各种网络结构有其优缺点的原因? 主从式总线型网路多机通信: 利用51单片机串行口工作方式2、3及SM2和RB8的配合完成主从式的多机通信 主机和系统中的某一从机通信时,先发出通信联络命令,与指定的从机相互确认后才进行正式的通信(具体的通信过程,见教材P137) △ 有时间,有机会将以上的主从机通过程的流程图画出来。 通信协议: 多机通信时,主、从机双方都应符合一定的规范,因此人为地制订了一些协议。这些
[单片机]
51<font color='red'>单片机</font>系列知识12--串行通信(3)
51单片机入门教程(3)——数码管显示
一、LED数码管简介 LED数码管(LED Segment Displays)是由多个发光二极管封装在一起组成的器件。常见的LED数码管为“8”字型的,共计8段。每一段对应一个发光二极管。 数码管有共阳极和共阴极两种 共阴极: 数码管的发光二极管的阴极连在一起,通常公共阴极接地。当阳极为高电平时,发光二极管点亮。 共阳极: 数码管的发光二极管的阳极连在一起,公共阳极接正电压,当某个发光二极管的阴极接低电平时,发光二极管被点亮,相应的段被显示。 二、数码管静态显示 数码管静态显示就是无论多少位LED数码管,同时处于显示状态。 为了使数码管显示不同的符号或数字,只需要把某些段发光二极管点亮就可以了。 假设在共阴极的
[单片机]
51<font color='red'>单片机</font>入门教程(3)——数码管显示
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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