STM32-GPIO


图片均来自江科大STM32教学PPT

GPIO理论

GPIO简介

  1. GPIO(General Purpose Input Output)通用输入输出口。
  2. 可配置为8种输入输出模式。
    在这里插入图片描述
  3. 引脚电平:0V~3.3V,部分引脚可容忍5V(在引脚定义表中带FT就是表示可以容忍5V)。
  4. 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等。
  5. 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等。

GPIO基本结构

  • 在STM32中所有的GPIO都是挂载到APB2总线上的。
  • 寄存器:就是特殊的存储器,内核可以通过APB2总线对其进行读写操作。每一位对应一个引脚。对输出寄存器1就是输出高电平,写0就是输出低电平。对输入寄存器读取为1就证明端口目前为高电平,读取为0就是低电平。
  • 因为是32位单片机,寄存器都是32位的,但是端口只有16位,所以寄存器低16位有对应的端口,高16位没有用到。
  • 驱动器是用来增加信号驱动能力的。
    在这里插入图片描述

GPIO位结构

在这里插入图片描述

  • 左边为寄存器,中间驱动器,右边I/O引脚。
  • 上半为输入部分,下半为输出部分。
  • 施密特触发器:对输入电压进行整形。执行逻辑就是:输入电压大于某一阈值,输出高电平,低于某一阈值,输出低电平。
  • 控制输出寄存器就是普通I/O口输出,写某一位就可以操作对应引脚。
  • 位设置/清除寄存器:可以单独操作输出寄存器的某一位,不影响其他位。
  • 推挽输出模式:输出寄存器为1,P-MOS导通,接到VDD,N-MOS断开,输出高电平,反之输出低电平。
  • 开漏输出模式:P-MOS无效,只有N-MOS在工作。输出寄存器为1,下管断开,高阻模式,为0,下管导通,接到VSS,输出低电平。开漏模式下高电平没有驱动能力。
    在这里插入图片描述

GPIO输出

LED灯闪烁代码

#include "stm32f10x.h"                  // 设备头文件
#include "Delay.h"

int main(void) 
{
    // 开启GPIOA外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    // GPIO初始化结构体
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    // 配置GPIOA引脚0为推挽输出模式,最大输出速度为50MHz
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    // 使用指定的配置初始化GPIOA
    while (1) 
    {
        // 将GPIOA的引脚0置为低电平(复位状态)
        GPIO_ResetBits(GPIOA, GPIO_Pin_0);
        // 延迟500毫秒
        Delay_ms(500);
        // 将GPIOA的引脚0置为高电平
        GPIO_SetBits(GPIOA, GPIO_Pin_0);
        // 延迟500毫秒
        Delay_ms(500);
        // 将GPIOA的引脚0写为低电平
        GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
        // 延迟500毫秒
        Delay_ms(500);
        // 将GPIOA的引脚0写为高电平
        GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
        // 延迟500毫秒
        Delay_ms(500);
    }
}

流水灯代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void) 
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//打开GPIOA的时钟
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    while(1) 
    {
		//	因为是低电平点亮,所以要取反
        GPIO_Write(GPIOA,~0x0001);	//0000 0000 0000 0001
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0002);	//0000 0000 0000 0010
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0004);	//0000 0000 0000 0100
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0008);	//0000 0000 0000 1000
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0010);	//0000 0000 0001 0000
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0020);	//0000 0000 0010 0000
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0040);	//0000 0000 0100 0000
        Delay_ms(500);
        GPIO_Write(GPIOA,~0x0080);	//0000 0000 1000 0000
        Delay_ms(500);
    }
}

蜂鸣器代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void) 
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    while(1)
    {
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);
        Delay_ms(100);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
        Delay_ms(100);
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);
        Delay_ms(100);
        GPIO_SetBits(GPIOB,GPIO_Pin_12);
        Delay_ms(700);
    }
}

GPIO输入

按键控制LED

LED.c

#include "stm32f10x.h"                  // Device header

//初始化LED灯
void LED_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
}

//开灯
void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}

//关灯
void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
}

//实现翻转
void LED1_Turn(void)
{
	//	判断此时IO口的状态,高->低|低->高
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_1);		// 输出高电平
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);		// 输出低电平
	}
}

void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}

void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
}

void LED2_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)==0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_2);
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	}
}

Key.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}
// 获取按键数值
uint8_t Key_GetNum(void)
{
	uint8_t keyNum=0;
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
	{
		//消抖
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0);
		Delay_ms(20);
		keyNum=1;
	}
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)
	{
		//消抖
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0);
		Delay_ms(20);
		keyNum=2;
	}
	return keyNum;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
uint8_t keyNum;
int main(void) 
{
    LED_Init();
    Key_Init();
    while(1)
    {
        keyNum=Key_GetNum();
        if(keyNum==1)
        {
            LED1_Turn();
        }
        if(keyNum==2)
        {
            LED2_Turn();
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值