STM32F103 通过配置寄存器来控制I/O口

1、STM32F103 通过配置寄存器来控制I/O口

1.1、GPIO的概述

1.2、端口位配置表

1.3、GPIO各寄存器的配置

2、程序例举:

2.1、配置寄存器,使GPIOA.0、GPIOA.1置位:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"

void Delay_Ms(u16 time);




/* Private functions ---------------------------------------------------------*/ 
/*******************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
//	GPIOA->CRL = 0X00 ;
//	GPIOA->CRH = 0XFFFFFFFF ;
	/*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/
	//1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH
	GPIOA->CRL = 0x33 ; //  00---00 0011 0011  CNF0 = 00 MODE = 11

	//2、设置从引脚上输出的为高/低电平,即配置寄存器GPIOA_ODR
	GPIOA->ODR = 0X00000000 ;
	GPIOA->ODR = 0X00000003 ;  //  1 1 

  	while (1)
  	{
	 ;
  	}
}

2.2、配置寄存器,使GPIOA.0作为GPIOA.8的跟随器:(即A.8输入什么样的电平信号,A.0就输出怎样的电平信号)

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"

void Delay_Ms(u16 time);




/* Private functions ---------------------------------------------------------*/ 
/*******************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8输入一个电平信号,将该电平信号从GPIOA.0口输出
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{

	/*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/
	//1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH
		//GPIOA.0推挽输出,速度50MHZ , GPIOA.8浮空输入
		GPIOA->CRL = 0x03 ; // CNF0 = 00 MODE0 = 11
		GPIOA->CRH = 0x04 ; // CNF0 = 01 MODE0 = 00

	//2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入
	  	while(1)
	  	{
			if((GPIOA->IDR & 0X0100) == 0X0100)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				GPIOA->ODR = 0X01 ; 
			}
			else
			{
				GPIOA->ODR = 0X00 ;
			}
		 
	  	}

		return 1 ;
}

2.3、配置寄存器,使GPIOA.0-.7作为GPIOA.8-.15的跟随器:(即A.8-.15输入什么样的电平信号,对应的A.0-.7就输出怎样的电平信号)

方法一:通过配置GPIOA->IDR和GPIOA->ODR寄存器实现

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"

void Delay_Ms(u16 time);




/* Private functions ---------------------------------------------------------*/ 
/*******************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8输入一个电平信号,将该电平信号从GPIOA.0口输出
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{

	/*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/
	//1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH
		//GPIOA.0推挽输出,速度50MHZ , GPIOA.8浮空输入
		GPIOA->CRL = 0x03 ; // CNF0 = 00 MODE0 = 11
		GPIOA->CRH = 0x04 ; // CNF0 = 01 MODE0 = 00

	//2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入
	  	while(1)
	  	{
			if((GPIOA->IDR & 0X0100) == 0X0100)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				GPIOA->ODR = 0X01 ; 
			}
			else
			{
				GPIOA->ODR = 0X00 ;
			}
		 
	  	}

		return 1 ;
}

方法二:通过配置 置位/清除寄存器(低16位置位,高16位清零) 和 位清零寄存器

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"

void Delay_Ms(u16 time);




/* Private functions -----------------------------------------------------------------------------*/ 
/**************************************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出
* Input          : None
* Output         : None
* Return         : None
****************************************************************************************************/
int main(void)
{

	/*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/
	//1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH
		//GPIOA.0-.7推挽输出,速度50MHZ , GPIOA.8-.16浮空输入
		GPIOA->CRL = 0x33333333 ; // CNF0 = 00 MODE0 = 11
		GPIOA->CRH = 0x44444444 ; // CNF0 = 01 MODE0 = 00

	//2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入
	  	while(1)
	  	{	
		/*----------------------第0位----------------------*/
			if((GPIOA->IDR & 0X0100) == 0X0100)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				GPIOA->BSRR = 0X01 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X01 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第1位----------------------*/
			if((GPIOA->IDR & 0X0200) == 0X0200)	 //寄存器GPIOA->IDR的第9位为1,表示从在GPIOA.9口输入了高电平
			{
				GPIOA->BSRR = 0X02 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X02 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第2位----------------------*/
			if((GPIOA->IDR & 0X0400) == 0X0400)	 //寄存器GPIOA->IDR的第10位为1,表示从在GPIOA.10口输入了高电平
			{
				GPIOA->BSRR = 0X04 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X04 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第3位----------------------*/
			if((GPIOA->IDR & 0X0800) == 0X0800)	 //寄存器GPIOA->IDR的第11位为1,表示从在GPIOA.11口输入了高电平
			{
				GPIOA->BSRR = 0X08 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X08 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第4位----------------------*/
			if((GPIOA->IDR & 0X1000) == 0X1000)	 //寄存器GPIOA->IDR的第12位为1,表示从在GPIOA.12口输入了高电平
			{
				GPIOA->BSRR = 0X10 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X10 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第5位----------------------*/
			if((GPIOA->IDR & 0X2000) == 0X2000)	 //寄存器GPIOA->IDR的第13位为1,表示从在GPIOA.13口输入了高电平
			{
				GPIOA->BSRR = 0X20 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X20 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第6位----------------------*/
			if((GPIOA->IDR & 0X4000) == 0X4000)	 //寄存器GPIOA->IDR的第14位为1,表示从在GPIOA.14口输入了高电平
			{
				GPIOA->BSRR = 0X40 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X40 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第7位----------------------*/
			if((GPIOA->IDR & 0X8000) == 0X8000)	 //寄存器GPIOA->IDR的第15位为1,表示从在GPIOA.15口输入了高电平
			{
				GPIOA->BSRR = 0X80 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				GPIOA->BRR = 0X80 ;	//通过配置清零寄存器将对应位清零
			}
		 
	  	}

		return 1 ;
}

方法三:通过配置 置位/清除寄存器(低16位置位,高16位清零) 和 位清零寄存器  (对相关寄存器用宏定义封装)

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"

#define SET_GPIOA GPIOA->BSRR 
#define RESET_GPIOA GPIOA->BRR


/* Private functions -----------------------------------------------------------------------------*/ 
/**************************************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出
* Input          : None
* Output         : None
* Return         : None
****************************************************************************************************/
int main(void)
{

	/*--------控制STM32引脚GPIOA.0 GPIOA.1推挽输出高电平--------*/
	//1、设置GPIOA的引脚的工作模式,即配置寄存器GPIOA_CRL 、 GPIOA_CRH
		//GPIOA.0-.7推挽输出,速度50MHZ , GPIOA.8-.16浮空输入
		GPIOA->CRL = 0x33333333 ; // CNF0 = 00 MODE0 = 11
		GPIOA->CRH = 0x44444444 ; // CNF0 = 01 MODE0 = 00

	//2、配置寄存器GPIOA_ODR、GPIOA_IDR ,实现GPIOA.0输出 跟随 GPIOA.8的输入
	  	while(1)
	  	{	
		/*----------------------第0位----------------------*/
			if((GPIOA->IDR & 0X0100) == 0X0100)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X01 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X01 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第1位----------------------*/
			if((GPIOA->IDR & 0X0200) == 0X0200)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X02 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X02 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第2位----------------------*/
			if((GPIOA->IDR & 0X0400) == 0X0400)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X04 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X04 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第3位----------------------*/
			if((GPIOA->IDR & 0X0800) == 0X0800)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X08 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X08 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第4位----------------------*/
			if((GPIOA->IDR & 0X1000) == 0X1000)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X10 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X10 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第5位----------------------*/
			if((GPIOA->IDR & 0X2000) == 0X2000)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X20 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X20 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第6位----------------------*/
			if((GPIOA->IDR & 0X4000) == 0X4000)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X40 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X40 ;	//通过配置清零寄存器将对应位清零
			}
		/*----------------------第7位----------------------*/
			if((GPIOA->IDR & 0X8000) == 0X8000)	 //寄存器GPIOA->IDR的第8位为1,表示从在GPIOA.8口输入了高电平
			{
				SET_GPIOA = 0X80 ;  //通过配置置位/清零寄存器将对应位置一
			}
			else
			{
				RESET_GPIOA = 0X80 ;	//通过配置清零寄存器将对应位清零
			}
		 
	  	}

		return 1 ;
}

































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值