- typedef enum//自定义的软件实现,限定了模式的取值
- {
- GPIO_Mode_AIN = 0x0, //模拟输入(0000 0000)b
- GPIO_Mode_IN_FLOATING = 0x04,//浮空输入(00000100)b
- GPIO_Mode_IPD = 0x28, //下拉输入(0010 1000)b
- GPIO_Mode_IPU = 0x48, //上拉输入(0100 1000)b
- GPIO_Mode_Out_OD =0x14, //开漏输出(00010100)b
- GPIO_Mode_Out_PP = 0x10, //推挽输出(0001 0000)b
- GPIO_Mode_AF_OD = 0x1C, //复用开漏输出(0001 1100)b
- GP1O_Mode_AF_PP = 0x18 //复用推挽输出(0001 1000)b
- }GPIOMode_TypeDef;
- typedef struct{//用于模式配置的结构体
- uint16_t GPIO_Pin; //要配置的引脚
- uint16_t GPIO_Speed; //速率,只有输出模式使用
- uint16_t GPIO_Mode; //模式
- }GPIO_InitTypeDef;
- void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)//初始化GPIO
- {
- uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
- uint32_t tmpreg = 0x00, pinmask = 0x00;
-
- /* GPIO 模式配置 */
- currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);//把输入参数GPIO_Mode的低4为暂存
- if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)//bit4如果是1为输出模式,0为输入模式
- {
- /* 输出模式 */
- currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;;//配置速度
- }
- /* GPIO CRL 寄存器配置,CRL控制GPIO某一端口的低8位 */
-
- if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
- {
- tmpreg = GPIOx->CRL; //暂存CRL的值
- for (pinpos = 0x00; pinpos < 0x08; pinpos++)//寻找对应引脚
- {
- pos = ((uint32_t)0x01) << pinpos;
- /* Get the port pins position */
- currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
- if (currentpin == pos) //找到了对应引脚
- {
- pos = pinpos << 2; //乘4,因为CRL中每4位配置一个引脚
- pinmask = ((uint32_t)0x0F) << pos;
- tmpreg &= ~pinmask; //把这几个位先清零
- tmpreg |= (currentmode << pos);//写入模式的值
- //GPIO_Mode_IPD和GPIO_Mode_IPU是自定义的宏,可以自己设置
- if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)//判断是上拉还是下拉
- { //下拉
- GPIOx->BRR = (((uint32_t)0x01) << pinpos);//将BRR最低位置1
- }
- else//上拉
- {
- if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
- {
- GPIOx->BSRR = (((uint32_t)0x01) << pinpos);//将BSRR最低位置1
- }
- }
- }
- }
- GPIOx->CRL = tmpreg;//写入寄存器
- }
- /* GPIO CRH 寄存器配置 ,过程和CRL配置基本相同*/
- if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
- {
- tmpreg = GPIOx->CRH;
- for (pinpos = 0x00; pinpos < 0x08; pinpos++)
- {
- pos = (((uint32_t)0x01) << (pinpos + 0x08));
- currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
- if (currentpin == pos)
- {
- pos = pinpos << 2;
- pinmask = ((uint32_t)0x0F) << pos;
- tmpreg &= ~pinmask;
- tmpreg |= (currentmode << pos);
- if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
- {
- GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
- }
- if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
- {
- GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
- }
- }
- }
- GPIOx->CRH = tmpreg;
- }
- }
- int main()
- {
- GPIO_InitTypeDef GPIO_Inits;
- //打开GPIOC的时钟
- RCC->APB2ENR |=((1)<<4);
- //在此,GPIO模式的配置也实现了屏蔽寄存器,在不知道寄存器取值的情况下可以编程,逐步将寄存器编程进化至固件库编程
- GPIO_Inits.GPIO_Pin=GPIO_Pin_8; //对第8个引脚进行配置
- GPIO_Inits.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出模式
- GPIO_Inits.GPIO_Speed=SPIO_Speed_50MHZ;//推挽输出50mhz
- GPIO_Init(GPIOC,&GPIO_Inits);//初始化GPIOC
- while(1)
- {
- GPIO_ResetBits(GPIOC,GPIO_Pin_8);//开启LED
- delay(0x10000);
- GPIO_SetBits(GPIOC,GPIO_Pin_8);//关闭LED
- delay(0x10000);
- }
- }
- void delay(uint32_t time)
- {
- while(time--)
- ;
- }`
-
|