目的:操作IO口电平
配置文件:#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
寄存器:GPIOx_CRL:32位,用于配置IO低8位,配置输入输出模式,输出速度
GPIOx_CRH:32位,用于配置IO高8位,配置输入输出模式,输出速度
GPIOx_IDR:32位,高16位保留,低16为对应16个IO口,输入寄存器,只能 16位读出
GPIOx_ODR:32位,高16位保留,低16为对应16个IO口,输出寄存器,只能 16位读出
GPIOx_BSRR:32位,高16位写1置位,低16位写1复位,对应16个IO口, 针对输出寄存器
GPIOx_BRR:32位,高16位保留,低16位写1清零,对应16个IO口,
针对输出寄存器
GPIO结构体:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
上述是IO口的寄存器结构体
其中:#define __IO volatile /*!< defines 'read / write' permissions */
typedef unsigned int uint32_t;
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
其中:
uint16_t GPIO_Pin:无符号16位二进制,指示IO口的引脚号
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */
#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 */
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< All pins selected */
GPIOSpeed_TypeDef GPIO_Speed:枚举量,设置端口速度
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Speed_10MHz) || ((SPEED) == GPIO_Speed_2MHz) || \((SPEED) == GPIO_Speed_50MHz))
GPIOMode_TypeDef GPIO_Mode:枚举量,设置端口输入输出模式
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;
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \ ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
库函数:
GPIO_DeInit(GPIO_TypeDef* GPIOx);将IO口寄存器恢复至缺省值,参数:GPIO端口标号
GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct):GPIO初始化函数,参数:IO端口标号,IO初始化结构体
GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct):将IO配置为缺省值,参数:IO初始化结构体
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin):读取输入寄存器的值,参数:GPIO端口标号,端口号,返回值为8位无符号二进制数,即unsigned char型
读取的是某一位IO口的状态
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx):读取输入寄存器的值,参数:GPIO端口标号,返回值为16为无符号二进制数,即unsigned short int型变量,读取的是某一个字母标号下的状态,一次性读出16位IO口的寄存器值
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
这两个函数同上,不同的是读取的是输出寄存器的值。
GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin):将指定IO口置位,参数:GPIO端口标号,端口号,
GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin):将指定IO口复位,参数:GPIO端口标号,端口号
GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVa):在指定IO口上赋值,参数:GPIO端口标号,端口号,BitAction 结构体变量
typedef enum
{ Bit_RESET = 0,
Bit_SET
}BitAction;
GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal):在指定一组IO口上一次性赋值,参数,GPIO端口标号,无符号16位二进制数,即unsigned char型变量
程序代码分析:(代码出自FIRE)
控制IO电平的2种方法,库函数法、直接操作寄存器法。
直接操作寄存器法:宏定义
#define digitalHi(p,i) {p->BSRR=i;} //P为GPIO端口标号
#define digitalLo(p,i) {p->BRR=i;} //
#define digitalToggle(p,i) {p->ODR ^=i;} //
库函数法:宏定义
#define LED1(a) if (a) \
GPIO_SetBits(GPIOB,GPIO_Pin_0);\
else \
GPIO_ResetBits(GPIOB,GPIO_Pin_0)
#define LED2(a) if (a) \
GPIO_SetBits(GPIOC,GPIO_Pin_4);\
else \
GPIO_ResetBits(GPIOC,GPIO_Pin_4)
#define LED3(a) if (a) \
GPIO_SetBits(GPIOC,GPIO_Pin_3);\
else \
GPIO_ResetBits(GPIOC,GPIO_Pin_3)
宏定义可当做内联函数使用,在main.c中可以直接调用
注意:配置寄存器代码如下:
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOC, &GPIO_InitStructure);
1、先定义结构体名
2、开启时钟调用RCC_APB2PeriphClockCmd函数
3、配置结构体内部变量
4、调用GPIO_Init函数
小总结:
1、操作IO口是单片机的第一课,STM32为32位单片机,寄存器为32位,IO口一共有5组,每组16个,每个IO可独立编程。
2、新建工程的时候,要先写对应的.c文件和.h文件,main.c直接调用已定义的函数
3、宏定义可直接定义函数
4、Stm32函数库学习时需要不断的查找对应的函数宏定义和变量宏定义,需要追踪到寄存器级别为止。简单函数需要掌握其如何实现。