1、STM32F103 通过配置寄存器来控制I/O口
1.1、GPIO的概述
1.2、端口位配置表![](https://img-blog.csdn.net/20140413165606046?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
1.3、GPIO各寄存器的配置![](https://img-blog.csdn.net/20140413165613421?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165625906?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165637531?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165647812?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165654703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165704109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165712500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165720375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165729484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140413165739750?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
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 ;
}