跳转至

01.GPIO输入输出

实验说明

本系列实验都是基于STM32F1的单片机进行的编程实验。

GPIO输出

实验简介

这里使用单片机控制LED灯的亮灭实现GPIO的输出实验,LED阴极接的单片机的PC13口,所以我们只需要配置PC13口,就可以使用了。

代码实现

一般的单片机配置引脚步骤可以分为开时钟,然后配置引脚属性,代码如下。

void bsp_led_init()
{
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    //初始化IO口
    {
        GPIO_InitTypeDef GPIO_InitStruct;

        GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_13;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;

        GPIO_Init(GPIOC,&GPIO_InitStruct);
    }
}

配置完成后,我们就可以通过代码控制引脚输出的高低电平实现LED的亮灭。

void led_on()
{
    GPIO_ResetBits(GPIOC,GPIO_Pin_13);
}

void led_off()
{
    GPIO_SetBits(GPIOC,GPIO_Pin_13);
}

由上面就可以知道,GPIO_ResetBits这个函数就可以把单片机对应引脚拉低,GPIO_SetBits这个函数可以将单片机对应引脚拉高。

GPIO输入

实验简介

这里使用单片机读取按键连接引脚的高低电平实现GPIO的输入实验,按键接的单片机的PA0口,而且外部按键按下后接入的高电平,所以我们只需要配置PA0口,就可以使用了。

代码实现

一般的单片机配置引脚步骤可以分为开时钟,然后配置引脚属性,代码如下。

void bsp_key_init()
{
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //初始化IO口
    {
        GPIO_InitTypeDef GPIO_InitStruct;

        GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;

        GPIO_Init(GPIOA,&GPIO_InitStruct);
    }
}

由于这里外面按键按下后是接的VCC,所以我们要将IO口的模式配置为下拉,那么按键没有按下的话,单片机检测到的就是低电平,如果外面按键按下后是接的GND,那么就要配置模式为GPIO_Mode_IPU,按键没有按下的话,单片机检测到的就是高电平,配置完成后,我们就可以通过代码获取引脚电平了。

uint8_t get_key_value()
{
    return GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15);
}

由上面就可以知道,GPIO_ReadInputDataBit这个函数就读取到单片机对应引脚的电平。

关于按键输入,参考并改进了正点原子的按键检测方法。

//10MS延时函数
#define KEY_DELAY_10MS() delay_ms(10)

/**
  * @brief          返回按键按下的值
  * @param[out]     mode:模式0就是单次扫描,1就是重复检测 time_set:根据周期时间确定延时的时间,有值就是定时器延时,为0就是普通延时
  * @retval         uint8_t 按键值
  */
uint8_t key_scan(uint8_t mode,uint8_t time_set)
{
    static uint8_t keyCount = 0;
    static uint8_t keyState = 0;
    if(mode == 1)  keyState = 0;
    if ((KEY_UP == 1 || KEY_0 == 0 || KEY_1 == 0)  && keyState == 0) //按键按下
    {
        if(time_set == 0)
        {
            KEY_DELAY_10MS();
            keyState = 1;
            if(KEY_UP == 1) return 1;
            else if(KEY_0 == 0) return 2;
            else if(KEY_1 == 0) return 3;
        }else
        {
            keyCount++;
            if (keyCount > time_set ) 
            {
                keyState = 1;
                keyCount = 0;
                if(KEY_UP == 1) return 1;
                else if(KEY_0 == 0) return 2;
                else if(KEY_1 == 0) return 3;
            }
        }
    }
    else if (KEY_UP == 0 && KEY_0 == 1 && KEY_1 == 1 && keyState == 1) //当所有按键都处于抬起状态,状态刷新
    {
        keyCount = 0;
        keyState = 0;
    }
    return 0;
}

PB3 PB4 PA15 引脚当普通引脚输出

我们常用的下载方式是SW调试,那么就用不到这几个引脚,有时候就想要他们作为普通的IO口输出,那么我们在配置这几个引脚的时候就要在前面加上以下代码来打开引脚的复用功能。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请附上原文出处链接及本声明。

原文链接: https://snqx-lqh.gitee.io/wiki/