• stm32 笔记 IO 口点灯实验及 HAL 库使用


    GPIO 概述

    全称:general purpose intput output,通用输入输出接口。

    顾名思义,既可作为输入框也可以作为输入口。

    引脚不一定是 GPIO,有些引脚也作为复位或晶振等使用。

    GPIO的八种工作模式

    输入:浮空输入,上拉输入,下拉输入,模拟输入

    输出:开漏输出,开漏复用功能,推挽式输出,推挽式复用功能

    输入:

    浮空输入:浮空状态上拉开关和下拉开关都是关闭,当引脚接到空气会输出无意义值

    下拉输入:GPIO 将接入带有电阻的负极,此时 CPU 接收到该 GPIO 的信号为 0,假设给这个 GPIO 一个高电平,因为电阻的关系,并不会将高电平全都吸收,此时 CPU 接收到该 GPIO 的信号为 1。意味该GPIO高电平有效。

    上拉输入:GPIO 将接入带有电阻的正极,此时 CPU 接收到该 GPIO 的信号为 1;假设给这个 GPIO 一个低电平,因为电阻的关系,并不会将低电平全都吸收,此时 CPU 接收到该 GPIO 的信号为 0。意味该GPIO低电平有效。

    模拟输入:不接入上拉和下拉电阻,绕过施密特触发器,直接进入模拟口。

    输出:

    开漏输出:有输出时只让 vss 高电平,并不设置 vdd 低电平驱动。此种输出方式,需要设置接收端需设置下拉电阻。开漏复用功能,即从外设获取信息到输出缓冲区再输出。

    推挽式输出:有信号时 vss 高,无信号时 vdd 低电平。接收端无需接上拉或下拉电阻。

    GPIO 寄存器

    每组 io 口由10个寄存器组成,如果芯片有 GPIOA~GPIOI 9个组,那么一定对应 9x10 = 10 个寄存器。

    如果一个 io 口配置两位。32 位寄存器正好配置 16 位口;如果一个 io 只需要配置一个 io 口,一般高十六位保留。

    BSRR寄存器较为抽象,来单独描述下:

    这是一个 32 位寄存器,其中 31~16 位为 BR 对其置1即对输出寄存器置1,如置0则不产生改变。

    如当前十六位寄存器值为:

    0100 0000 0000 0000

    我们对BSRR赋:

    BSRR = 1000 0000 0000 0000 0000 0000 0000 0000

     则当前寄存器值为:

    1100 000 0000 0000

    15~0 位则为 BS 寄存器复位寄存器,对其置1即对输出寄存器置0,如置0则不产生改变。

    如当前十六位寄存器值为:

    0100 0000 0000 0000

    我们对BSRR赋:

    BSRR = 0000 0000 0000 0000 0100 0000 0000 0000

     则当前寄存器值为:

    0000 000 0000 0000

    15~0 位则为 BS 寄存器复位寄存器,对其置1即对输出寄存器置0,如置0则不产生改变。

    寄存器点灯实验

    对于灯泡来说,两边电平不一致即可点亮。此时让 GPIOB0 或 GPIOB1 给出低电平即可点亮 LED0 或者 LED1。 

     所以对于 GPIOB 来说应该至少设置三个寄存器即可点亮灯泡,分别是:

    MODER 端口模式寄存器,设置为输出模式

    OTYPER 端口输出类型寄存器,设置为推挽输出(设置为开漏也可以)

    ODR 端口输出数据寄存器,设置为 0000 0000 0000 0000 全为 0 低电平即可

    寄存器电灯

    设置 GPIOB 时钟

    在设置三个寄存器之前,应先对 GPIOB 时钟进行设置:

     参考 stm32 手册 53 页,GPIOB 属于 AHB1 总线。 

     

    翻阅芯片手册,我们需要将 GPIOB 使能。

    所以 AHB1ENR 寄存器应该被赋值成 00000000 00000000 00000000 00000010

    换成十六进制代码就是:

    1. //GPIOB 时钟 使能
    2. RCC->AHB1ENR = 0x00000002;

    配置输出模式

    MODER 寄存器配置为输出模式,应该为 00000000 00000000 00000000 00000101

    十六进制:

    1. //输出模式 通用输出
    2. GPIOB->MODER = 0x00000005;

    配置输出类型

     

     

    OTYPER 寄存器配置为推挽模式,应该为 00000000 00000000 00000000 00000000

     换成十六进制代码就是:

    1. //推挽输出
    2. GPIOB->OTYPER = 0x00000000;

    寄存器配置

     

    ODR 端口输出寄存器配置为: 00000000 00000000 00000000 00000000

    低电平即可点亮灯泡,所以全设置为0

     换成十六进制代码就是:

    1. //寄存器
    2. GPIOB->ODR = 0x00000000;

    全部代码:

     在此之前需要设置整体时钟。

    1. #include "sys.h"
    2. #include "delay.h"
    3. int main(void)
    4. {
    5. Stm32_Clock_Init(360,25,2,8);//设置时钟,180Mhz
    6. delay_init(180); //初始化延时函数
    7. //GPIOB 时钟 使能
    8. RCC->AHB1ENR = 0x00000002;
    9. //输出模式 通用输出
    10. GPIOB->MODER = 0x00000005;
    11. //推挽输出
    12. GPIOB->OTYPER =0x00000000;
    13. //寄存器
    14. GPIOB->ODR = 0x00000000;
    15. }

    成功点亮 

    HAL 库点灯

    需要使用 GPIO_InitTypeDef 结构体定义寄存器类型。之后使用 HAL_GPIO_Init() 进行初始化。

     HAL_GPIO_WritePin() 函数则向GPIOB 置位

    1. int main(void)
    2. {
    3. HAL_Init(); //初始化HAL库
    4. Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
    5. delay_init(180); //初始化延时函数
    6. LED_Init(); //初始化LED
    7. GPIO_InitTypeDef GPIO_Initure;
    8. __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
    9. GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; //PB1,0
    10. GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
    11. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
    12. GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
    13. HAL_GPIO_Init(GPIOB,&GPIO_Initure);
    14. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); //PB0置1,默认初始化后灯灭
    15. HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //PB1置1,默认初始化后灯灭
    16. }

  • 相关阅读:
    Ubuntu 20.04安装Anaconda3及使用
    PDF编辑工具Acrobat Pro DC 2023中文
    如何导出文件名到Excel?
    《The Rise and Potential of Large Language Model Based Agents: A Survey》全文翻译
    XIlinx FPGA 和 Intel FPGA的区别
    Java 异常处理通关指南
    Part3_理解MATSIM_第48章 MATSim作为蒙特卡洛引擎
    03贪心:摆动序列
    【Vue】06 计算属性 侦听属性
    深入理解Nginx~Nginx的命令行控制
  • 原文地址:https://blog.csdn.net/nullccc/article/details/127846223