寒假学习之STM32(1)----GPIO

GPIO

PS1: 呃,大二上学期没有数模电的知识, 笔记目前是按照库函数版本进行的,不涉及电路分析,以后再加上
PS2:额,在没有微机原理,数模电的基础知识之前,我打算先学会用库函数来配置寄存器,所以,这个博客不是一篇深度解析文,更确切的来说,这是一篇小白入门的勉强文。

准备工作:

1.数目

一般的stm32上有GPIOA~GPIOG七组GPIO口,每组由0~15共16个引脚(但是具体到某一个芯片,则引脚数也会有相应的差别,比如RCT6,一共GPIOA~GPIOD四组IO口,GPIOA~C有十六个引脚,但是GPIOD只有0~2俩引脚)

2.功能简介

每个引脚都有相应的功能,如,芯片手册上所标注的FT,意为这个IO口可以承受5V的电压,具体到某个引脚有不同的功能。
· 复用 : 端口既可以作为通用的IO口,又可以作为外设的引脚
· 重映射 :通过配置重映射寄存器,将一些复用功能映射到其他引脚,以方便PCB设计布线,减少信号的交叉干扰 !
端口复用

3.工作方式:

输入:
a. 上拉输入(GPIO_Mode_IPU)上拉就表示该端口在默认情况下输入为高电平
b. 下拉输入(GPIO_Mode_IPD) 下拉和上拉相反
c. 浮空输入(GPIO_Mode_IN_FLOATING)正常情况呈高阻态,在日后的I2C中会用到
d. 模拟输入(GPIO_Mode_AIN)AD/DA转换中常用

输出:
a. 开漏输出(GPIO_Mode_Out_OD):多用于连接不同电平的器件
b.开漏复用(GPIO_Mode_AF_OD):
c:推挽输出(GPIO_Mode_Out_PP):
d.复用推挽(GPIO_Mode_AF_PP):

OK,准备工作结束之后,接下来是配置工作,配置工作分为输入配置,输出配置两点进行

 PS:所有寄存器的配置均要首先配置时钟

GPIO的输出配置(以PB.5为例):

  1. 配置时钟

    `RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);`
    
  2. 配置寄存器

    “`
    GPIO_InitTypeDef GPIOB_Struct;
    GPIOB_Struct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
    GPIOB_Struct.GPIO_Pin=GPIO_Pin_8;//引脚
    GPIOB_Struct.GPIO_Speed=GPIO_Speed_50MHz;//速度有5MHz,10MHz,50MHz
    GPIO_Init(GPIOB,&GPIOB_Stuct);



3. 输出电平
`   GPIO_SetBits(GPIOB,GPIO_Pin_8);`
        PS:常见的输出电平的函数有两个它们的原型分别是:
        `void GPIO_SetBits(GPIOx,GPIO_Pin_x); //输出高电平
         void GPIO_ResetBits(GPIOx,GPIO_Pin_x); //输出低电平
         `


GPIO的输入配置(以PB.5为例):




1. 配置时钟


        `RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);`

2. 配置寄存器


    ```
    GPIO_InitTypeDef GPIOB_Struct;
    GPIOB_Struct.GPIO_Mode=GPIO_Mode_In_IPU;//上拉输入
    GPIOB_Struct.GPIO_Pin=GPIO_Pin_8;//引脚
    GPIOB_Struct.GPIO_Speed=GPIO_Speed_50MHz;//速度有5MHz,10MHz,50MHz
    GPIO_Init(GPIOB,&GPIOB_Stuct);
  1. 输入电平
    GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8);
    PS:常见的输出电平的函数有两个它们的原型分别是:
    uint16_t GPIO_ReadInputData(GPIOX);//读取某一组GPIO口的信息
    uint8_t GPIO_ReadInputDataBit(GPIOx,GPIO_Pin_x);//读取某一个GPIO口的信息

例:按键的输入检测:

#define KEY  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)

#define KEY0_PRES  1  //KEY0 按下
#define KEY1_PRES  2  //KEY1 按下
#define KEY2_PRES  3  //KEY2 按下
#define KEY_PRES   4  //WK_UP 按下(即 WK_UP/WK_UP)

void Key_Init(void)
{
    //开头步骤,定义结构体,时钟使能
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOE, ENABLE );


    //初始化GPIOE,也就是Key0,Key1,Key2
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; 
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
    GPIO_Init(GPIOE,&GPIO_InitStructure);


    //初始化GPIOA,也就是Key
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

}


//mode, 模式,两种模式,第一种支持连续
u8 Key_Scan(u8 mode)
{    
    static u8 key_up=1;//按键按松开标志
    if(mode)key_up=1;  //支持连按         
    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY==1))
    {
        delay_ms(10);//去抖动 
        key_up=0;
        if(KEY0==0)return KEY0_PRES;
        else if(KEY1==0)return KEY1_PRES;
        else if(KEY2==0)return KEY2_PRES;
        else if(KEY==1)return KEY_PRES;
    }else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY==0)key_up=1;        
    return 0;// 无按键按下
}

int main(void)
{   

    vu8 e;
    Key_Init();
    delay_init();   
    Beep_Init();
    LED_Init();


    while(1)
    {
        e=Key_Scan(1);
        if(e)
        {
            switch(e)
            {
                case KEY_PRES:
                     PBout(8)=!PBout(8);break;
                case KEY0_PRES: 
                     PEout(5)=!PEout(5);
                     PBout(5)=!PBout(5);break;
                case KEY1_PRES:
                     PEout(5)=!PEout(5);break;
                case KEY2_PRES:
                     PBout(5)=!PBout(5);break;
                default :delay_ms(1);

            }


        }
        else delay_ms(10);
    }


}

你可能感兴趣的:(stm32)