• STM32 入门之 GPIO


     

            入手STM32有一段时间了,感觉刚入门时很难,无处下手,现在学到了点皮毛,写出来和大家分享一下。

        首先,什么叫GPIO?这个问题,答案是我也不知道!至少目前我没有必要知道,我只要知道他其实就是51单片机的那种IO口而已,不同的是,51单片机的IO口是不需要配置模式的,而STM32的IO口(哦,不,应该说是GPIO口,╮(╯▽╰)╭,真绕舌头)是需要配置模式和时钟的(好吧,又冒出一个时钟来,够麻烦的),在这里要说明一下,STM32的GPIO,如果你要用它,就要做两步工作,第一是配置模式、速度,第二是配置其时钟并使能(貌似说两步有点牵强)。估计现在大家已经糊涂了,好吧,别急,我一点一点给大家解释解释;

        我们第一步要知道GPIO的那八种模式是什么,怎么用。GPIO的八种模式如下:

        (1)浮空输入:In_Floating

        (2)带上拉输入:IPU(In Push_Up)

        (3)带下拉输入:IPD(In Push_Down)

        (4)模拟输入:AIN(Anolog In)

        (5)开漏输出:OUT_PD(OD 代表开漏,既Open Drain,OC代表开集,Open Collect)

        (6)推挽输出:OUT_PP(PP代表推挽式,Push_Pull)

        (7)复用功能推挽输出:AF_PP(AF代表复用功能,Alternate-Fuction)

        (8)复用功能开漏输出:AF_OD

        好吧,就这八种模式,打字打得我手都酸了、、、、、、

        这八种模式什么时候用哪种,这个问题值得研究,不过也不用现在就玩命地研究,以后在使用过程中慢慢就体会到了,所以在这里我就不多说了。

        再就是配置GPIO的翻转速度了,有10M、2M和50M,具体配置方式等最后我们贴个完整的代码就明白了。

        GPIO配置说完了,再说说时钟配置,时钟配置其实就是一堆让初学者看不懂的代码,不过看多了慢慢体会,你就明白他到底是在说什么了,在写程序的时候可以直接从他给的工程中移植过来,然后修改一下相关的配制就行了,先贴个代码,然后再解释。


    上图是配置时钟的代码,我挨着行解释一下:

    SystemInit();看名字就知道这个是系统初始化,到底初始化了些什么,我的意思是不知道,目前也不用知道,你就写这么一句就行了;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA

                           |RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC

                           |RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE

                                                |RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO

                           |RCC_APB2Periph_SPI1, ENABLE );

    这几句有点长,看着就头晕,但是我们不怕,一句一句看,RCC_APB2PeriphClockCmd()这个函数名字有点怪,它叫做使能或失能APB2外设时钟(这名字够绕嘴的),不用管它,直接复制过来就行,再看括号里面的,RCC_APB2Periph_USART1,这个代表的是USART1的时钟是和APB2的一样,下面的几个都是这么个意思,用或符号连接在一起,然后再加上个ENABLE,这就算使能了你想要用的管脚,大家要注意啊,上面的代码是我随便找的,在实际使用过程中,具体是能什么,要看你用到什么,就使能什么,不用最好别使能,免得造成不必要的干扰和麻烦。

        好了,我们一开始说的两个问题说完了,下面说一下如何让GPIO输出高低电平吧。其实吧这个问题很简单,很多的资料一提到这个问题,就开始讲寄存器,一讲寄存器,就涉及到内部原理,好吧,终于,初学者不淡定了,脑子成了一堆浆糊,然后信心受挫,然后就降低了学习效率,其实我个人认为大不必,既然有库函数,那我们就先用库函数,等库函数用熟了,再自己慢慢领悟库函数里面的寄存器操作。看下面两条语句:

    GPIO_SetBits(GPIOD, GPIO_Pin_9);

    GPIO_ResetBits(GPIOD, GPIO_Pin_9);

    第一句的意思是将GPIOD9口置位(我们假定这个口的模式是输出模式),第二句的意思是将GPIOD9口清零(同样的假定)。哈哈,怎么样,简单吧,这就是基本的IO口操作,这样,你就能成功点亮或者熄灭指定的LED了,下面附上一段例程,大家自己慢慢研究。

    #include "stm32f10x.h"

    //-------------------------------------------GPIO初始化-----------------------------------------//

    void GPIO_Configuration(void)

    {

           GPIO_InitTypeDef GPIO_InitStructure;

          

            

           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;

          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

          GPIO_Init(GPIOD, &GPIO_InitStructure);

          

           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

          GPIO_Init(GPIOB, &GPIO_InitStructure);

    }

    //--------------------------------------配置系统时钟,使能各外设时钟---------------------------------//

    void RCC_Configuration(void)

    {

           SystemInit(); 

           RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB

                               | RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD

                               | RCC_APB2Periph_GPIOE, ENABLE );

    }

    //-----------------------------------配置所有外设------------------------------//

    void Init_All_Periph(void)

    {

           RCC_Configuration();  

           GPIO_Configuration();

    }

    //----------------------------------------延时函数--------------------------------------------//

    void Delay(vu32 nCount)

    {

      for(; nCount != 0; nCount--);

    }

    //------------------------------------------主函数--------------------------------------------//

    int main(void)

           Init_All_Periph();

          while(1)

          {

              

               GPIO_SetBits(GPIOD, GPIO_Pin_8);

              

               GPIO_ResetBits(GPIOD, GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11);

              

               Delay(0xEFFFF);

              

               GPIO_SetBits(GPIOD, GPIO_Pin_9);

              

               GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11);

              

               Delay(0xEFFFF);

              

               GPIO_SetBits(GPIOD, GPIO_Pin_10);

              

               GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11);

              

               Delay(0xEFFFF);

              

               GPIO_SetBits(GPIOD, GPIO_Pin_11);

              

               GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);

              

               Delay(0xEFFFF);

               GPIO_ResetBits(GPIOD, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);

          }

    }

  • 相关阅读:
    Codeforces Round #344 (Div. 2) C. Report 其他
    Codeforces Round #344 (Div. 2) B. Print Check 水题
    Codeforces Round #344 (Div. 2) A. Interview 水题
    8VC Venture Cup 2016
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂
    CDOJ 1279 班委选举 每周一题 div2 暴力
    每周算法讲堂 快速幂
    8VC Venture Cup 2016
    Educational Codeforces Round 9 F. Magic Matrix 最小生成树
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/6802978.html
Copyright © 2020-2023  润新知