STM32单片机的IO口可以设置为8中模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能
每个IO口可以自由使用,但是都必须按照32位字节形式访问。在单片机内部,每个IO口北斗杯7个寄存器控制。
他们分别是:
2个32位的端口配置寄存器CRL和CRH;
2个32位的数据寄存器IDR和ODR;
1个32位的置位/复位寄存器BSRR;
1个16位的复位寄存器BRR;
1个32位的锁存寄存器LCKR。
但是在我们使用过程中一般都是使用固件库的开发方式:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
该函数有两个参数:
一个参数指定具体的GPIO,其范围为GPIOA-GPIOG
第二个参数是初始化参数结构体指针,结构体的类型为GPIO_InitTypeDef
,在找到该函数体时,双击GPIO_Init
函数,鼠标右键选择Go to definition of … 就可以找到该函数的原型,然后选中GPIO_InitTypeDef
该函数体,就可以找到该结构体内部的参数;
typedef struct
{
uint16_t GPIO_Pin; // 具体哪个引脚可以在GPIO_Pin_0 ~ GPIO_Pin_15之间进行选择
GPIOSpeed_TypeDef GPIO_Speed; //设置该脚的传输速率
GPIOMode_TypeDef GPIO_Mode; //设置该脚的工作模式
}GPIO_InitTypeDef;
双击GPIOSpeed_TypeDef
该结构体,鼠标右键Go to definition of …可以找到该结构体的原型。可以在提供的参数中进行选择,10MHZ,2MHz,50MHz。配置具体的传输速率。
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
双击GPIOMode_TypeDef
结构体,右键Go to definition of …同样可以找到结构体的原型,可以在提供的参数中进行选择。
typedef enum
{ GPIO_Mode_AIN = 0x0,//模拟输入
GPIO_Mode_IN_FLOATING = 0x04,//浮空输入
GPIO_Mode_IPD = 0x28,//下拉输入
GPIO_Mode_IPU = 0x48,//上拉输入
GPIO_Mode_Out_OD = 0x14,//开漏输出
GPIO_Mode_Out_PP = 0x10,//推挽输出
GPIO_Mode_AF_OD = 0x1C,//复用开漏输出
GPIO_Mode_AF_PP = 0x18//复用推挽输出
}GPIOMode_TypeDef;
设置单个GPIO端口输出时通过函数GPIO_SetBits()
与GPIO_ResetBits()
这个两个函数实现的,同样我们可以鼠标右键跳转到该函数的原型:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
我们可以通过这两个函数来控制单个或多个GPIO端口输出高电平或者低电平。
下面为跑马灯的具体实现函数:
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
}
上面为跑马灯实验的全部流程,IO口操作过于简单,但还是做一个简单的概括:
(1)结构体的定义
(2)使能IO口的时钟,调用的函数为RCC_APB2PeriphClockCmd
(3)初始化IO操作,需要将GPIO_Init
中的三个参数全部配置一次:端口,输出模式,端口传输速率。
头文件LED.H的编写:
#ifndef __LED_H
#define __LED_H
#include "sys.h"//包含在系统头文件下
#define LED0 PBout(5)// 宏定义,以后可以根据LED0的赋值来控制端口电平,位带操作
void LED_Init(void);//函数的声明
#endif
在main函数中可以使用while循环对LED进行控制,编写延时函数,可以控制LED闪烁。
while(1)
{
LED0 = 1;
delay(1000ms);
LED0 = 0;
delay(1000ms)
}
注意:在主函数中需要包含LED的头文件,还需要在主函数中对LED_Init
进行声明。
参考文献:《STM32F1开发指南(库函数板)》