要想使用STM32的GPIO功能,首先要明确这一功能由谁来支配。你应该了解到对于STM32单片机来说,有一部本功能是由Cortex内核来决定的,而另一部分功能则由STM32芯片自己决定 。翻开Cortex内核手册你会看到,GPIO功能是有芯片自己来决定的。
●由手册到流程
打开stm32手册,定位到GPIO这一章,不是手册的所有内容都要读,也不是GPIO这一章的所有内容都要读。每一章的开始都有一个功能介绍,也许依据这个介绍就已经可以操作你要的功能了。。。
1、功能概述
其实由上面的介绍已经可以总结出GPIO的基本配置过程:模式选择、输出设置、输出速度、上拉下拉。想在具体一点?直接跳转到寄存器详解
2、寄存器详解
GPIOx_MODER(模式选择)
这是一个32位的寄存器,分为16组,也就是说2位控制一个IO引脚(STM32的每一个IO口恰好是16个管脚)。可以看到每一个IO管脚都有4种功能,目前我们使用的是前两种最简单的功能。另外,请注意它的复位值
GPIOx_OTYPER(输出类型)
这里可以设置输出模式,对于输出又分为两种:推挽和开漏。(GPIO是16位的,因此这个寄存器的高16位系统保留了)
GPIOx_OSPEEDR(输出速度)
输出功能无非是要驱动某一个外部器件,因此输出速度可以根据外部连接电路来设置
GPIOx_PUPDR(上拉下拉)
配置IO上拉或者下拉,分为16组,2位控制一个管脚
GPIOx_IDR(端口数据输入)
GPIOx_ODR(端口数据输出)
不管是数据的输入还是输出,永远都是16位的,因此这两个寄存器的高16位都是系统保留的。
3、GPIO初始化流程
1)打开GPIO时钟(每一个模块使用的时候,必须先打开对应时钟)
2)选择输入输出模式
3)设置输出类型(如果是输出模式)
4)设置输出速度(如果是输出模式)
5)选择上拉或下拉
●由流程到代码(以led为例子)
1、直接操作寄存器
void led_init()
{
//打开GPIOA时钟
RCC->AHB1ENR |= 1;
//设置PA6位输出模式
GPIOA->MODER |= 1 //设置推挽输出
GPIOA->OTYPER &= ~(1 //设置输出速度50MHz
GPIOx->OSPEEDR |= 2 //设置上拉
GPIOA->PUPDR |=1 }
void led_on()
{
GPIOA->ODR &= ~(1 }
void led_off()
{
GPIOA->ODR |= 1 }
2、库函数
操作库函数,需要找到对应的库函数源文件,以及头文件。在库函数中,初始化使用结构体,结构体的定义在头文件中
void myled_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打开时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//选择管脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
//选择为输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//推挽输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//输出速度100MHz
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//上拉
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//开灯
void led_on()
{
GPIO_ResetBits(GPIOA, GPIO_Pin_6);
}
//关灯
void led_off()
{
GPIO_SetBits(GPIOA, GPIO_Pin_6);
}