STM32学习笔记 — 之GPIO端口篇

STM32上电IO口是输入悬浮状态

 

最近刚开始学习STM32,所以从最基本的GPIO开始学起;首先看看STM32datasheet上对GPIO口的简单介绍:

每个GPI/O 端口有两个32 位配置寄存器(GPIOx_CRLGPIOx_CRH),两个32位数据寄存器(GPIOx_IDRGPIOx_ODR),一个32 位置位/复位寄存器(GPIOx_BSRR),一个16 位复位寄存器(GPIOx_BRR)和一个32 位锁定寄存器(GPIOx_LCKR)

   GPIO 端口的每个位可以由软件分别配置成多种模式。每个I/O 端口位可以自由编程,然而I/0 端口寄存器必须按32 位字被访问(允许半字或字节访问)GPIOx_BSRR GPIOx_BRR 寄存器允许对任何GPIO 寄存器的读/改的独访问;这样,在读和改访问之间产生IRQ 会发生危险。

    端口位配置 CNFx[1:0]=xxbMODEx[1:0]=xxb

再看GPIO功能很强大:

1.通用I/O(GPIO):最最基本的功能,可以驱动LED、可以产生PWM、可以驱动蜂鸣器等等;

2.单独的位设置或位清除:方便软体作业,程序简单。端口配置好以后只需GPIO_SetBits(GPIOx, GPIO_Pin_x)就可以实现对GPIOxpinx位为高电平;

3.外部中断/唤醒线:端口必须配置成输入模式时,所有端口都有外部中断能力;

4.复用功能(AF):复用功能的端口兼有IO功能等。复位期间和刚复位后,复用功能未开启,I/O 端口被配置成浮空输入模式(CNFx[1:0]=01bMODEx[1:0]=00b)

5.软件重新映射I/O复用功能:为了使不同器件封装的外设I/O 功能的数量达到最优,可以把一些复用功能重新映射到其他一些脚上。这可以通过软件配置相应的寄存器来完成。这时,复用功能就不再映射到它们的原始引脚上了;

6.GPIO锁定机制:当在一个端口位上执行了所定(LOCK)程序,在下一次复位之前,将不能再更改端口位的配置。

 

GPIO基本设置

GPIOMode_TypeDef GPIO mode定义及偏移地址

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    //推挽复用

 GPIO输入输出速度选择:

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))

做一个GPIO输出的试验

I/O 端口被配置为推挽模式输出时:输出寄存器上的0 激活N-MOS,而输出寄存器上的1 将激活P-MOS

用这段程序实现:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

int main(void)

{

#ifdef DEBUG

  debug();

#endif

 

  /* 设置系统时钟 */

  RCC_Configuration();

   

  /* 嵌套中断设置*/

  NVIC_Configuration();

 

  /* 激活GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

 

  /* Configure PC.04, PC.05, PC.06 and PC.07 as Output push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

 

  while (1)

  {

    /*本试验仅能实现LED1亮、熄功能*/

    GPIO_SetBits(GPIOC, GPIO_Pin_4); //设置PC.04 pin为高电平,点亮LED1

    Delay();

    GPIO_ResetBits(GPIOC, GPIO_Pin_4); //设置PC.04 pin为低电平,熄灭LED1

    Delay();

  }

}

做一个GPIO输入的试验:以EK-STM32FLCDdemo做例子

  这个试验中把GPIOPD.04做为按键输入,当下降沿来临时触发。

LCDdemo中的例程如下:首先配置按键PD.03, PD.04为按键输入接口。

void Button_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

 

  /* Enable GPIOD clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

 

  /* Configure PD.03, PD.04 as output push-pull */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 | GPIO_Pin_4 ;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

}

下面为按键作用是启动外部中断

GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource3);

 

  EXTI_InitStructure.EXTI_Line = EXTI_Line3;            //设定外部中断3

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  //设定中断模式

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设定下降沿触发模式

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

你可能感兴趣的:(STM32)