STM32 学习三 GPIO操作

一、基础知识

STM32 学习三 GPIO操作_第1张图片

GPIO寄存器

  • 32位配置寄存器:GPIOx_CRL
  • 32位配置寄存器:GPIOx_CRH
  • 32位数据寄存器:GPIOx_IDR
  • 32位数据寄存器:GPIOx_ODR
  • 32位置位/复位寄存器:GPIOx_BSRR
  • 16位复位寄存器:GPIOx_BRR
  • 32位锁定寄存器:GPIOx_LCKR

工作模式:

  • 输入浮空
  • 输入上拉
  • 输入下拉
  • 模拟输入
  • 开漏输出
  • 推挽式输出
  • 推挽式复用功能
  • 开漏复用功能
每个I/O端口位可以自由编程,而I/O端口寄存器必须按32位字被访问,不允许半字或字节访问。
GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问,这样,在读和更改访问之间产生IRQ时不会发生危险。
每个I/O端口位的基本结构:
STM32 学习三 GPIO操作_第2张图片

端口位配置表:

STM32 学习三 GPIO操作_第3张图片

输出模式位:


端口配置低寄存器CRL:

STM32 学习三 GPIO操作_第4张图片

端口配置高寄存器CRH:

STM32 学习三 GPIO操作_第5张图片

端口输入数据寄存器IDR:


端口输出数据寄存器:ODR


锁定寄存器:GPIOx_LCKR

锁定寄存器位置

端口位设置寄存器:GPIOx_BSRR
端口位复位寄存器:GPIOx_BRR

二、编程测试

在GPIOA.0 .1引脚输出高电平:

#include "stm32f10x_map.h"

int main()
{
<span style="white-space:pre">	</span>//GPIOA->CRL  <span style="white-space:pre">		</span>	控制0-7引脚  工作模式
<span style="white-space:pre">	</span>//GPIOA->CRH 	  	<span style="white-space:pre">	</span>控制8-15引脚 工作模式
<span style="white-space:pre">	</span>//1.设置GPIOA引脚工作模式:
<span style="white-space:pre">	</span>//GPIO共16个引脚,让
<span style="white-space:pre">	</span>//GPIOA.0 GPIOA.1 
<span style="white-space:pre">	</span>//用推挽式输出、速度50Mhz
<span style="white-space:pre">	</span>GPIOA->CRL=0x33;

<span style="white-space:pre">	</span>//2.在相应的引脚输出一个电平
	GPIOA->ODR=0x00;	  			//清零
	GPIOA->ODR=0x3;   				//11
   return(1);
}

程序执行结果:

STM32 学习三 GPIO操作_第6张图片


通过第8引脚输入,控制第0引脚输出

#include "stm32f10x_map.h"

int main()
{
   <span style="white-space:pre">	</span>//配置 	PA.0 	推挽输出 50M
  <span style="white-space:pre">	</span>// 	PA.8	输入
	GPIOA->CRL = 0x03; 		//CNF0=00  	MODE0=11
	GPIOA->CRH = 0x04;		//CNF0=01	MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
   <span style="white-space:pre">	</span>//	PA.0=PA.8
   <span style="white-space:pre">	</span>while(1){
		if((GPIOA->IDR & 0x0100)==0x0100) //如果第8位为1
			GPIOA->ODR = 0x01;									 
		else
			GPIOA->ODR = 0x00;
   <span style="white-space:pre">	</span>}
   return(1);
}

程序仿真结果:

STM32 学习三 GPIO操作_第7张图片
点击8脚,发现0脚跟着改变。

通过高8位控制低8位引脚:方法1

#include "stm32f10x_map.h"

int main()
{
   <span style="white-space:pre">	</span>//配置 	PA.0-7 	推挽输出 50M
   <span style="white-space:pre">	</span>// 		PA.8-15	输入
	GPIOA->CRL = 0x33333333; 		//CNF0=00  	MODE0=11
	GPIOA->CRH = 0x44444444;		//CNF0=01	MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
   <span style="white-space:pre">	</span>//		PA.0=PA.8...
   <span style="white-space:pre">	</span>while(1){
		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);
		if((GPIOA->IDR & 0x2000)==0x2000)  GPIOA->ODR = GPIOA->ODR | 0x20; else GPIOA->ODR = GPIOA->ODR & (~0x20);
		if((GPIOA->IDR & 0x4000)==0x4000)  GPIOA->ODR = GPIOA->ODR | 0x40; else GPIOA->ODR = GPIOA->ODR & (~0x40);
		if((GPIOA->IDR & 0x8000)==0x8000)  GPIOA->ODR = GPIOA->ODR | 0x80; else GPIOA->ODR = GPIOA->ODR & (~0x80);
   <span style="white-space:pre">	</span>}
   <span style="white-space:pre">	</span>return(1);
}

输出结果:

STM32 学习三 GPIO操作_第8张图片

通过高8位控制低8位引脚:方法2 通过端口位设置/复位寄存器

#include "stm32f10x_map.h"

int main()
{
  <span style="white-space:pre">	</span> //配置 	PA.0-7 	推挽输出 50M
   <span style="white-space:pre">	</span>// 		PA.8-15	输入
	GPIOA->CRL = 0x33333333; 		//CNF0=00  	MODE0=11
	GPIOA->CRH = 0x44444444;		//CNF0=01	MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
  <span style="white-space:pre">	</span> //		PA.0=PA.8...
   <span style="white-space:pre">	</span>while(1){
		if((GPIOA->IDR & 0x0100)==0x0100)  		GPIOA->BSRR = 0x01;  //置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;
		if((GPIOA->IDR & 0x1000)==0x1000)  GPIOA->BSRR = 0x10; else GPIOA->BRR = 0x10;
		if((GPIOA->IDR & 0x2000)==0x2000)  GPIOA->BSRR = 0x20; else GPIOA->BRR = 0x20;
		if((GPIOA->IDR & 0x4000)==0x4000)  GPIOA->BSRR = 0x40; else GPIOA->BRR = 0x40;
		if((GPIOA->IDR & 0x8000)==0x8000)  GPIOA->BSRR = 0x80; else GPIOA->BRR = 0x80;
   <span style="white-space:pre">	</span>}
   <span style="white-space:pre">	</span>return(1);
}

通过高8位控制低8位引脚:方法3 定义宏

#include "stm32f10x_map.h"
#define PA0  GPIOA->BRR 
#define PA1	 GPIOA->BSRR 
int main()
{
  <span style="white-space:pre">	</span> //配置 	PA.0-7 	推挽输出 50M
  <span style="white-space:pre">	</span> // 		PA.8-15	输入
	GPIOA->CRL = 0x33333333; 		//CNF0=00  	MODE0=11
	GPIOA->CRH = 0x44444444;		//CNF0=01	MODE0=00 //模拟CNF0=00输入时,引脚变化不会引起IDR变化,浮空输入CNF0=01
   <span style="white-space:pre">	</span>//		PA.0=PA.8...
  <span style="white-space:pre">	</span> while(1){
		if((GPIOA->IDR & 0x0100)==0x0100)  PA1 = 0x01; else PA0 = 0x01;  //清0
		if((GPIOA->IDR & 0x0200)==0x0200)  PA1 = 0x02; else PA0 = 0x02;
		if((GPIOA->IDR & 0x0400)==0x0400)  PA1 = 0x04; else PA0 = 0x04;
		if((GPIOA->IDR & 0x0800)==0x0800)  PA1 = 0x08; else PA0 = 0x08;
		if((GPIOA->IDR & 0x1000)==0x1000)  PA1 = 0x10; else PA0 = 0x10;
		if((GPIOA->IDR & 0x2000)==0x2000)  PA1 = 0x20; else PA0 = 0x20;
		if((GPIOA->IDR & 0x4000)==0x4000)  PA1 = 0x40; else PA0 = 0x40;
		if((GPIOA->IDR & 0x8000)==0x8000)  PA1 = 0x80; else PA0 = 0x80;
  <span style="white-space:pre">	</span> }
  <span style="white-space:pre">	</span> return(1);
}


本文学习 《刘凯老师STm32培训视频》,感谢老师辛勤付出。

你可能感兴趣的:(IO,stm32,ARM,GPIO)