流水灯(标准库函数)
知识点GPIO 寄存器基地址外设输入模式(上拉、下拉、浮空、模拟)输出模式(推挽/开漏)复用功能(推挽/开漏)改变GPIO引脚状态GPIO_Init()函数函数讲解函数使用例子库函数理解实例操作知识点
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;typedef struct{vu32 EVCR;vu32 MAPR;vu32 EXTICR[4];} AFIO_TypeDef;
基地址
#define PERIPH_BASE ((u32)0x40000000)#define APB1PERIPH_BASE PERIPH_BASE#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)#define AFIO_BASE (APB2PERIPH_BASE + 0x0000)#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
外设
#define TIM2((TIM_TypeDef *) TIM2_BASE)#define TIM3((TIM_TypeDef *) TIM3_BASE)#define TIM4((TIM_TypeDef *) TIM4_BASE)#define TIM5((TIM_TypeDef *) TIM5_BASE)#define TIM6((TIM_TypeDef *) TIM6_BASE)#define TIM7((TIM_TypeDef *) TIM7_BASE)#define TIM12((TIM_TypeDef *) TIM12_BASE)#define TIM13((TIM_TypeDef *) TIM13_BASE)#define TIM14((TIM_TypeDef *) TIM14_BASE)#define RTC ((RTC_TypeDef *) RTC_BASE)#define WWDG((WWDG_TypeDef *) WWDG_BASE)#define IWDG((IWDG_TypeDef *) IWDG_BASE)#define SPI2((SPI_TypeDef *) SPI2_BASE)#define SPI3((SPI_TypeDef *) SPI3_BASE)#define USART2 ((USART_TypeDef *) USART2_BASE)#define USART3 ((USART_TypeDef *) USART3_BASE)#define UART4((USART_TypeDef *) UART4_BASE)#define UART5((USART_TypeDef *) UART5_BASE)#define I2C1((I2C_TypeDef *) I2C1_BASE)#define I2C2((I2C_TypeDef *) I2C2_BASE)#define CAN1((CAN_TypeDef *) CAN1_BASE)#define CAN2((CAN_TypeDef *) CAN2_BASE)#define BKP ((BKP_TypeDef *) BKP_BASE)#define PWR ((PWR_TypeDef *) PWR_BASE)#define DAC ((DAC_TypeDef *) DAC_BASE)#define CEC ((CEC_TypeDef *) CEC_BASE)#define AFIO((AFIO_TypeDef *) AFIO_BASE)#define EXTI((EXTI_TypeDef *) EXTI_BASE)#define GPIOA((GPIO_TypeDef *) GPIOA_BASE)#define GPIOB((GPIO_TypeDef *) GPIOB_BASE)#define GPIOC((GPIO_TypeDef *) GPIOC_BASE)#define GPIOD((GPIO_TypeDef *) GPIOD_BASE)#define GPIOE((GPIO_TypeDef *) GPIOE_BASE)#define GPIOF((GPIO_TypeDef *) GPIOF_BASE)#define GPIOG((GPIO_TypeDef *) GPIOG_BASE)#define ADC1((ADC_TypeDef *) ADC1_BASE)#define ADC2((ADC_TypeDef *) ADC2_BASE)#define TIM1((TIM_TypeDef *) TIM1_BASE)#define SPI1((SPI_TypeDef *) SPI1_BASE)#define TIM8((TIM_TypeDef *) TIM8_BASE)#define USART1 ((USART_TypeDef *) USART1_BASE)#define ADC3((ADC_TypeDef *) ADC3_BASE)#define TIM15((TIM_TypeDef *) TIM15_BASE)#define TIM16((TIM_TypeDef *) TIM16_BASE)#define TIM17((TIM_TypeDef *) TIM17_BASE)#define TIM9((TIM_TypeDef *) TIM9_BASE)#define TIM10((TIM_TypeDef *) TIM10_BASE)#define TIM11((TIM_TypeDef *) TIM11_BASE)#define SDIO((SDIO_TypeDef *) SDIO_BASE)#define DMA1((DMA_TypeDef *) DMA1_BASE)#define DMA2((DMA_TypeDef *) DMA2_BASE)#define DMA1_Channel1 ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE)#define DMA1_Channel2 ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE)#define DMA1_Channel3 ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE)#define DMA1_Channel4 ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE)#define DMA1_Channel5 ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE)#define DMA1_Channel6 ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE)#define DMA1_Channel7 ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE)#define DMA2_Channel1 ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE)#define DMA2_Channel2 ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE)#define DMA2_Channel3 ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE)#define DMA2_Channel4 ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE)#define DMA2_Channel5 ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE)#define RCC ((RCC_TypeDef *) RCC_BASE)#define CRC ((CRC_TypeDef *) CRC_BASE)#define FLASH((FLASH_TypeDef *) FLASH_R_BASE)#define OB ((OB_TypeDef *) OB_BASE) #define ETH ((ETH_TypeDef *) ETH_BASE)#define FSMC_Bank1((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)#define FSMC_Bank2((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)#define FSMC_Bank3((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)#define FSMC_Bank4((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE)
这里就已经把GPIOx的类型变为结构体 GPIO_TypeDef,地址变为GPIOx_BASE;
比如使用时可以 用GPIOC->ODR这样。
输入模式(上拉、下拉、浮空、模拟)
在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器 GPIOx_IDR读取 I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于 ADC 采集。
输出模式(推挽/开漏)
在输出模式中,推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR可控制 I/O 输出高低电平。开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O输出高阻态或低电平。输出速度可配置,有2MHz\10MHz\50MHz的选项。此处的输出速度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR可读取 I/O 的实际状态。
复用功能(推挽/开漏)
复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。
通过对 GPIO寄存器写入不同的参数,就可以改变 GPIO的工作模式,再强调一下,要了解具体寄存器时一定要查阅《STM32F10X-中文参考手册》中对应外设的寄存器说明。
在 GPIO外设中,控制端口高低控制寄存器 CRH和 CRL可以配置每个 GPIO 的工作模式和工作的速度,每 4个位控制一个 IO,CRH控制端口的高八位,CRL控制端口的低 8位,具体的看 CRH和 CRL的寄存器描述。
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;
typedef enum{GPIO_Speed_10MHz = 1,GPIO_Speed_2MHz, GPIO_Speed_50MHz}GPIOSpeed_TypeDef;
改变GPIO引脚状态
1、高16位和低16位,只能以16位形式操作。 2、高16位用于置 0,低16位用于置 1。(高16位用于置0,低16位用于1置1,相应位设1才有效) 3、各个位对 0 操作是免疫的
比如控制PC13:
输出高电平 1<<13
输出低电平 1<<(13+16)
只有低16位有效,在相应位置写 1 时,可以输出一个低电平。
通过这两个寄存器,我们就可以控制一个GPIO引脚输出高低电平,最简单的可以使用BSRR输出高电平,用BRR输出低电平。
GPIOC ->BSRR |=1<<13;
用函数控制引脚输出高电平
用函数控制输出低电平
GPIO_Init()函数
函数讲解
作用:根据 GPIO_InitStruct 中指定的参数初始化外设 GPIOx 寄存器。
GPIO_Init()函数就是配置引脚的四个位,再将四个位写入到对应引脚的寄存器。
库函数中的此函数代码如下图。
函数分析:
确定currentmode 的值。判断输入还是输出,如果是输出,添加速度值。配置低八位。配置高八位。
函数使用例子
比如设定:PA2推挽输出,输出速度50NHz;
用库函数定义的代码和实际赋值如下图:
0b:32位
库函数理解
库函数是控制寄存器操作的语句被封装成函数的函数集合,需要执行相应动作的时候只需要调用函数(并填入参数)即可。
实例操作
工 程在这里分为三个程序。main.c ;LED.h ;LED.c
思路:
一:打开引脚对应的时钟。
二:配置输出,确定输出模式
三:输出高电平或者低电平
LED.h
#ifndef __LED_H//此处是表示当我们没有定义LED这个名字时,一下这个程序才被使用#define __LED_H#include "stm32f10x.h"//头文件#define LED_G_GPIO_PINGPIO_Pin_0//定义LED灯G的管脚#define LED_B_GPIO_PINGPIO_Pin_1//定义LED灯B的管脚#define LED_R_GPIO_PINGPIO_Pin_5//定义LED灯R的管脚#define LED_GPIO_PORT GPIOB#define LED_GPIO_CLK RCC_APB2Periph_GPIOB#define ON 1#define OFF 0// \表示换行符//ResetBits可用于输出低电平//SetBits 可用于输出高电平#define LED_G(a) if(a) \GPIO_ResetBits(LED_GPIO_PORT, LED_G_GPIO_PIN); \else GPIO_SetBits(LED_GPIO_PORT, LED_G_GPIO_PIN);#define LED_B(a) if(a) \GPIO_ResetBits(LED_GPIO_PORT, LED_B_GPIO_PIN); \else GPIO_SetBits(LED_GPIO_PORT, LED_B_GPIO_PIN);#define LED_R(a) if(a)\GPIO_ResetBits(LED_GPIO_PORT, LED_R_GPIO_PIN); \else GPIO_SetBits(LED_GPIO_PORT, LED_R_GPIO_PIN);void LED_GPIO_Config(void);#endif /* __LED_H */
LED.c
#include "LED.h"void LED_GPIO_Config(void){/*定义3个GPIO_InitTypeDef 类型的结构体*/GPIO_InitTypeDef GPIO_InitStruct1;GPIO_InitTypeDef GPIO_InitStruct2;GPIO_InitTypeDef GPIO_InitStruct3;/*开启 LED 相关的 GPIO 外设时钟*/RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);GPIO_InitStruct1.GPIO_Pin = LED_G_GPIO_PIN;//赋值为相应管脚的地址GPIO_InitStruct2.GPIO_Pin = LED_B_GPIO_PIN;GPIO_InitStruct3.GPIO_Pin = LED_R_GPIO_PIN;GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_Out_PP;//其实就是赋值为0x10;GPIO_InitStruct1.GPIO_Speed = GPIO_Speed_50MHz;//赋值为3GPIO_InitStruct2.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct2.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct3.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct3.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct1); GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct2); GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct3); }
main.c
#include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h>#include "LED.h"void Delay( uint32_t count ){for(; count!=0; count--);}int main(void){LED_GPIO_Config();while(1){LED_G(OFF);LED_B(OFF);LED_R(OFF); Delay(0xFFFFF); LED_G(ON);Delay(0xFFFFF);LED_G(OFF);Delay(0xFFFFF); LED_B(ON);Delay(0xFFFFF);LED_B(OFF);Delay(0xFFFFF); LED_R(ON);Delay(0xFFFFF);LED_R(OFF); }}
仿真图
如果觉得《STM32(三)-------流水灯(标准库函数)》对你有帮助,请点赞、收藏,并留下你的观点哦!