STM32学习笔记-如何操作GPIO

以一个按键控制一个LED为例

1、使能对应GPIOx的时钟,调用void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)函数;
/*APB2线上外设使能时钟函数,通过宏将各外设在RCC_APB2ENR寄存器上的对应使能位重新定义,通过函数传递宏定义操作寄存器实现外设使能*/

2、创建一个GPIO_InitTypeDef类型的结构体变量,并给结构体成员变量进行赋值:GPIO_Mode和GPIO_Speed固件库已经使用枚举的方式提供,GPIO_Pin固件库已经通过宏定义方式定义;

3、调用GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)函数初始化GPIO;

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
/*GPIO初始化函数,第一个参数为GPIO_TypeDef类型的结构体指针,且已经通过宏定义对应好GPIOx的地址,结构体内的成员排序正好对应需要操作的GPIOx的各个寄存器的地址*/
/*第二个参数为GPIO_InitTypeDef类型的结构体指针,库函数值创建了类型,未创建结构体及对应地址,故需自己创建结构体并对结构体成员变量进行赋值,最后调用此函数初始化*/

4、调用GPIO的读写函数实现按键控制LED的功能

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
/*对GPIOX对应的GPIO_PING进行写1或者写0操作,也是对GPIOx_BRR和BSRR寄存器进行操作,实现GPIOx->ODR的写1还是0的操作*/
/*与SetBits和ResetBits差异为,SetBits函数就是写1,ResetBits写0,而GPIO_WriteBit写多少是看第三个参数BitAction BitVal,可以是Bit_RESET和Bit_SET其中一个值*/

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*GPIO作为输入模式下,读对应GPIOX的16个ping中其中一个ping的值并返回,其实就是在读取GPIOx_IDR寄存器对应位置的值,通过GPIOx->IDR & GPIO_Pin的与操作,确认对应位置是0?是1?*/

5、GPIO相关库函数说明

stm32f10x_rcc.h和stm32f10x_rcc.c中的时钟相关函数

void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
/*对应外设寄存器置复位操作,操作RCC_APB2RSTR寄存器,第一个参数已通过宏将各外设在RCC_APB2RSTR寄存器上的对应位置对应,通过函数传递宏定义操作寄存器实现外设寄存器复位*/
 

stm32f10x_gpio.h和stm32f10x_gpio.c中的GPIO相关函数

void GPIO_DeInit(GPIO_TypeDef* GPIOx);
/*将对应GPIOX的寄存器恢复为默认值,实际操作是调用RCC_APB2PeriphResetCmd函数,操作RCC_APB2RSTR对对应外设的寄存器进行复位,整个过程,先置1复位寄存器,再置0退出复位操作*/

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
/*GPIO初始化函数,第一个参数为GPIO_TypeDef类型的结构体指针,且已经通过宏定义对应好GPIOx的地址,结构体内的成员排序正好对应需要操作的GPIOx的各个寄存器的地址*/
/*第二个参数为GPIO_InitTypeDef类型的结构体指针,库函数值创建了类型,未创建结构体及对应地址,故需自己创建结构体并对结构体成员变量进行赋值,最后调用此函数初始化*/


void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
/*对用户创建的GPIO_InitTypeDef类型的结构体内各个成员变量附默认值*/


uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*GPIO作为输入模式下,读对应GPIOX的16个ping中其中一个ping的值并返回,其实就是在读取GPIOx_IDR寄存器对应位置的值,通过GPIOx->IDR & GPIO_Pin的与操作,确认对应位置是0?是1?*/


uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
/*GPIO作为输入模式下,读取整个GPIOx_IDR寄存器的低16位值,高16位保留,并返回一个U16INT的值*/


uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*GPIO作为输出模式下,读对应GPIOX的16个ping中其中一个ping的值并返回,其实就是在读取GPIOx_ODR寄存器对应位置的值,通过GPIOx->ODR & GPIO_Pin的与操作,确认对应位置是0?是1?*/


uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
/*GPIO作为输出模式下,读取整个GPIOx_ODR寄存器的低16位值,高16位保留,并返回一个U16INT的值*/


void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*操作GPIOx结构体内对应的成员BSRR(就是在操作对应GPIO的BSRR寄存器),哪个ping脚选择为第二个参数;*/ 
/*第二个参数,GPIO_Pin1~15, 库函数已经宏定义为0x0001 / 2 / 4 / 8,, 0x0010 / 20 / 40 / 80....0x8000,对应BSRR寄存器的低16个bit写入1,置1操作,实现高电平输出 */


void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*与GPIO_SetBits类似,结果相反,同样操作GPIOX结构体,实现对BRR寄存器的操作,为清除操作,写入1为清除,,即置0,实现低电平输出*/


void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
/*对GPIOX对应的GPIO_PING进行写1或者写0操作,也是对GPIOx_BRR和BSRR寄存器进行操作,实现GPIOx->ODR的写1还是0的操作*/
/*与SetBits和ResetBits差异为,SetBits函数就是写1,ResetBits写0,而GPIO_WriteBit写多少是看第三个参数BitAction BitVal,可以是Bit_RESET和Bit_SET其中一个值*/


void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
/*一次性对GPIOX的16个ping进行写入,操作GPIOx->ODR = PortVal;*/


void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/*锁定GPIOX对应的GPIO_PIN的配置,防止被改动*/


void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
/*看着像时GPIO的函数,其实操作的是AFIO_EVCR寄存器,用来配置对应的GPIO口的具体ping脚作为事件输出功能,GPIO_PortSource对应GPIO_PortSourceGPIOA~G,物理层的话可以理解为GPIOA~G, GPIO_PinSource对应GPIO_PinSource0~15,物理层的话可以理解为ping0~ping15*/


void GPIO_EventOutputCmd(FunctionalState NewState);
/*操作的也是AFIO_EVCR寄存器,事件输出功能的使能函数,与GPIO_EventOutputConfig配套使用*/


void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
/*GPIO的重映射功能,操作的是AFIO_MAPR寄存器,GPIO_Remap库函数已根据硬件可重映射的功能进行宏定义后可选择输入,第二个参数ENABLE代表使能*/


void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
/*操作AFIO_EXTICR寄存器,配置AFIO的数据选择器来实现GPIO到中断的线路选择,第一个参数选择GPIO_PortSourceGPIOx,对应GPIOX,第二个参数选择GPIO_PinSourcex,对应GPIO_pingX*/


void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
/*以太网相关,未知*/

#include "stm32f10x.h"                  // Device header
#include "DELAY.H"
int main()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct_Ouput;
	GPIO_InitStruct_Ouput.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct_Ouput.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStruct_Ouput.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct_Ouput);
	GPIO_Write(GPIOA, 0xFFFF);
	
	GPIO_InitTypeDef GPIO_InitStruct_Input;
	GPIO_InitStruct_Input.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct_Input.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_6;
	GPIO_InitStruct_Input.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct_Input);
	
		int x=0;
		int y=0;
	
	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4)==0)
		{
			Delay_ms(20);
			while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4));
			Delay_ms(20);
			x=!x;
				if(x==0)
				{
					GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
				}
				else
				{
					GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
				}
		}
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)==0)
		{
			Delay_ms(20);
			while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6));
			Delay_ms(20);
			y=!y;
				if(y==0)
				{
					GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);
				}
				else
				{
					GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);
				}
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值