用户工具

站点工具


arm驱动三色led
银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-07-03 gingko 初次建立

实验一:GPIO输出实验——ARM驱动三色LED

一、 实验目的与意义

  1. 了解STM32 GPIO结构。
  2. 了解STM32 GPIO 特征。
  3. 了解三色LED特征和应用领域。
  4. 掌握STM32 HAL库中GPIO属性的配置方法。
  5. 掌握KEILMDK 集成开发环境使用方法。

二、 实验设备及平台

  1. iCore4 双核心板点击购买
  2. JLINK(或相同功能)仿真器点击购买
  3. Micro USB线缆。
  4. Keil MDK 开发平台。
  5. STM32CubeMX开发平台。
  6. 装有WIN XP(及更高版本)系统的计算机。

三、 实验原理

1、STM32F7 IO简介

  • STM32F7每组通用I/O端口包括4个32位配置寄存器(MODER、OTYPER、OSPEEDR和PUPDR)、2个32位数据寄存器(IDR和ODR)、1个32位置位/复位寄存器(BSRR)、1个32位锁定寄存器(LCKR)和2个32位复用功能选择寄存器(AFRH和AFRL)等。这样,STM32F7每组IO有10个32位寄存器控制,其中常用的有4个配置寄存器+2个数据寄存器+2个复用功能选择寄存器,共8个。

2、GPIO输入输出模式

GPIO可以配置成以下8种工作模式:

  1. 浮空输入:此端口在默认情况下什么都不接,呈高阻态,这种设置在数据传输时用的比较多。
  2. 上拉输入:上拉输入模式与浮空输入模式相比,仅仅是在数据通道上部,接入了一个上拉电阻,这个上拉电阻的阻值介于30K~50K欧姆,CPU可以随时在输入数据寄存器的另一端,读出I/O端口的电平状态。这种模式的好处在于我们什么都不输入时,由于内部上拉电阻的原因,处理器会觉得我们输入了高电平,这就避免了不确定的输入。该端口在默认情况下输入为高电平。
  3. 下拉输入:下拉输入模式与浮空输入模式相比,仅仅是在数据通道上部,接入了一个下拉电阻。与上拉输入模式类似,这种模式的好处在于外部没有输入时,由于内部下拉电阻的原因,我们的处理器会觉得我们输入了低电平。
  4. 模拟功能:STM32的模拟输入通道的配置很简单,信号从I/O端口直接进入ADC模块。此时,所有的上拉、下拉电阻和施密特触发器,均处于断开状态,因此输入数据寄存器将不能反映端口上的电平状态,也就是说,模拟输入配置下,信号不经过输入数据寄存器,CPU不能在输入数据寄存器上读到有效的数据。该输入模式,使我们可以获得外部的模拟信号。
  5. 开漏输出:开漏输出不可以直接输出高电平,开漏输出的输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。
  6. 推挽输出:推挽输出可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源决定。
  7. 开漏复用输出:GPIO的基本功能是普通的I/O,而STM32有自己的各个功能模块,这些内置外设的外部引脚是与标准GPIO复用的,当作为这些模块的功能引脚时就叫复用。开漏复用输出功能模式与开漏输出模式相比,不同的是输出控制电路的输入,是和片上外设的输出信号相连即与复用功能的输出端相连,此时,输出数据寄存器在输出通道被断开。
  8. 推挽复用输出:推挽复用输出功能模式与推挽输出模式相比,不同的是输出控制电路的输入,是和片上外设的输出信号相连,即与复用功能的输出端相连,而输出数据寄存器在输出通道被断开。

3、GPIO口配置

  • 1 作为普通GPIO输入:
    • 根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时不要使能该引脚对应的所有复用功能模块。
  • 2 作为普通GPIO输出:
    • 根据需要配置该引脚为推挽输出或开漏输出,同时不要使能该引脚对应的所有复用功能模块。
  • 3 作为普通模拟输入:
    • 配置该引脚为模拟输入模式,同时不要使能该引脚对应的所有复用功能模块。
  • 4 作为内置外设的输入:
    • 根据需要配置该引脚为浮空输入、带弱上拉输入或带弱下拉输入,同时使能该引脚对应的某个复用功能模块。
  • 5 作为内置外设的输出:
    • 根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。
  • 本实验通过STM32的三个GPIO驱动一个三色LED,引脚PB2接红色LED(ARM_LEDR),引脚PA9接蓝色LED(ARM_LEDB),引脚PA10接绿色LED(ARM_LEDG), GPIO为推挽输出模式,采用灌电流方式与LED连接,通过拉高拉低GPIO电平,从而控制LED亮灭。原理图如下图所示。

四、 实验程序

1、主函数

int main(void)
{
  /* MCU配置*/
  /* 重置所有外围设备,初始化Flash接口和Systick */
  HAL_Init();
  /* 配置系统时钟 */
  SystemClock_Config();
  /* 初始化所有已配置的外围设备 */
  MX_GPIO_Init();
  /* 无限循环 */
  while (1)
  {
        //三色LED循环闪烁
        LED_RED_ON;
        LED_BLUE_OFF;
        LED_GREEN_OFF;
        HAL_Delay(500);
        LED_RED_OFF;
        LED_BLUE_ON;
        LED_GREEN_OFF;
        HAL_Delay(500);
        LED_RED_OFF;
        LED_BLUE_OFF;
        LED_GREEN_ON;
        HAL_Delay(500);
  }
}

2、GPIO初始化

void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  /* GPIO端口时钟使能 */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  /*配置GPIO引脚输出电平 */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
  /*配置GPIO引脚输出电平*/
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_SET);
 
  /*配置GPIO引脚:PB2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /*配置GPIO引脚:PA9 PA10 */
  GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
 
void HAL_GPIO_Init(GPIO_TypeDef*GPIOx, GPIO_InitTypeDef *GPIO_Init)
  • 这个函数两个参数,第一个参数是用来指定需要初始化的GPIO对应的GPIO组,取值范围为GPIOA~GPIOK。第二个参数为初始化参数结构体指针,结构体类型为GPIO_InitTypeDef。
typedef struct 
{  
  uint32_t Pin;         // 配置IO端口
  uint32_t Mode;        // 配置IO模式
  uint32_t Pull;        // 配置IO上下拉
  uint32_t Speed;       // 配置IO速度等级
  uint32_t Alternate;  // 要连接到所选引脚的外围设备
}GPIO_InitTypeDef;

3、GPIO写入电平函数

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{   /* 检查参数 */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));
  if(PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRR = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << 16;
  }
}
  • 实验中通过调用HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)函数来实现对GPIO引脚高低电平的写入。

4、宏定义引脚

#define LED_RED_ON  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_RESET)
#define LED_RED_OFF HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2,GPIO_PIN_SET)
 
#define LED_BLUE_ON  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_RESET)
#define LED_BLUE_OFF HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_SET)
 
#define LED_GREEN_ON HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10,GPIO_PIN_RESET)
#define LED_GREEN_OFF HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10,GPIO_PIN_SET)
  • 定义好上面的宏定义之后,就可以直接通过直接操作宏定义来控制三色LED的状态。

五、 实验步骤

  1. 把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连);
  2. 把iCore4通过Micro USB线与计算机相连,为iCore4供电;
  3. 打开Keil MDK 开发环境,并打开本实验工程;
  4. 烧写程序到iCore4上;
  5. 也可以进入Debug 模式,单步运行或设置断电运行观察三色LED状态。

六、 实验现象

  • 该实验实现跑马灯功能,红、绿、蓝三色LED每隔500ms循环点亮。
arm驱动三色led.txt · 最后更改: 2022/03/22 10:16 由 sean