#define GPIO_pin_0 ((uint16_t)0x0001)// 1<<0
#define GPIO_pin_1 ((uint16_t)0x0002)// 1<<1
#define GPIO_pin_2 ((uint16_t)0x0004)// 1<<2
#define GPIO_pin_3 ((uint16_t)0x0008)// 1<<3
#define GPIO_pin_4 ((uint16_t)0x0010)// 1<<4
#define GPIO_pin_5 ((uint16_t)0x0020)// 1<<5
#define GPIO_pin_6 ((uint16_t)0x0040)// 1<<6
#define GPIO_pin_7 ((uint16_t)0x0080)// 1<<7
#define GPIO_pin_8 ((uint16_t)0x0100)// 1<<8
#define GPIO_pin_9 ((uint16_t)0x0200)// 1<<9
#define GPIO_pin_10 ((uint16_t)0x0400)// 1<<10
#define GPIO_pin_11 ((uint16_t)0x0800)// 1<<11
#define GPIO_pin_12 ((uint16_t)0x1000)// 1<<12
#define GPIO_pin_13 ((uint16_t)0x2000)// 1<<13
#define GPIO_pin_14 ((uint16_t)0x4000)// 1<<14
#define GPIO_pin_15 ((uint16_t)0x8000)// 1<<15
typedef struct
{
uint32_t CRL;
uint32_t CRH;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t LCKR;
}GPIO_Typedef;
typedef enum
{
GPIO_Speed_10MHz=1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_Typedef;
typedef enum
{
GPIO_Mode_AIN=0x00,//模拟输入
GPIO_MODE_IN_FLOATING=0x04,//浮空输入
GPIO_MODE_IPD=0x28,//下拉输入
GPIO_MODE_IPU=0x48,//上拉输入
GPIO_MODE_Out_OD=0x14,//开漏输出
GPIO_MODE_Out_PP=0x10,//推挽输出
GPIO_MODE_AF_OD=0x1c,//复用开漏输出
GPIO_MODE_AF_PP=0x18 //复用推挽输出
}GPIOMode_Typedef;
typedef struct
{
uint16_t GPIO_Pin;
GPIO_Speed_Typedef GPIO_Speed;
GPIOMode_Typedef GPIO_Mode;
}GPIO_InitTypedef;
/************需要配置的具体数据*****************/
GPIO_InitTypedef GPIO_Initstruct;
*(unsigned int*)0x40021018|=(1<<4);//配置RCC寄存器使能GPIOde时钟
GPIO_Initstruct.GPIO_pin=GPIO_pin_2;
GPIO_Initstruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Initstruct.GPIO_Speed=GPIO_Speed_10MHz;
/******************************************************/
、/*************GPIO的初始化*********************************/
void GPIO_Init(GPIO_Typedef *GPIOx,GPIO_InitTypedef *GPIO_InitStruct)
{
uint32_t currentmode=0x00,currentpin=0x00,pinpos=0x00,pos=0x00;
uint32_t tmpreg=0x00,pinmask=0x00;
//GPIO 模式设置
/*****GPIO_Mode 的低四位暂存currentmode*********/
currentmode|=((uint32_t)GIO_InitStruct->GPIO_Mode)&((uint32_t)0x0f);
//判断bit4 是0, 还是1. 即 输出还是输入
if(((uint32_t)GPIO_InitStruct->GPIO_Mode)&((uint32_t)0x10)!=0x00)
{
//输出模式需要设置输出速度
currentmod|=(uint32_t)GPIO_InitStruct->GPIO_Speed;//模式的低四位+速度
}
/************GPIO_CRL寄存器配置 CRL控制寄存器控制低8位IO端口,pin0~pin7**********/
if(((uint32_t)GPIO_InitStruct->GPIO_Pin)&((uint32_t)0x00ff)!=0x00) //一个端口有四个位 CNF[1:0] MODE[1:0]
{
//先备份CRL寄存器的值
tmpreg=GPIOx->CRL;
//循环从pin0 开始配对,找出具体的pin
for(pinpos=0x00;pinpos<0x08;pinpos++)
4{
//pos 的值位1,左移pinpos 位
pos=((uint32_t)0x01)<<pinpos; //1,左移 1,2,3,4,5,6,7,8位
//令pos 输入参数GPIO_PIN做位与运算,位下面判断做准备
currentpin=(GPIO_InitStruct->GPIO_Pin)&pos;//该句多余吗?
//若currentpin=pos 则找到该引脚
if(currentpin==pos)
{
//pinpos左移2两位(乘以4),寄存器的4个寄存器配置1个引脚
pos=pinpos<<2;
//把控制这个银价搜的4个寄存器清零,其他寄存器的位不变
pinmask=((uint32_t)0x0f)<<pos;
tmpreg&=~pinmask;
//向寄存器将要配置的引脚模式
tmpreg|=(currentmode<<pos);
//判断是否为下拉输入模式
if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPD)
{
//下拉输入模式,引脚默认设置0,对BRR 寄存器写1,可对引脚置0
GPIOx->BRR=(((uint32_t)0x01)<<pinpos);
}
else
{
//判断是否为下拉模式
if(GPIO_InitStruct->GPIO_Mode==GPIO_Mode_IPU)
{
//上拉输入模式,引脚默认为1,对BSRR寄存器写1,可对引脚置1
GPIOx->BSRR=(((uint32_t)0x01)<<pinpos);
}
}
}
}
//把前面处理后的暂存器的值写入到CRL寄存器中
GPIOx->CRL=tmpreg;
}
} |