• 使用寄存器点亮LED——编程实战


    stm32的编程和stc89c51还是存在着很多思想上的不同的,在51单片机中,我们点亮LED灯,只用给对应IO高低电平就可以了,而stm32中,就一个简单的GPIO,我们也需要配置好几个寄存器,而且,就算配置好GPIO寄存器,我们还必须有一步不能缺少的操作,那就是开启对应GPIO的时钟。在stm32的编程中,开启对应时钟是必不可少的一个操作,而且,开启时钟的操作必须在配置相应寄存器之前,以GPIO为例,如果我们先配置GPIO的寄存器,不开启时钟或者先配置GPIO寄存器,最后再开启时钟,都不能正常驱动芯片工作。时钟就像人的脉搏一样,人必须有脉搏才能工作,同样,stm32也必须先给时钟,再配置寄存器达到相应的功能。

    那么我是怎么知道要这样配置的呢?

    第一,现在的教程比较成熟,能够知道这些内容;第二,在开发板的学习教程中,他也是通过ST的官方demo知道的,具体在

    F4固件库STM32F4xx_DSP_StdPeriph_Lib_V1.5.1STM32F4xx_DSP_StdPeriph_Lib_V1.5.1ProjectSTM32F4xx_StdPeriph_Examples

    这个目录下,有基于ST的参考代码,别人告诉我们要先开启时钟;第三,为什么要先开启对应外设时钟才能工作,51单片机就不需要啊。这个也是可以理解的,为了低功耗嘛,时钟相当于一把钥匙控制这个电路的开关,没用时钟这把钥匙,你什么操作也是白搭,对应时钟控制对应外设,这也无可厚非。

     

    那么我们怎么查看具体外设到底要开启什么时钟呢?

    查看《STM32F4xx中文参考手册1》2.3节,STM32F4xx 寄存器边界地址 ,可以看到对应外设的时钟。

    可以看到我们的GPIOH是挂载在AHB1总线上,所以要先开启AHB1总线上的GPIOH时钟。

    那么又在哪里查看这个呢?还是中文参考资料中,6.3.12 RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)

    通过这里我们我们可以看到:

    参考手册上说明,这个寄存器的第七位控制我们的GPIOH,置1,使能。

    同样,配置GPIO寄存器时,也应该参考对应手册:

    在知道这些流程之后,开始编写程序:

    /*
        使用寄存器的方法点亮LED灯
      */
    #include "./stm32f4xx.h"  
    
    
    /**
      *   主函数
      */
    int main(void)
    {    
        /*开启 GPIOH 时钟,使用外设时都要先开启它的时钟*/
        RCC_AHB1ENR |= (1<<7);    //很明朗了,第七位要置1,使能时钟
        
        /* LED 端口初始化 */
        //根据上面的寄存器描述依次配置,这个技能是只要你去看,就会的东西
        /*GPIOH MODER10清空*/
        GPIOH_MODER  &= ~( 0x03<< (2*12));    
        /*PH10 MODER10 = 01b 输出模式*/
        GPIOH_MODER |= (1<<2*12);
        
        /*GPIOH OTYPER10清空*/
        GPIOH_OTYPER &= ~(1<<1*12);
        /*PH10 OTYPER10 = 0b 推挽模式*/
        GPIOH_OTYPER |= (0<<1*12);
        
        /*GPIOH OSPEEDR10清空*/
        GPIOH_OSPEEDR &= ~(0x03<<2*12);
        /*PH10 OSPEEDR10 = 0b 速率2MHz*/
        GPIOH_OSPEEDR |= (0<<2*12);
        
        /*GPIOH PUPDR10清空*/
        GPIOH_PUPDR &= ~(0x03<<2*12);
        /*PH10 PUPDR10 = 01b 上拉模式*/
        GPIOH_PUPDR |= (1<<2*12);
        
        /*PH10 BSRR寄存器的 BR10置1,使引脚输出低电平*/
        GPIOH_BSRR |= (1<<16<<12);
        
        /*PH10 BSRR寄存器的 BS10置1,使引脚输出高电平*/
        //GPIOH_BSRR |= (1<<10);
    
        while(1);
    
    }
    
    // 函数为空,目的是为了骗过编译器不报错
    void SystemInit(void)//这个函数必须自己写一个加上,因为启动文件的关系,到后面会详细说这个问题
    {    
    }
    
    
    
    
    
    
    /*********************************************END OF FILE**********************/

    这个是我们自己用寄存器实现的例子,我的开发板有三个灯,分别接GPIOH10,11,12,所以更改了几次代码,这样也发现寄存器编程的一个问题,修改代码有点麻烦,而且还是有点冗余,虽然我们可以通过宏或者函数封装,但是,那样封装之后,他就是库函数版本了, 到后面,我们都会采用库函数的方式来学习,项目开发中肯定也是库函数首选。但是,我们经过自己配置寄存器这个步骤,知道了库函数底层其实也就是封装了配置好的寄存器而已,知道原理之后,我们还是应该才赢开发效率更高的库函数来进行应用。

  • 相关阅读:
    Strapi and MongoDB
    Windows 下入手 MongoDB
    npm 创建一个 github action
    Vue3: does not provide an export named 'createRouter'
    How To Use Rocketbots As A Dialogflow CRM
    Telegram Groups vs Telegram Channels
    WhatsApp Group vs WhatsApp Broadcast for Business
    Instant Messaging for Business: Your 10 Best Options
    How to Create and Use Facebook Messenger Codes (June 2019)
    Ultimate Guide to Line For Business (May 2019)
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6692321.html
Copyright © 2020-2023  润新知