• 第二篇,Stm32f407芯片GPIO编程,寄存器操作,库函数操作和位段操作


     Stm32f407芯片GPIO编程

    GPIO叫做通用的输入输出接口,用作通用的输入输出功能,输入和输出01,用高电平表示1,低电平表示0.ARM,高电平为3.3v,低电平为0v

    1.查看下载的原理图,应该注意的是,原理图名字相同的引脚在物理上是连接在一起的,可以在原理上搜索丝印的名称来找到硬件对应的原理图。

    LED硬件对应的原理图

    STM32芯片对应的原理图

    看LED原理图要达到两个目的(连不连接VDD3v3情况判断)

    1)明确操作的硬件的工作方式(结合硬件的说明手册)

    对应的引脚为低电平——LED

    对应的引脚为高电平——LED

    (2)要操作的硬件连接到CPU那些引脚

    D1——————PF9

    D2——————PF10

    D3——————PE13

    D4——————PE14

    查看CPU的芯片手册(STM32F4xx中文参考手册和Cortex-M4权威指南)硬件控制是通过操作寄存器来实现的。有三种寄存器配置方法,GPIO寄存器位操作,库函数操作,位段操作,下面将分别介绍。

    ———————————————————————————————————————————

    ———————————————————————————————————————————

    GPIO寄存器位操作

    1GPIO 的输入输出选择

    输入————浮空,上/下拉输入,复用,模拟

    输出————推挽/开漏,上/下拉,复用,模拟

    推挽和开漏的区别:推挽是拉高,开漏是弱拉高,开漏拉高需要外接上拉电阻,开漏还有吸收电流的功能,可以做双向IO

    2)输出速度

    低——中——高——快

    (3)锁定机制

    锁定GPIO的配置

    (4)数据寄存器

    输入数据寄存器————获取GPIO输入的电平

    输出数据寄存器 置位/复位寄存器————设置GPIO输出的电平

    (5)功能复用选择

    选择复用寄存器

    (6)配置寄存器

    查表确定寄存器配置的值

    查看对应的硬件寄存器

    Stm32f407共有9GPIOA~I,每组16个(0~15),stm32所有寄存器都是32位的。

    查看硬件寄存器需要获取的信息

    1.获取硬件寄存器的地址

    stm32中寄存器的地址使用的是基地址+偏移      

    基地址在参考手册的2.3节的表中查询

    比如GPIOF寄存器的基地址=0x40021400,有偏移的要加上偏移量

    每个寄存器的偏移在寄存器的说明上   

    2.寄存器每一位代表的内容

    ———————————————————————————————————————————

    ———————————————————————————————————————————

    做个简单练习

    配置PF9寄存器为通用推挽输出,无上下拉,高速输出

    模式寄存器

    基地址 = 0x40021400

    (7)配置模式寄存器

    位操作配置,比较麻烦

    Volatile unsigned int *pxx = (unsigned int*)0x40021400;

    //18~19位设置为01

    *pxx &=~(0x3<<18);  //位与运算,先将18~19位设置为00

    *pxx |=~(0x1<<18);  //位或运算,再将18~19位设置为01

    配置输出类型寄存器

    配置输出速度寄存器

    上下拉选择寄存器

    通过以上4个寄存器的配置完成了PF9的初始化,通用推挽输出,无上下拉,快速输出,下面是通过复位/置位寄存器控制输出的电平。

    这里通过配置GPIO置位/复位寄存器来控制GPIO输出寄存器的输出电平,配置PF9寄存器,我们需要明白的工作原理为(请仔细看上图中的寄存器配置对用关系,这个很重要):

    第一点:往置位复位寄存器BS9位中写1,输出寄存器ODR9位就会置1,往置位复位寄存器BS9位中写0,输出寄存器ODR9位不会改变;

    第二点:往置位复位寄存器BR9位中写1,输出寄存器ODR9位就会清0,往置位复位寄存器BR9位中写0,输出寄存器ODR9位不会改变;这就是通过GPIO置位/复位寄存器控制GPIO输出寄存器的输出电平的方法。

    想要GPIO正常工作,必须开启GPIO时钟开关,通过外设时钟使能寄存器去配置

    基地址:0x40023800

    编写驱动程序

    Stm32官方提供了寄存器地址的宏定义,可以直接使用。

    编写代码思路(伪代码)

    1. 初始化

       开始GPIO时钟

       PF9配置成通用推挽输出,无上下拉,高速输出

    1. 闪烁

       While1{

            

             延时

            

             延时

    }

    ——————————————————————————————————————————————————————————————————————————————————————

    GPIO库函数的使用,可以通过源码或者库函数手册来查找

    1GPIO库函数初始化

    Void GPIO_Init(GPIO_TypeDef*GPIOx ,GPIO_TypeDef*GPIO_InitStruct);

      GPIOx ————哪一组GPIO

      GPIO_InitStruct ————GPIO初始化结构体

    Typedef struct

    {   

    Uint32_t GPIO_Pin;                //初始化该组的哪些引脚

    GPIOMode_TypeDef  GPIO_Mode;   //模式选择

    GPIOSpeed_TypeDef  GPIOSpeed;   //输出速度

    GPIOOType_TypeDef  GPIOOType;  // 输出模式

    GPIOPuPd_TypeDef   GPIO_PuPd;  //上下拉选择

    }GPIO_InitTypeDef;

    (2)AHB1总线时钟使能

    Void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph,FunctinalStste NewState);

    RCC_AHB1Periph————哪个时钟   RCC_AHB1Periph_GPIOF

    NewState————使能/关闭        ENABLE/DISABLE

    (3)设置GPIO的输出值

    void GPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);

    void GPIO_ResetBits(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);

    参数:

    GPIOx————哪一组引脚

    GPIO_Pin————哪些引脚

    keil5中添加源码,源文件要加入工程左边的工程目录,头文件的路径加入配置界面的C/C++include paths

     

    ——————————————————————————————————————————————————————————————————————————————————————

    GPIO位段操作

    寄存器的操作通常以二进制为单位,相对来说不那么方便,stm32提供了位段操作让开发者以更方便和更高效地去访问寄存器中的某些位。位段操作既方便了编程,又提高了代码的运行效率,如果对寄存器访问频繁,可以使用位段操作。

    bit_word_adddr = bit_band_base+(byte_offset*32)+(bit_number*4)

    bit_word_adddr  代表别名区域中将映射到目标位的字的地址

    bit_band_base  代表别名区域的起始地址

    byte_offset     代表目标位所在位段区域中的字节编号

    bit_number     代表目标位的位位置(0-7

    ——————————————————————————————————————————————————————————————————————————————————————

    练习

    利用GPIO库函数配置PF9,PF10引脚为输出模式,推挽输出,高速输出,无上下拉

    1. //功能代码
    2. void led_init(void)
    3. {
    4.     GPIO_InitTypeDef GPIO_InitStruct;
    5.     
    6.     //1.开启GPIOE GPIOF的时钟
    7.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF,ENABLE);
    8.     
    9.     //2.GPIO初始化 PF9 PF10 PE13 PE14
    10.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//输出模式
    11.     GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
    12.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
    13.     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
    14.     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;//PF9 PF10
    15.     GPIO_Init(GPIOF,&GPIO_InitStruct);
    16.     
    17.     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;//PE13 PE14
    18.     GPIO_Init(GPIOE,&GPIO_InitStruct);
    19.     
    20.     //3.LED默认关闭
    21.     GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
    22.     GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14);
    23. }

  • 相关阅读:
    独孤思维:被你们群嘲的王自如,正在偷偷赚钱
    【Ubuntu】安装企业微信(Wine)
    2024前端面试准备之HTML篇
    【畅购商城】订单模块之收货人列表
    玄子Share-服务器硬件及RAID配置实战
    计算二进制中1的个数
    构造器(constructor)是否可被重写(override)?
    “大数据分析师”来了,提高职业含金量,欢迎来领
    Linux项目自动化构建工具-make/Makefile
    【用四道刁钻例题带你理解】数据在内存中存储的方式
  • 原文地址:https://blog.csdn.net/weixin_44651073/article/details/125565815