int main(void)
{
LED_Init(); //初始化LED端口
while(1)
{
GPIO_bits_OUT(GPIOG,13,3,0x0006);
delay_ms(500);
GPIO_bits_OUT(GPIOG,13,3,0x0005);
delay_ms(500);
GPIO_bits_OUT(GPIOG,13,3,0x0003);
delay_ms(500);
}
}
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟
//PG13、PG14和PG15初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;//LED0、LED1和LED2对应IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOG, &GPIO_InitStructure); //初始化GPIO
GPIO_SetBits(GPIOG, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); //GPIOG13,G14,G15设置高,灯灭
}
解析:
如何使能时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG时钟
#define RCC_AHB1Periph_GPIOG ((uint32_t)0x00000040)
#define RCC ((RCC_TypeDef *) RCC_BASE)
#define RCC_BASE (AHB1PERIPH_BASE + 0x3800)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region
根据值的推算: 地址rcc = 0x40000000 + 0x00020000 + 0x3800 = 0x40023800 这个地址根据系统映射图可以看见是AHB总线地址
函数如下:
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
{
if (NewState != DISABLE)
{
RCC->AHB1ENR |= RCC_AHB1Periph; // 根据 结构体偏移位置 /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */
//设定地址 0x40023830地址的值或0x40 由下图可以看见为gpiogen位设置为1
}
else
{
RCC->AHB1ENR &= ~RCC_AHB1Periph; / /将gpiog为设置为0
}
}
二 gpio的配置流程
查电路图可知:led对应的gpio 为PG13 PG14 PG15
gpio属性具有通行 所以用 GPIO_InitTypeDef 结构体表示。先看gpio_init函数
先列出2个参数:
#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800)
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
#define PERIPH_BASE ((uint32_t)0x40000000)
即 GPIOG = 40021800
#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
/* ------------------------- Configure the port pins ---------------- */
/*-- GPIO Mode Configuration --*/
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
{
pos = ((uint32_t)0x01) << pinpos;
/* Get the port pins position */
currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
if (currentpin == pos)
{
GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
if ((GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) || (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_AF))
{
/* Check Speed mode parameters */
assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
/* Speed mode configuration */
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
/* Check Output mode parameters */
assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));
/* Output mode configuration*/
GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ;
GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
}
/* Pull-up Pull down resistor configuration*/
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
}
}
}