使用寄存器点亮跑马灯

使用寄存器点亮跑马灯

寄存器

其实不管用库函数法还是位操作,其本质都是操作STM32单片机的寄存器。那什么是寄存器呢?先来给寄存器下个定义
寄存器就是给特定的内存单元取一个别名,这个别名就是我们常说的寄存器。这里的重点是"内存单元"如下栗子
在这里插入图片描述
上图来自于STM32官方数据手册,左边是地址,右边是相对应的外设。而寄存器就是,给这些地址取的一个别名。那为什么要这么做?如果我要给GPIOB的端口全部输出1,不用寄存器,即直接对地址进行操作:
在这里插入图片描述
每次这么操作很麻烦有木有。如果使用寄存器就会方便很多。
在这里插入图片描述
说白了,就是将端口的地址用宏定义定义好了。我们直接使用宏定义后的名称就好。当然,对于地址的宏定义是不需要我们操作的,我们直接操作相关的寄存器就好了。在每个引脚里面,很多的寄存器,可以看到这些寄存器相对于基地址的偏移。以GPIOB为例。
在这里插入图片描述

明白了什么是寄存器,再来看看怎么通过寄存器点亮跑马灯。

步骤:

1. 时钟使能
2. GPIO配置
3. 点亮

步骤和库函数法一样,不过操作内容有区别。

1) 时钟使能

还是以PA8和PD2为例,时钟使能操作如下

RCC->APB2ENR|=1<<2;  //使能GPIO.A时钟
RCC->APB2ENR|=1<<5;   //使能GPIO.D时钟

怎么实现的?通过查阅芯片数据手册,我们可以看到GPIO的端口,都是挂载在APB2总线上的
在这里插入图片描述
APB2是由RCC时钟进行控制的,因此,我们要进行时钟使能,就是要配置其寄存器。还是查阅数据手册,可以看到RCC_APB2RSTR寄存器,这是16位寄存器
在这里插入图片描述
在这里插入图片描述
可以看到,我们需要配置的PA和PD分别位该寄存器的第2位和第5位
直接给其写入1即可。所以有了这一步。

RCC->APB2ENR|=1<<2;  //使能GPIO.A时钟
RCC->APB2ENR|=1<<5;   //使能GPIO.D时钟

**2)**GPIO配置

接下来,配置GPIO相关的寄存器。GPIO的寄存器在上面有展示,
端口配置低寄存器(GPIOx_CRL) (x=A…E)
端口配置高寄存器(GPIOx_CRH) (x=A…E)
端口输入数据寄存器(GPIOx_IDR) (x=A…E)
端口输出数据寄存器(GPIOx_ODR) (x=A…E)
端口位设置/清除寄存器(GPIOx_BSRR) (x=A…E)
端口位清除寄存器(GPIOx_BRR) (x=A…E)
端口配置锁定寄存器(GPIOx_LCKR) (x=A…E)

我们需要使用的端口配置寄存器和端口输出寄存器。端口配置寄存器分为高8位CRH和低8位CRL,根据输出引脚而定。例如输出引脚是PA15,则用高八位寄存器CRH配置,同样,若输出引脚为PA2,则用低八位寄存器CRL配置。我们这里引脚为PA8和PD2,因此用高八位配置和低八位配置。以低八位PD2配置为例

在这里插入图片描述
这里我们需要做的工作是:

1. 找准引脚口
2. 配置正确的输出模式、速度

在这里插入图片描述
上图的四位为一个引脚,该寄存器32位一共对应8个引脚。PD2为第三个引脚,因此为8、9、10、11位。配置PA8也参考此方法,不过是在CRH寄存器中。
CNFy[1:0]:用于配置输出模式。MODEy[1:0]:用于配置输出速度。

00:通用推挽输出模式                   
01:通用开漏输出模式
10:复用功能推挽输出模式
11:复用功能开漏输出模式
00:输入模式(复位后的状态)
01:输出模式,最大速度10MHz
10:输出模式,最大速度2MHz
11:输出模式,最大速度50MHz

选择输出模式为推挽输出模式,速度为50Mhz。因此配置为0011,16进制表示为03

GPIOD->CRL&= 0xFFFFF0FF;    //PD2  第二位清零
GPIOD->CRL|= 0x00000300;   //设置输出模式、输出速度。这两步就配置好了CRL

配置时需要先对寄存器数据与运算进行清零,然后进行或运算写入

端口配置好以后,再配置数据输出寄存器:
在这里插入图片描述
这是低16位寄存器,根据引脚直接写入1即可,简单粗暴

GPIOD->ODR|=1<<2;      //ODR寄存器给PTD.2第二个口高位.

这样就配置好了关于PD2的寄存器,PA8同样是使用该寄存器写入数据。

3) 点亮


    GPIOA->ODR|=1<<8;   //ODR是数据输出寄存器
    GPIOD->ODR=~(1<<2);   //取非运算 
  
    delay_ms(300);
    
    GPIOD->ODR|=1<<2; 
    GPIOA->ODR=~(1<<8);
	delay_ms(300);

通过取非运算,操作ODR寄存器,来控制灯的熄灭。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值