STM32-(05):GPIO原理与操作

上一篇:STM32-(04):STM32F103VCT6芯片内部资源分析下一篇:STM32-(06):位绑定的基础应用

在这里插入图片描述

简单分析:红色框主要是输出电路(O),蓝色框主要是输入电路(I);关于输出电路,可以通过写位设置/清除寄存器来改变输出数据寄存器,或者直接读写输出数据寄存器,有这两种方式,继而通过I/O端口输出。如果打开了复用功能,就走复用的通道,输出控制就是一个锁存器。若寄存器写入1,输出控制的上方输出1,则CMOS管P-MOS导通,CMOS管N-MOS不导通,输出高电平,若寄存器写入0,输出低电平。关于输入电路,I/O进来有两个保护二极管,防止电压过高,再进入,有两个电阻,上拉和下拉,当不拉时为浮空输入,一般用于模拟输入,经过施密特触发器,如果用作GPIO口,将值写入寄存器,如果用作复用,走复用通道。

GPIO功能描述端口配置表+输出模式位
开漏输出就是P-MOS上方不接
推挽输出就是两个CMOS都正常
如图所示,涉及到四个位来决定输入输出
端口配置低寄存器 CRL端口配置高寄存器 CRH
0-7一个八组,控制8个GPIO, 8-15另外八组,控制另外8个GPIO,GPIOX的 x的取值范围为(A-E)
端口输入数据低寄存器 IDR端口输出数据高寄存器 ODR
输入、输出数据寄存器都只用到1位(一个端口16个引脚),只需要16位,所以高16位保留
端口位设置/复位寄存器 BSRR端口位复位寄存器 BRR端口配置锁定寄存器 LCKR

设置I/O口的引脚,输出电平。

int  main(void)
{
//	GPIOA->CRL = 0x00;		//CRL 代表低八个引脚(0-7)
//	GPIOA->CRH = 0xffffffff;	//CRH 代表高八个引脚(8-15)
/*1.设置GPIOA组的引脚的工作模式;应该是输出模式,输出模式应该是通用GPIO(非复用),假设使用的是GPIOA.0、GPIOA.1
这两个引脚应该设置为推挽输出(查看端口位配置表<表11>:CNF1设为0、CNF0设为0)、速度50Mhz(查看端口位配置表<表11>:
MODE1、MODE0设为1),继续查看 端口配置低寄存器(GPIOx_CRL),一共32位(0-31),0-3控制GPIOA的第一个引脚,
4-7控制GPIOB的第二个引脚,0-3内是MODE0、MODE1、CNF0、CNF1,需要设置对应位已达到推挽输出与速度的要求。
*/
	GPIOA->CRL = 0x33;	//CRL是端口配置寄存器

//2.在相应的引脚输出一个电平

	GPIOA->ODR = 0x0;	//00 设置这两个引脚输出两个低电平
	GPIOA->ODR = 0x3;	//11 设置这两个引脚输出两个高电平
	
	return(1);
}

通过改变GPIOA的第8位,使第0位状态跟着改变

int  main(void)
{
//	1、PA.0输出、50Mhz	  PA.8输入(PA.0用到CRL, PA.8用到CRH)
	GPIOA->CRL = 0x03; 	//PA.0输出、50Mhz
	GPIOA->CRH = 0x04; 	//PA.8输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
//	2、PA.0 == PA.8
	while(1)
	{
	//第8位输入影响第0位输出
		if((GPIOA->IDR & 0x0100) == 0x0100)		//若成立,则第八位为1 (IDR 输入数据寄存器)
			GPIOA->ODR = 0x01;				//则相应第0位也置为1 (ODR 输入数据寄存器)
		else
			GPIOA->ODR = 0x00;
	}
	return(1);
}

GPIOA.8 ~ GPIOA.15 引脚输入状态影响GPIOA.0 ~ GPIOA.7 引脚输出状态

方案一

int  main(void)
{
//	1、PA.0 ~ PA.7 输出、50Mhz	  PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
	GPIOA->CRL = 0x33333333; 	//PA.0 ~ PA.7 输出、50Mhz
	GPIOA->CRL = 0x44444444; 	//PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
//	2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
	while(1)
	{
	//则第八位为1 (IDR 输入数据寄存器),则相应第0位也置为1 (BSRR为 端口位设置寄存器,BRR位复位寄存器)
		if((GPIOA->IDR & 0x0100) == 0x0100)		GPIOA->ODR = GPIOA->ODR | 0x01;		
		else									GPIOA->ODR = GPIOA->ODR & (~0x01);
		if((GPIOA->IDR & 0x0200) == 0x0200)		GPIOA->ODR = GPIOA->ODR | 0x02;		
		else									GPIOA->ODR = GPIOA->ODR & (~0x02);	
		if((GPIOA->IDR & 0x0400) == 0x0400)		GPIOA->ODR = GPIOA->ODR | 0x04;		
		else									GPIOA->ODR = GPIOA->ODR & (~0x04);
		if((GPIOA->IDR & 0x0800) == 0x0800)		GPIOA->ODR = GPIOA->ODR | 0x08;		
		else									GPIOA->ODR = GPIOA->ODR & (~0x08);
		if((GPIOA->IDR & 0x1000) == 0x1000)		GPIOA->ODR = GPIOA->ODR | 0x10;		
		else									GPIOA->ODR = GPIOA->ODR & (~0x10);		
					
//………………以此类推							
	}
	return(1);
}

方案二

int  main(void)
{
//	1、PA.0 ~ PA.7 输出、50Mhz	  PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
	GPIOA->CRL = 0x33333333; 	//PA.0 ~ PA.7 输出、50Mhz
	GPIOA->CRL = 0x44444444; 	//PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
//	2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
	while(1)
	{
	//则第八位为1 (IDR 输入数据寄存器),则相应第0位也置为1 (BSRR为 端口位设置寄存器,BRR位复位寄存器)
		if((GPIOA->IDR & 0x0100) == 0x0100)		GPIOA->BSRR = 0x01;	//第0位置1;	
		else						GPIOA->BRR = 0x01;	//第0位清零
		if((GPIOA->IDR & 0x0200) == 0x0200)		GPIOA->BSRR = 0x02;		
		else						GPIOA->BRR = 0x02;		
		if((GPIOA->IDR & 0x0400) == 0x0400)		GPIOA->BSRR = 0x04;		
		else						GPIOA->BRR = 0x04;
		if((GPIOA->IDR & 0x0800) == 0x0800)		GPIOA->BSRR = 0x08;		
		else						GPIOA->BRR = 0x08;

//………………以此类推				
	}
	return(1);
}
//若使程序简便,可使用#define GPIOA1 GPIOA->BSRR		#define GPIOA0 GPIOA->BRR
上一篇:STM32-(04):STM32F103VCT6芯片内部资源分析下一篇:STM32-(06):位绑定的基础应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值