STM32外设之GPIO&LED指示灯模块程序设计

文章目录

  • 一、STM32外设之GPIO
  • 二、CT117E-M4的LED电路原理
  • 三、LED指示灯模板程序设计
  • 一、STM32外设之GPIO

    1.GPIO的8种工作模式:

    模式配置 模式寄存器 输出类型寄存器 输出速度寄存器 上/下拉寄存器
    输入浮空 00 不使用 不使用 00
    输入上拉 00 不使用 不使用 01
    输入下拉 00 不使用 不使用 10
    模拟功能 11 不使用 不使用 00
    开漏通用输出 01 1 00-速度2MHz 00-无上下拉
    推挽通用输出 01 0 01-速度25MHz 01-上拉
    复用开漏输出 10 1 10-速度-50MHz 10-下拉
    复用推挽输出 01 1 11-速度100MHz 11-保留

    注:输出模式中,输出速度寄存器和上/下拉寄存器的四种形式为四个输出模式共用。

    1.1、浮空输入模式:
    a.CPU通过I/O端口→保护二极管→TTL肖特基触发器→输入数据寄存器→CPU读取到I/O端口的高低电平。(保护二极管:因为I/O端口信号不确定,所以需要添加二极管保护电路)
    b.浮空模式下,I/O端口的电平信号直接输入到输入数据寄存器中,所以I/O端口电平是不确定的,完全由外部决定。

    1.2、输入上拉模式:

    a.作用:把不确定的信号通过电阻连接到高电平,默认情况下输入引脚数据为1(高电平)。
    b.上拉输入与浮空输入的主要区别在于上拉电阻的闭合,且上拉电阻大小约为30-50KΩ。

    1.3、输入下拉模式:

    a.作用:把不确定的信号通过电阻连接到低电平,默认情况下输入引脚数据为0(低电平)。
    b.下拉输入与浮空输入的主要区别在于下拉电阻的闭合。

    1.4、高组态模拟输入模式:
    a.模拟输入模式中,上拉、下拉电阻和TTL施密特触发器均处于截止状态,导致CPU无法接收到输入数据寄存器传来的I/O端口的电平变化。
    b.I/O端口的模拟信号直接模拟输入到片上外设模块。

    1.5、开漏通用输出模式:

    a.若输出控制电路接收到1(高电平),则N-MOS管截止,I/O端口处的电平仅仅取决于外部上拉或下拉。
    b.若输出控制电路接收到0(低电平),则N-MOS管导通,I/O端口处的电平将被N-MOS管拉低。
    c.在输出状态下,I/O端口处电平还可以用输入电路(I/O端口→输入数据寄存器→CPU读取)来读取。

    1.6、推挽通用输出模式:
    a.若输出控制电路接收到1(高电平),则P-MOS导通,N-MOS截止,I/O端口处输出高电平。
    b.若输出控制电路接收到0(低电平),则P-MOS截止,N-MOS导通,I/O断口处输出低电平。
    c.在输出状态下,I/O端口处电平还可以用输入电路(I/O端口→输入数据寄存器→CPU读取)来读取。
    1.7、推挽复用输出:
    推挽复用输出与推挽通用输出相似,区别在于输出的高低电平的来源,不是让CPU向置位/复位寄存器写1/0然后将其映射到输出数据寄存器中,而是利用片上外设模块的复用功能输出来决定的。
    1.8、开漏复用输出:

    开漏复用输出与开漏通用输出相似,区别在于输出的高低电平的来源,不是让CPU向置位/复位寄存器写1/0然后将其映射到输出数据寄存器中,而是利用片上外设模块的复用功能输出来决定的。

    二、CT117E-M4的LED电路原理

    原理图:

    锁存器:LED和LCD有共用的引脚,为防止使用时出现混乱,往往会在LED电路中加一个573锁存器。

    输出端:D0-D7;输入端Q0-Q7
    LE高电平时信号可以从D传到Q,低电平时阻断。

    三、LED指示灯模板程序设计

    1.main.c(main.c文件是STM32项目的心脏,主要负责系统的初始化、时钟配置、外设设置以及主程序的执行逻辑。)

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>&copy; Copyright (c) 2024 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "led\bsp_led.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
    //  MX_GPIO_Init();
      LED_Init();
      /* USER CODE BEGIN 2 */
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    	LED_Disp(0x01);
    	HAL_Delay(500);
    	LED_Disp(0x02);
    	HAL_Delay(500);
    	LED_Disp(0x04);
    	HAL_Delay(500);
    	LED_Disp(0x08);
    	HAL_Delay(500);
    	LED_Disp(0x10);
    	HAL_Delay(500);
    	LED_Disp(0x20);
    	HAL_Delay(500);
    	LED_Disp(0x40);
    	HAL_Delay(500);
    	LED_Disp(0x80);
    	HAL_Delay(500);
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
      /** Configure the main internal regulator output voltage
      */
      HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
      RCC_OscInitStruct.PLL.PLLN = 20;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
      RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
      RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      __disable_irq();
      while (1)
      {
      }
      /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    
    
    HAL_Init():初始化HAL库,作为STM32硬件抽象层库,一般用于简化硬件访问。
    SystemClock_Config():配置系统时钟。它通常涉及到外部高速时钟(HSE)、PLL(相位锁定环)和其他时钟分频器等等,以确保系统以所需的频率运行。
    LED_Init():初始化LED外设。这个函数在bsp_led.h头文件对应的源文件中定义,用来配置控制LED的GPIO端口。
    Error_Handler():在配置时钟失败时调用。它通常会使系统进入一个死循环,并禁止中断运行来避免更麻烦的问题。
    assert_failed():在启用USE_FULL_ASSERT宏时,如果assert_param宏检测到参数错误,则调用此函数。
    在while (1)循环中,程序通过调用LED_Disp()函数并以位寻址方式控制亮不同的LED。每次点亮LED指示灯后,程序通过HAL_Delay(500)函数暂停500毫秒,然后点亮下一个LED。
    

    2.bsp_led.c(用于STM32微控制器的LED控制程序,是在HAL库的基础上编写的。)

    #include "led\bsp_led.h"
    
    void LED_Init(void)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOF_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                              |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
    
      /*Configure GPIO pins : PC13 PC14 PC15 PC8
                               PC9 PC10 PC11 PC12 */
      GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                              |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
      /*Configure GPIO pin : PD2 */
      GPIO_InitStruct.Pin = GPIO_PIN_2;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    
    }
    
    void LED_Disp(unsigned char ucled)
    {
    	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,GPIO_PIN_SET);
    	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
    	
    	HAL_GPIO_WritePin(GPIOC,ucled,GPIO_PIN_RESET);
    	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
    }
    
    

    2.1、LED初始化 (LED_Init 函数):
    a.使能GPIOC、GPIOD和GPIOF端口的时钟。
    b.将GPIOC上的引脚(PIN_13, PIN_14, PIN_15, PIN_8, PIN_9, PIN_10, PIN_11, PIN_12)和GPIOD上的PIN_2配置为推挽输出(Push-Pull Output)模式,并且不启用上拉和下拉电阻,输出速度设置为低速。
    c.将所有配置的GPIOC引脚初始化为高电平(GPIO_PIN_SET),GPIOD引脚PIN_2初始化为低电平(PIO_PIN_RESET)。
    2.2、LED显示控制 (LED_Disp 函数):
    a.将所有GPIOC上的LED引脚设置为高电平(GPIO_PIN_SET),并且也将GPIOD的PIN_2设置为高电平(GPIO_PIN_SET)。紧接着又将其设置为低电平。(GPIO_PIN_RESET)
    b.通过ucled确定需要调节的LED指示灯(ucled<<8的作用是将引脚对应的二进制值左移8位)。

    3.bsp_led.h(该文件是一个头文件,它声明了两个函数:LED_Init和LED_Disp。)

    #include "main.h"
    
    void LED_Init(void);
    void LED_Disp(unsigned char ucled);
    
    

    作者:小唐可不唐

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32外设之GPIO&LED指示灯模块程序设计

    发表回复