STM32-GPIO(江协科技学习笔记)

目录

1、工程结构

2、系统结构

3、GPIO位结构

4、GPIO模式

5、ELD和蜂鸣器

6、标准库中常见的GPIO函数及其用法


1、工程结构

2、系统结构

在STM32中,所有的GPIO都是挂载在APB2外设总线上的。

APB1(Advanced Peripheral Bus 1)和APB2,它们是AHB(Advanced High-performance Bus)的从属总线。两个AHB/APB桥在AHB2APB总线间提供同步连接。APB1操作速度限于36MHzAPB2操作于全速(最高72MHz)
注意: 当对 APB 寄存器进行 8 位或者 16 位访问时,该访问会被自动转换成 32 位的访问:桥会自动将 8 或者 32 位的数据扩展以配合 32 位的向量

3、GPIO位结构

(1)施密特触发器:对输入电压进行整形。其执行逻辑为:如果输入电压大于某一阈值,输出就会瞬间升为高电平

(2)模拟输入:这个是连接到ADC(片上外设)上的,因为ADC需要接收模拟量,所以接到施密特触发器前面。

(3)复用功能输入:这个是连接到其他需要读取端口的外设上的,比如串口的输入引脚等,这根线接收的是数字量,所以接到施密特触发器后面。

(4)输出数据寄存器(ODR):写其的某一位就可以操作对应的某个端口。

(5)位设置/清除寄存器:可用来单独操作输出数据寄存器的某一位,而不是影响其他位。因为输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以想单独控制其中某一个端口而不影响其他端口的话,就需要一些特殊的方式:

  • 先读出这个寄存器,然后用按位与和按位或的方式更改某一位(&=  |=),最后再将更改后的数据写回去。但这种方法效率不高且麻烦,对IO口的操作而言不太合适

  • 通过设置这个位设置/清除寄存器,如果我们要对某一位置1,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样它内部就会有电路自动将位设置寄存器中对应位置1,而剩下写0的位保持不变。保证了只操作其中某一位而不影响其它位,并且这是一步到位的操作。如果想对某一位进行清0的操作,就在位清除寄存器的对应位写1即可,内部电路会把这一位清0.

  • 读写STM32中的“位带”区域,这个位带的作用跟51单片机的位寻址作用差不多。在STM32中,专门分配有一段地址区域,这段地址映射了RAM和外设寄存器所有的位,读取这段地址中的数据,就相当于读写所映射位置的某一位,这就是位带的操作方式。

输出模式

控制开关

工作方式

特点

推挽输出

P-MOS、N-MOS均有效

数据寄存器为1时,上管导通,下管断开,输出直接接到VDD,即高电平;反之则是低电平

这种模式下,高低电平均有较强的驱动能力,所以推挽输出模式也可以叫强推输出模式(STM32对IO口具有绝对的控制权,高低电平都由STM32说了算)

开漏输出

P-MOS无效、N-MOS均有效

数据寄存器为1时,下管断开,下管断开,输出相当于断开,即高阻模式。数据寄存器为0时,下管导通,输出直接接到VSS,即输出低电平。这种模式下,只有低电平有驱动能力,高电平没有驱动能力。

这个开漏模式可以作为通信协议的驱动方式,比如I2C通信的引脚,就是使用的开漏模式。在多机通信的情况下,这个模式可以避免各个设备的相互干扰。另外开漏模式还可以用于输出5V的电平信号。

关闭

P-MOS、N-MOS均有效

当引脚配置为输入模式的时候,输出关闭,端口的电平由外部信号来控制

4、GPIO模式

(1)1、2、3模式的电路结构基本一样,区别就是上拉电阻和下拉电阻的连接。

(浮空输入下,端口一定要接上一个连续的驱动源,不能出现悬空的状态)

(2)

(3)

(4)

GPIO_Mode_AIN

Analog In--模拟输入

GPIO_Mode_IN_FLOATING

Floating--浮空输入

GPIO_Mode_IPD

In Pull Down--下拉输入

GPIO_Mode_IPU

In Pull Up--上拉输入

GPIO_Mode_OUT_OD

Out Open Drain--开漏输出

GPIO_Mode_OUT_PP

Out Push Pull--推挽输出(点灯 )

GPIO_Mode_AF_OD

Atl Open Drain--复用开漏

GPIO_Mode_AF_PP

Atl Push Pull--复用推挽

5、ELD和蜂鸣器

LED:长正短负,小正大负。

以上图为例,将P1^2引脚接低电平,蜂鸣器响,接高电平,蜂鸣器关闭(低电平触发)。

(1)低电平驱动LED:当PA0输出低电平时,LED两端就会产生电压差,从而形成正向导通的电流,LED点亮。 

该GPIO在推挽输出模式下,高低电平均有比较强的驱动能力,故两种接法均可。但在单片机的电路里,一般使用低电平驱动,因为很多单片机或者芯片都使用了“高电平弱驱动,低电平强驱动”的规则。

(2)蜂鸣器电路使用了三极管开关的驱动方案(最简单的驱动电路)(对于功率稍微大一点的电路,直接用IO口驱动会导致STM32负担过重)。三极管左边的是基极,带箭头的是发射极,剩下的是集电极。

PNP三极管:基极给低电平三极管导通, 蜂鸣器有电流,反之没有。

NPN三极管:相反。

(PNP的三极管接在蜂鸣器上面,而NPN的三极管接在蜂鸣器下面,因为三极管的通断需要在发射极和基极直接产生一定的开启电压,若反过来可能导致三极管不能开启)

(3)在PA0口输出高低电平,驱动LED闪烁

(注意因为配置的是GPIO,所以要使用APB2外设总线)

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

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   // RCC的APB2外设时钟控制函数(PA0-GPIOA,使能)
	
	GPIO_InitTypeDef GPIO_InitStructure;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//选择0号端口
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度为50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);					// GPIO初始化(GPOIX, )第二个参数是一个结构体,需要先把结构体类型复制下来,再在前面定义
	
//	GPIO_ResetBits(GPIOA, GPIO_Pin_0);						// 设置指定端口为低电平
//	GPIO_SetBits(GPIOA, GPIO_Pin_0);						// 设置指定端口为高电平
//	GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);			// 设置指定端口为高电平
//	GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);				// 设置指定端口为低电平
//	GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);			// 将0强制转换为BitAction的枚举类型,低电平
//	GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);			// 将1强制转换为BitAction的枚举类型,高电平
	
	while(1)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
		Delay_ms(500);
		GPIO_SetBits(GPIOA, GPIO_Pin_0);
		Delay_ms(500);
		
		//直接法
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
		Delay_ms(500);
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
		Delay_ms(500);
		
		//枚举法
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);
		Delay_ms(500);
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
		Delay_ms(500);
	}
}

6、标准库中常见的GPIO函数及其用法

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

读取输入数据寄存器某引脚的输入值

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

读取输入数据寄存器全部的输入值

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

读取输出数据寄存器某引脚的输入值

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

读取输入数据寄存器全部的输入值

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

设置指定端口为低电平

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

设置指定端口为高电平

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

一般可以实现批量或者同时控制多个 GPIO 引脚的输出状态

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

用来单独设置某一个特定的 GPIO 引脚的输出状态

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习STM32F103的GPIO时,我记录了以下内容: 1. GPIO寄存器有32位,但是只用到了低16位,高16位是闲置的。GPIOA对应PA,GPIOB对应PB,GPIOC对应PC等。\[1\] 2. 控制GPIO的输出可以通过输出数据寄存器进行。可以通过写入数据寄存器的某一位来操作对应的端口。左边的位设置/清除寄存器可以单独操作某一位,而不影响其他位。在推挽输出模式下,P-Mos和N-Mos均有效,这种模式下具有较强的驱动能力,因此可以称为强推输出模式。\[2\] 3. 在设置GPIO的模式时,可以使用GPIO_InitStruct结构体来进行配置。例如,选择LED的引脚为B_LED_GPIO_PIN,将模式设置为推挽输出模式(GPIO_MODE_OUTPUT_PP),默认上拉(GPIO_PULLUP),引脚输出速度设置为慢(GPIO_SPEED_FREQ_LOW)。\[3\] 这些记录可以帮助你更好地理解和使用STM32F103的GPIO功能。 #### 引用[.reference_title] - *1* [STM32F103C8T6-GPIO学习笔记1](https://blog.csdn.net/xyh17858926692/article/details/126136176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【嵌入式学习-STM32F103-GPIO】](https://blog.csdn.net/weixin_43251807/article/details/129462844)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32F103C8T6GPIO点灯](https://blog.csdn.net/weixin_43604457/article/details/123262236)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值