补上章:GPIO的分组
GPIO的划分按组划分,GPIOA、GPIOB、、、等,每组最多16个引脚,pin A0、A1~A15
原理图上以Pxy(x代表A,B,C...,y代表数字0~15)命名。
比如PE6:代表是GPIOE的6号引脚。
1.查看原理图
LED灯电路图:
如图,因为3.3V在二极管的右边,想要让LED灯亮的话需要两边有电压差。②是引脚名,可以查看原理图对应接到哪个GPIO接口,如下图二:
刚才我们通过分析了LED的原理图得知,想让LED发光只需要让两边拥有电压差,也就说只需要给LED灯左边输出一个低电平,电流就会导通,LED就会发光。
根据图二可以得知LED1的引脚对应的GPIO接口为PE8,也就是GPIOE的第8号引脚,当该引脚输出一个低电平时,有电压差,LED1灯发光,当输出一个高电平时,没有电压差,LED不会发光。
#include "drv_led.h"
void delay_ms(uint32_t ms)
{
uint32_t i;
// 基于系统时钟的粗略延时函数
for ( i = 0; i < (ms * 10000); ++i) {
__NOP();
}
}
void drv_led_init(void)
{
/*标准库开发
GPIO_InitTypeDef GPIO_InitStruct; //配置初始化结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能时钟
//配置端口号分别为LED1,2,3
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //输出模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //设置上拉
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; //速率
GPIO_Init(GPIOE, &GPIO_InitStruct);
*/
//寄存器开发
//时钟使能
RCC->AHB1ENR |= (0x01<<4);
//设置模式为输出
GPIOE->MODER &= ~(0x3F<<16); //清0
GPIOE->MODER |= (0x15<<16); //3个全部设置为输出
}
void drv_led_open(uint16_t GPIO_Pin)
{
//GPIO_ResetBits(GPIOE,GPIO_Pin); //标准库开发
//寄存器开发
int i=0;
if(GPIO_Pin == GPIO_Pin_8) i=8; //8号端口-LED1
else if(GPIO_Pin == GPIO_Pin_9) i=9; //9号端口-LED2
else if(GPIO_Pin == GPIO_Pin_10) i=10; //10号端口-LED3
GPIOE->BSRRH |= (0x1<<i); //低电平,开灯
}
void drv_led_close(uint16_t GPIO_Pin)
{
//GPIO_SetBits(GPIOE,GPIO_Pin); //标准库开发
//寄存器开发
int i=0;
if(GPIO_Pin == GPIO_Pin_8) i=8;
else if(GPIO_Pin == GPIO_Pin_9) i=9;
else if(GPIO_Pin == GPIO_Pin_10) i=10;
GPIOE->BSRRL |= (0x1<<i); //高电平,关灯
}
注:注释代码部分为标准库开发,没有注释部分为寄存器开发,两种都可以实现。
时钟使能是必须要有的,可以简单理解为时钟就是cpu处理的频率,必须要有时钟,才能使用。
通过这个实际例子我们可以看到标准库开发和寄存器开发的区别。在初始化函数中,标准库需要全部配置,而使用寄存器控制只需要3行代码。可以对比下图理解寄存器,有关寄存器说明如下: