赞
踩
语言只是工具
总线->外设->端口
GPIO端口->IO端口
库函数
#define PERIPH_BASE ((unsigned int )0x40000000) #define APB1_PERIPH_BASE PERIPH_BASE #define APB2_PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHB_PERIPH_BASE (APB2_PERIPH_BASE + 0x10000) #define RCC_BASE (AHB_PERIPH_BASE + 0x1000) #define GPIOA_BASE (APB2_PERIPH_BASE + 0x0800 typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef struct { uint32_t CRL; uint32_t CRH; uint32_t IDR; uint32_t ODR; uint32_t BSRR; uint32_t BRR; uint32_t LCKR; }GPIO_TypeDef; #define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
封装成结构体 节约编码时间 简化逻辑
main.c
//打开GPIOA端口的时钟
RCC_APB2ENR |= ( (1) << 2);
//配置 IO口 为输出
GPIOA->CRH |= ( (1) << (4*0) );
//控制 ODR 寄存器
GPIOA->ODR &= ~(1<<7);
防止多次调用头文件时重复定义
区别用户定义的宏
#ifndef _STM32F10X_GPIO_H
#define _STM32F10X_GPIO_H
#endif /*_STM32F10X_GPIO_H*/
// stm32f10x_gpio.c #include "stm32f10x_gpio.h" #include "stm32f10x.h" // 端口位设置/清除寄存器 void GPIO_SetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) { GPIOx->BSRR |= GPIO_Pin; } // 端口位清除寄存器 void GPIO_ResetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin) { GPIOx->BRR |= GPIO_Pin; }
// stm32f10x_gpio.h #ifndef _STM32F10X_GPIO_H #define _STM32F10X_GPIO_H #include "stm32f10x.h" //GPIO 引脚定义 #define GPIO_Pin_0 ((uint16_t)0x0001) /*!< 选择Pin0*/ //(00000000 00000001)a #define GPIO_Pin_1 ((uint16_t)0x0002)/*!< 选择Pin1*/ //(00000000 00000010)a #define GPIO_Pin_2 ((uint16_t)0x0004) /*!< 选择Pin2*/ //(00000000 00000100)a #define GPIO_Pin_3 ((uint16_t)0x0008) /*!< 选择Pin3*/ //(00000000 00001000)a #define GPIO_Pin_4 ((uint16_t)0x00010) /*!< 选择Pin4*/ //(00000000 00010000)a #define GPIO_Pin_5 ((uint16_t)0x0020) /*!< 选择Pin5*/ //(00000000 00100000)a #define GPIO_Pin_6 ((uint16_t)0x0040) /*!< 选择Pin6*/ //(00000000 01000000)a #define GPIO_Pin_7 ((uint16_t)0x0080) /*!< 选择Pin7*/ //(00000000 10000000)a #define GPIO_Pin_8 ((uint16_t)0x0100) /*!< 选择Pin8*/ //(00000000 00000001)a #define GPIO_Pin_9 ((uint16_t)0x0200) /*!< 选择Pin9*/ //(00000010 00000000)a #define GPIO_Pin_10 ((uint16_t)0x0400) /*!< 选择Pin10*/ //(00000100 00000000)a #define GPIO_Pin_11 ((uint16_t)0x0800) /*!< 选择Pin11*/ //(00001000 00000000)a #define GPIO_Pin_12 ((uint16_t)0x1000) /*!< 选择Pin12*/ //(00010000 00000000)a #define GPIO_Pin_13 ((uint16_t)0x2000) /*!< 选择Pin13*/ //(00100000 00000000)a #define GPIO_Pin_14 ((uint16_t)0x4000) /*!< 选择Pin14*/ //(01000000 00000000)a #define GPIO_Pin_15 ((uint16_t)0x8000) /*!< 选择Pin15*/ //(10000000 00000000)a #define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< 选择全部引脚*/ //(11111111 11111111)a void GPIO_SetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin); void GPIO_ResetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin); #endif /*_STM32F10X_GPIO_H*/
// main.c
#elif 1
GPIOA->ODR &= ~(1<<7);
//打开GPIOA端口的时钟
RCC->APB2ENR |= ( (1) << 2);
//配置 IO口 为输出
GPIOA->CRH |= ( (1) << (4*0) );
GPIO_SetBits(GPIOA,GPIO_Pin_8);
//GPIO_ResetBits(GPIOA,GPIO_Pin_8);
#endif
寄存器中左移一位相当于乘以2
main.c
GPIO_InitTypeDef GPIO_InitStructure;
RCC->APB2ENR |= ( (1) << 2);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//传入两个参数 GPIO端口 配置引脚
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
//GPIO_ResetBits(GPIOA,GPIO_Pin_8);
stm32f10x_gpio.h
配置GPIO结构体
typedef struct
{
uint16_t GPIO_Pin;
uint16_t GPIO_Speed;
uint16_t GPIO_Mode;
}GPIO_InitTypeDef;
官方固件库 GPIO配置函数
stm32f10x_gpio.c
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; /* Check the parameters */ // assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); // assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); // assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); /*---------------------------- GPIO Mode Configuration -----------------------*/ /*---------------------------- GPIO 模式配置 -----------------------*/ //把输入参数GPIO_Mode的低四位暂存在currentmode currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F); //bit 是1代表输入 //bit 是0代表输出 //判断bit4是1还是0,即首选判断是输入还是输出模式 if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00) { /* Check the parameters */ //assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed)); /* Output mode */ //输出模式则要设置输出速率 currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed; } /*---------------------------- GPIO CRL Configuration ------------------------*/ /* Configure the eight low port pins */ /*——————————GPIO CRL寄存器 控制着低8位I/O口——————————————*/ //配置端口低8位 即Pin0-Pin7 if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00) { //首先备份CRL寄存器的值 tmpreg = GPIOx->CRL; //循环 从Pin0开始配对找出具体的Pin值 for (pinpos = 0x00; pinpos < 0x08; pinpos++) { //pos的值为一 左移pinpos位 pos = ((uint32_t)0x01) << pinpos; /* Get the port pins position */ currentpin = (GPIO_InitStruct->GPIO_Pin) & pos; //找到使用引脚 if (currentpin == pos) { //pinpos左移两位(乘以4),寄存器中4个寄存器位控制一个引脚 pos = pinpos << 2; /* Clear the corresponding low control register bits */ //把控制这个引脚的寄存器清零,其他的寄存器位不变 pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ //向寄存器写入将要配置的引脚的模式 tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ //判断是否为下拉输出 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { //下拉输出模式,默认为1,对BRR寄存器写1可对引脚置0 GPIOx->BRR = (((uint32_t)0x01) << pinpos); } else { /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << pinpos); } } } } GPIOx->CRL = tmpreg; } /*---------------------------- GPIO CRH Configuration ------------------------*/ /* Configure the eight high port pins */ if (GPIO_InitStruct->GPIO_Pin > 0x00FF) { tmpreg = GPIOx->CRH; for (pinpos = 0x00; pinpos < 0x08; pinpos++) { pos = (((uint32_t)0x01) << (pinpos + 0x08)); /* Get the port pins position */ currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos); if (currentpin == pos) { pos = pinpos << 2; /* Clear the corresponding high control register bits */ pinmask = ((uint32_t)0x0F) << pos; tmpreg &= ~pinmask; /* Write the mode configuration in the corresponding bits */ tmpreg |= (currentmode << pos); /* Reset the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD) { GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08)); } /* Set the corresponding ODR bit */ if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU) { GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08)); } } } GPIOx->CRH = tmpreg; } }
#define LED_G_GPIO_PORT GPIOA
#define LED_G_GPIO_CLK_ENABLE (RCC->APB2ENR |= ( (1) << 2));
#define LED_G_GPIO_PIN GPIO_Pin_8
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。