一、代码
IO.c
#include "STM32F10x.h"
#include "IO.h"
//IO初始化(引脚号【例如PA1】,引脚模式【例如GPIO_Mode_Out_PP】,初始电平【例如低电平0或者高电平1】)
void IO_Init(GPIOx_Pinx_enum GPIOx_Pinx, GPIOMode_TypeDef GPIO_Mode, u8 val)
{
static int Remap_SWJ_Disable = 0;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_TypeDef *GPIOx;
uint16_t GPIO_Pin;
Check_GPIOx_Pinx(GPIOx_Pinx, &GPIOx, &GPIO_Pin);
if (GPIOx == GPIOA)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
else if (GPIOx == GPIOB)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
else if (GPIOx == GPIOC)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
else if (GPIOx == GPIOD)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
else if (GPIOx == GPIOE)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
else if (GPIOx == GPIOF)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
else if (GPIOx == GPIOG)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
if (((GPIOx == GPIOB && GPIO_Pin == GPIO_Pin_3) || (GPIOx == GPIOB && GPIO_Pin == GPIO_Pin_4) ||
(GPIOx == GPIOA && GPIO_Pin == GPIO_Pin_13) || (GPIOx == GPIOA && GPIO_Pin == GPIO_Pin_14) ||
(GPIOx == GPIOA && GPIO_Pin == GPIO_Pin_15)) &&
Remap_SWJ_Disable == 0)
{
Remap_SWJ_Disable = 1;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
}
GPIO_InitStructure.GPIO_Pin = GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOx, &GPIO_InitStructure);
GPIO_WriteBit(GPIOx, GPIO_Pin, (BitAction)val);
}
//IO输出电平(引脚号【例如PA1】,输出电平【例如低电平0或者高电平1】)
void IO_Write(GPIOx_Pinx_enum GPIOx_Pinx, u8 val)
{
GPIO_TypeDef *GPIOx;
uint16_t GPIO_Pin;
Check_GPIOx_Pinx(GPIOx_Pinx, &GPIOx, &GPIO_Pin);
GPIO_WriteBit(GPIOx, GPIO_Pin, (BitAction)val);
}
//IO读取电平(引脚号【例如PA6】)
uint8_t IO_Read(GPIOx_Pinx_enum GPIOx_Pinx)
{
GPIO_TypeDef *GPIOx;
uint16_t GPIO_Pin;
Check_GPIOx_Pinx(GPIOx_Pinx, &GPIOx, &GPIO_Pin);
return (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin));
}
//内部转换,引脚号转时钟、引脚
void Check_GPIOx_Pinx(GPIOx_Pinx_enum GPIOx_Pinx, GPIO_TypeDef **GPIOx, uint16_t *GPIO_Pin)
{
if (GPIOx_Pinx < 16 * 1)
*GPIOx = GPIOA;
else if (GPIOx_Pinx < 16 * 2)
*GPIOx = GPIOB;
else if (GPIOx_Pinx < 16 * 3)
*GPIOx = GPIOC;
else if (GPIOx_Pinx < 16 * 4)
*GPIOx = GPIOD;
else if (GPIOx_Pinx < 16 * 5)
*GPIOx = GPIOE;
else if (GPIOx_Pinx < 16 * 6)
*GPIOx = GPIOF;
else if (GPIOx_Pinx < 16 * 7)
*GPIOx = GPIOG;
if (GPIOx_Pinx % 16 == 0)
*GPIO_Pin = GPIO_Pin_0;
else if (GPIOx_Pinx % 16 == 1)
*GPIO_Pin = GPIO_Pin_1;
else if (GPIOx_Pinx % 16 == 2)
*GPIO_Pin = GPIO_Pin_2;
else if (GPIOx_Pinx % 16 == 3)
*GPIO_Pin = GPIO_Pin_3;
else if (GPIOx_Pinx % 16 == 4)
*GPIO_Pin = GPIO_Pin_4;
else if (GPIOx_Pinx % 16 == 5)
*GPIO_Pin = GPIO_Pin_5;
else if (GPIOx_Pinx % 16 == 6)
*GPIO_Pin = GPIO_Pin_6;
else if (GPIOx_Pinx % 16 == 7)
*GPIO_Pin = GPIO_Pin_7;
else if (GPIOx_Pinx % 16 == 8)
*GPIO_Pin = GPIO_Pin_8;
else if (GPIOx_Pinx % 16 == 9)
*GPIO_Pin = GPIO_Pin_9;
else if (GPIOx_Pinx % 16 == 10)
*GPIO_Pin = GPIO_Pin_10;
else if (GPIOx_Pinx % 16 == 11)
*GPIO_Pin = GPIO_Pin_11;
else if (GPIOx_Pinx % 16 == 12)
*GPIO_Pin = GPIO_Pin_12;
else if (GPIOx_Pinx % 16 == 13)
*GPIO_Pin = GPIO_Pin_13;
else if (GPIOx_Pinx % 16 == 14)
*GPIO_Pin = GPIO_Pin_14;
else if (GPIOx_Pinx % 16 == 15)
*GPIO_Pin = GPIO_Pin_15;
}
IO.h
#ifndef _IO_H__
#define _IO_H__
#include "STM32F10x.h"
typedef enum
{
PA0,PA1,PA2,PA3,PA4,PA5,PA6,PA7,PA8,PA9,PA10,PA11,PA12,PA13,PA14,PA15,
PB0,PB1,PB2,PB3,PB4,PB5,PB6,PB7,PB8,PB9,PB10,PB11,PB12,PB13,PB14,PB15,
PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7,PC8,PC9,PC10,PC11,PC12,PC13,PC14,PC15,
PD0,PD1,PD2,PD3,PD4,PD5,PD6,PD7,PD8,PD9,PD10,PD11,PD12,PD13,PD14,PD15,
PE0,PE1,PE2,PE3,PE4,PE5,PE6,PE7,PE8,PE9,PE10,PE11,PE12,PE13,PE14,PE15,
PF0,PF1,PF2,PF3,PF4,PF5,PF6,PF7,PF8,PF9,PF10,PF11,PF12,PF13,PF14,PF15,
PG0,PG1,PG2,PG3,PG4,PG5,PG6,PG7,PG8,PG9,PG10,PG11,PG12,PG13,PG14,PG15,
}GPIOx_Pinx_enum;//IO引脚转换(时钟)
void Check_GPIOx_Pinx(GPIOx_Pinx_enum GPIOx_Pinx,GPIO_TypeDef** GPIOx,uint16_t* GPIO_Pin);//IO时钟转换内部调用
void IO_Init(GPIOx_Pinx_enum GPIOx_Pinx, GPIOMode_TypeDef GPIO_Mode,u8 val) ;//IO初始化
void IO_Write(GPIOx_Pinx_enum GPIOx_Pinx,u8 val) ;//IO输出电平
uint8_t IO_Read(GPIOx_Pinx_enum GPIOx_Pinx);//IO读取电平
#endif
二、调用方法
例:main.c
#include "STM32F10x.h"
#include "IO.h"
int main(void)
{
IO_Init(PA1, GPIO_Mode_Out_PP, 1); //初始化PA1引脚为推挽输出模式并输出1
IO_Write(PA1, 1); // PA1引脚输出高电平1
IO_Write(PA1, 0); // PA1引脚输出低电平0
IO_Init(PA12, GPIO_Mode_IPU, 1); //初始化PA12引脚为上拉输入模式初始值为0
u8 a = IO_Read(PA12); //读取PA12引脚的电平值(0或1),并把这个值给a
if (!IO_Read(PA12)) //当PA12输入低电平时
printf("PA12变成低电平了"); //串口打印字符"PA12变成低电平了"
}
三、该库函数的优缺点
优点
- 调用简单,可大大提高调试效率。
- 减少代码篇幅,使代码整体结构清晰明了。
缺点
调用的速度(例如打开一个端口输出高电平)会比原ST官方初始化方案慢1~5微秒。