STM32——GPIO输出与输入

一、GPIO简介

  • GPIO(General Purpose Input Output):通用输入输出口
  • 可配置为8种输入输出模式
  • 引脚电平:0V~3.3V,部分引脚可容忍5V(但输出只能是3.3V)
  • 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等,如果控制功率较大的设备,加入驱动电路即可
  • 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

二、GPIO基本结构

在这里插入图片描述

  • GPIOx外设挂载在AHPB2总线上,每个GPIOx内部都设计了寄存器,驱动器是为了将弱电平输出为高电平
    • 寄存器就是特殊的存储器,内核可以通过APB2总线对寄存器进行读写,完成输入电平和输出电平,寄存器的低16位对应一个物理引脚,stm32内部寄存器都是32位,端口只有16位(Px1~Px15),所以寄存器只有低16位有对应的端口

GPIO位结构

在这里插入图片描述

  • 保护二极管从作用是:0-3.3V才能输入,否则都不能流入
  • 输入驱动器中的开关:可以通过程序设置上拉电阻和下拉电阻(阻值都很大)。都断开就是浮空输入模式,作用是给输入提供默认电平,避免引脚的输入电平收外界的干扰
  • 输入驱动器中斯密特触发器:模拟输入接收模拟量,在斯密特触发器之前,数字量在触发器之后。斯密特触发器的另一个作用是调整波形
  • 输出电路中:GPIOX的内部图在输入模式和输出模式下都有寄存器,在输出模式下既可以写入二进制到寄存器也可以读取寄存器的数据。单独操作输出数据寄存器的某一位而不影响其他端口,而普通的输出数据寄存器是一次性读取。关于输出还有位带操作,和51单片机类似
  • 输出驱动器中的开关:mos是开关,用数字信号来导通和关闭开关。
    • 在推挽模式下,两个模式(高低电平)都有效,数据寄存器为1时,pmos导通,nmos断开,输出接到vdd。反之。。。这种模式下输出高低电平均有较强的驱动能力,
    • 开漏模式下,只有nmos有效,数据寄存器为1时,nmos断开,输出断开,高阻模式,反之输出低电平。可以作为通信协议驱动模式。
    • 关闭模式下两个模式(高低电平)都失效

三、GPIO模式

通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式

在这里插入图片描述

  • 除了模拟输入会关闭数字输入功能(也就是GPIO无效),其他模式输入功能都是正常的
  • GPIO输出速度用于控制引脚的最大翻转速度,为了低功耗和稳定性

1. 浮空/上拉/下拉输入

在这里插入图片描述

2. 模拟输入

在这里插入图片描述

  • 模拟输入会关闭数字输入功能

3. 开漏/推挽输出

在这里插入图片描述

4. 复用开漏/推挽输出

在这里插入图片描述

  • 复用开漏/推挽输出由片上外设控制

四、LED闪烁&LED流水灯&蜂鸣器

硬件介绍

  • LED:发光二极管,正向通电点亮,反向通电不亮
  • 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定,滴答声
  • 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音,可以做音乐

电路设计

  • LED连接推荐使用负极接单片机GPIO口,正极接VCC,因为单片机一般被设置为高电平弱驱动,低电平强驱动
    在这里插入图片描述

  • 无源蜂鸣器采用三极管开关的驱动电路,上图是PNP,带箭头的是发射极,左边是基极,下面是集电极,给低电平会导通。下图是NPN
    在这里插入图片描述
    在这里插入图片描述

关键函数

GPIO口初始化

//使能GPIOC口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//定义结构体变量
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;
//GPIO模式设置
GPIO_Init(GPIOA,&GPIO_InitStructure);

stm32f10x_gpio.c文件中的一些函数的使用

void GPIO_DeInit(GPIO_TypeDef* GPIOx);//GPIO外设复位
void GPIO_AFIODeInit(void);//引脚复用

//GPIO读取函数
//在输入模式下读取一端口的电平,配合GPIO_MODE理解,如果是上拉输入,此时若返回值为0表示导通
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//在输入模式下读取16位
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

//输出数据寄存器即可以写入也可以读取
//在输出模式下读取某一位,为了进行翻转,输出相反的结果!!!
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//在输出模式下读取16位
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

//GPIO写入函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//参数是enum类型,参数有:Bit_RESET低电平或Bit_SET高电平,如果要写0或1,可以强制类型转换,例如(BitAction)0
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//写指定数据到GPIOx端口寄存器,根据宏定义找到对应端口的十六进制数据

五、按键控制LED&光敏传感器控制蜂鸣器

硬件介绍

  • 按键:常见的输入设备,按下导通,松手断开
    • 按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动,需要解决按键抖动和松手检测(通过延时将抖动时间耗过去)
      在这里插入图片描述
  • 传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化(反比)【例如入射光强,串联电阻减小,输出电压减小,最小值为0】,通过与定值电阻串联分压即可得到模拟电压输出,再通过电压比较器(运算放大器)进行二值化即可得到数字电压输出在这里插入图片描述
    • 图二电位器作为分压电阻使用
    • 图四传感器模块
      • L1是电源指示灯
      • L2是数字信号输出电平,旁边10K的上拉电阻默认输出高电平
      • AO口是模拟电压输出
      • DO就是数字输出,数字输出就是对AO进行二值化的输出
    • 图三N1是传感器的可变电阻,R1是串联分压的电阻
      • 可以采用上下拉电阻分析法:当n1阻值变小,下拉作用变强,中间AO电压变小,当n1阻值为0时,AO电压完全下拉,输出为0v,反之n1阻值变强,VO由于R1的上拉作用,电压升高。N1阻值无穷大就是断路
    • 图一是二值化输出的芯片LM393,是电压比较器芯片(本质是运算放大器。运算放大器原理:同向输入端电压大于反向输入端电压,输出为最大值vcc,反之为gnd,完成二值化)

电路设计

按键控制LED电路(该电路设计时PA0需要采用上拉输入,不能采用浮空,会导致引脚电压不确定情况)
在这里插入图片描述
该电路设计时可以采用浮空输入或上拉输入,因为始终有高电平上拉
在这里插入图片描述

光敏传感器控制蜂鸣器电路
在这里插入图片描述

关键函数

按键读取函数

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;
}

按键检测

  • 按键检测推荐使用定时器中断,而不是在主函数中读取输入数据寄存器的值,
  • 因为采用中断的方法,后台读取按键值不阻塞主程序,也可以处理按键抖动和松手检测。
  • 也可以采用主程序中外部中断的上升沿循环判断读取

参考视频:江科大自化协

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值