stm32---1.两种开发方式点亮LED

LED简介:

  • 实物LED灯有一长一短,长的是正极,短的是负极
  • 在点亮LED的简单电路中,正极通常连接vcc,中间在连一个电阻;而负极则与单片机的引脚相连接。

因此我们就可以知晓,只需给对应引脚输出0,就可以点亮这个LED灯了,接下来就开始实操

一、以寄存器的方式点亮LED

以PA0为例:表示属于GPIOA这个模块的0号引脚,现在要给这个引脚输出一个低电平。

  • GPIO有GPIOA~GPIOX,相当于对单片机引脚进行的一个分组

基本流程:

复制代码
如果你学习过51,对于点灯这个流程,肯定非常熟悉,
只需要找到对应的引脚,隶属于哪一个寄存器,
然后给这个寄存器 控制该引脚的 某一位置0,就可以将灯点亮了
但是如果在stm32中,与之有什么差别的呢?
变的更复杂了,换句话来说,应该更具备逻辑性,为什么会这样?
在介绍基本流程过程中,我会回答这个问题。

1.时钟(RCC)配置

  • 我们使用PA0,属于GPIOA这个模块,我们需要打开这个模块的时钟,这个模块才能正常运行,所以我们需要找到它。
  • 通过下面这张系统架构图我们可以知道ABH系统总线上桥接着APB2和APB1这两根高速外设总线 ,它们需要的系统时钟频率是不同的:
    • APB1:36MHz
    • APB2:72Mhz
  • 我们要使用的GPIOA挂载在APB2这个高速外设总线上,因此我们就确认好了GPIOA的位置,也就可以进行配置。

-

回到一开始的问题:为什么需要时钟?为什么stm32需要配置时钟?为什么51不需要?

  • 时钟相当于一个指挥家,芯片内部的运行需要高低电平的变化,且具有节奏,节奏需要上升沿和下降沿来控制,因此引脚在输入输出时,需要配置配置时钟。
  • 对于51的看法,我们通常认为是落后过时,结构简单。确实如此,51单片机内部的模块少,只需统一的时钟就可以。在通电以后,内部时钟就自动打开。
  • 而32,内部结构复杂,有着许多不同模块。通过上面的系统架构图,我们就可以看到高速外设总线上挂载这许多不同设备模块。不同模块,需要的时钟不一致,有些需要高速,有些需要低速。如果采用统一的时钟,就会资源浪费。所以我们采取的策略就是哪个模块需要,就打开哪个模块的时钟。

2.配置引脚的工作模式

输出模式下,分为四种:

  • 通用推挽输出模式
  • 通用开漏输出模式
  • 复用推挽输出模式
  • 复用开漏输出模式

输入模式下,分为四种:

  • 模拟输入模式
  • 浮空输入模式
  • 上/下拉输入模式

我们采用的是通用推挽输出模式 ,即通过单片机的引脚给LED的负极输入低电平。LED理解为外设,单片机理解为内,由内而外,自然是输出。

假如单片机要读取外设的内容,比如读取传感器的内容,然后单片机要进行处理,这种由外而内,就是输入。

对于是输入还是输出,我们要站在单片机的角度去看,如果站在外设角度看,逻辑恰好相反。

对于通用和复用的区别,在后续的案列更新中,会慢慢阐述,这里简单介绍一下开漏和推挽。

  • 开漏,相当于有一个默认的输出值,但这个默认值需要我们去设置,我们设置为1。如果要输出0,就需要我们主动控制引脚输出0。
  • 推挽,可以理解为,需要我们主动介入。输出1还是0,都需要我们控制对应的引脚,置1还是置0

实际的配置过程中,我们需要配置输入还是输出,

在选择输出的时候,有多个速度选择10MHz,2MHz,还是50Mhz

最后就是具体的输出模式了

3.控制引脚输出低电平

只需要找到对应引脚的寄存器,置0就可以了

实现:

1)配置时钟

参考手册:

  • 在这个图里面,我们可以看到RCC这个寄存器表示的范围,从起始地址~末尾地址
  • 这里面包含了我们配置各种模块的时钟
  • 我们只需要在起始地址的基础上 + 对应模块时钟的偏移地址 = 对应模块配置的区域

点击后面的 存储器映像列表下对应位置 就可以跳转到如下的这张图:

  • 但是这张图传递的信息,并不详细,但也比较直观了

在目录中找到RCC寄存器:

  • 从这里我们可以知道:0X18就是GPIOA这个模块的偏移地址
  • IOPA中的A是端口A,所指的就是GPIOA
c 复制代码
//1.时钟配置

法一:

//GPIOA位于第二位,我们要给这一位置1,如果采用十进制的方式赋值,那就是赋值4
//由于我们是直接操作地址,32位基地址+8位的起始地址以后,需要进行强转,这是一个指针类型
//所以还需要进行解引用
*(uint32_t*)(0x40021000+0X18)=4; 

//我们还可以采用位运算的方式(位与):
*(uint32_t*)(0x40021000+0X18)|=1<<2; 

//事实上,直接采用地址的方式可见不便于阅读,在编写的过程中也比较的复杂,

//因此我们对此进行了一个宏定义,库文件已经帮助我们完成了这个工作

只需要包含:
#include "stm32f10x.h"

所以我们可以这样表达:
//RCC 是一个结构体指针,指向 RCC 外设的基地址(也就是我们之前说的 0x40021000)。
//-> 是 C 语言的指针成员访问符,它会自动根据结构体成员的偏移地址,计算出 APB2ENR 寄存器的实际地址(基地址 + 偏移 0x18),和我们手动计算的逻辑完全一致。
//而后面要去配置指定位时,采用_的方式衔接,这种方式可以将我们要配置的位,默认置1
RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;
  • 底层文件已经帮助我们找到配置了位,我们只需q要将其 与上 对应的寄存器 就可以了

2)配置工作模式

通过这张图我们可以知道如何配置工作模式:

  • 通过MODE多位 可以选择输入输出模式,通过CNF多位 可以选择具体的一种模式
  • 具体模式,赋值什么值,一目了然

事实上有了宏定义,我们就不需要关注要配置的位处于哪一个位置,我们只需要知道寄存器的名字,知道赋值一个怎样的值,就可以了。指定位置默认初值是1,对于这个位置的宏定义是:名字+序号

  • 除了CRL寄存器,还有CRH,CR---控制寄存器,由于每一个引脚的具体模式都需要四位完成,一个GPIO口有16个引脚,因此就需要64位,我们的stm32是32位的处理器,也就需要两个32位的寄存器存放,一个存放序号高的8个,一个存放序号低的8个。
  • 我们使用的是PA0,因此它所属的CHL,我们就要对MODE0和CNF0,进行一个操作
c 复制代码
//因为我们现在要对引脚模式进行配置
//自然它的逻辑就是:
//通过对应GPIO,比如GPIOA,找到它的成员CRL,现在就找到要进行配置的寄存器
//要在指定位置上赋值,默认值是1
//所有的GPIO的引脚包含的模式都是一样的,因此就不需要去指定是哪个GPIO

//通用推挽输出模式:MODE---11 CNF---00

//这种方式是同时控制 两位 
GPIOA->CRL&=~GPIO_CRL_CNF0; (按位取反&,指定位置 置0,其他位置不变)
GPIOA->CRL|=GPIO_CRL_MODE0; (按位或上,指定位置 置1,其他位置不变)

对照上面的那张图,我们可以发现宏定义的位就是我们目标配置的位:

除了可以同时配置两位以外,我们还可以去单独配置一位:

c 复制代码
GPIOA->CRL&=~GPIO_CRL_CNF0_1; //配置两位中的高位
GPIOA->CRL&=~GPIO_CRL_CNF0_0;//配置两位中的低位

GPIOA->CRL&=~GPIO_CRL_CNF0_1;
GPIOA->CRL&=~GPIO_CRL_CNF0_0;

3)配置引脚输出

  • 我们现在要给引脚输出0,自然是使用端口输出数据寄存器ODR,IDR是负责输入的。

  • 使用ODR是一种直接控制引脚的方式,置1就是1,置0就是0.

  • 如图我还包含了另外一个寄存器:BSRR。这是一种间接控制引脚输出的寄存器。

    • 如果给BR0置1,那就相当于输出1
    • 如果给BS0置1,那就相当于输出0
c 复制代码
//通过GPIOA找到要配置的寄存器
//然后通过GPIO找到要配置位的宏定义,通过逻辑运算,输出0
GPIOA->ODR&=~GPIO_ODR_ODR0;

二、以HAL库的方式点亮LED

(1)引脚配置



(2)时钟配置

(3)项目管理


  • 我们只需要找到主函数中的死循环,将代码的逻辑写在前面就可以了,一切的初始化工作,在图形化配置时,都帮助我做了,只需要调用HAL库就可以了

  • 转义到声明这之后,可以看到还有许多的操作

  • 继续看我们刚才使用到的函数,底层的逻辑采用BSSR寄存器,就是那个间接控制引脚上输出值的寄存器

  • 我们使用的PA0,对应的就是位0
相关推荐
项目題供诗1 分钟前
STM32-编码器接口测速(十七)
stm32·单片机·嵌入式硬件
嵌入式小站3 分钟前
STM32 零基础可移植教程 19:I2C 读写寄存器,先读一个设备 ID
stm32·单片机·嵌入式硬件
minglie121 分钟前
zynq用普通网口在局域网同步
单片机
weixin_4671822821 分钟前
Arduino进阶二|自定义类库保姆级教程(从零手写属于自己的传感器类库+完整源码)
c语言·c++·单片机·嵌入式硬件·arduino·c++面向对象·diy库文件
清风6666661 小时前
基于单片机的64位多模式流水灯控制系统设计
单片机·毕业设计·课程设计·期末大作业
进击的横打1 小时前
【车载开发系列】热敏电阻与上下拉电阻
单片机·嵌入式硬件
崇山峻岭之间2 小时前
单片机USB虚拟串口实验
单片机·嵌入式硬件
崇山峻岭之间2 小时前
单片机USB U盘实验
单片机·嵌入式硬件
点灯小铭2 小时前
基于单片机的锅炉压力与温度监测报警系统设计
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
环境倒逼我学习2 小时前
无人机地面站之第13章 Mission Planner 入门与界面总览
单片机·嵌入式硬件·无人机