INTRODUCTION: This laboratory activity is about learning how a brain chip (called a Microcontroller, or MCU) communicates with simple external devices. In this lab, we use an STM32 Nucleo development board.
We connect it to three things: First, five buttons arranged like a game controller's d-pad (Up, Down, Left, Right, Center); Second, a multi-colored light bulb; and lastly, a small digital screen on which the word "Hello World" will be displayed.
1. Hardware Set-upThe STM32 RT-Spark development board was connected to a breadboard containing three LEDs (Blue, Green, and Red) and five push-button switches (UP, DOWN, LEFT, RIGHT, and CENTER). Each LED was connected to a GPIO output pin through a current-limiting resistor, while each push button was connected to a GPIO input pin.
GPIO Pin ComponentPA0 Blue LED
PA2 Green LED
PA3 Red LED
PG0 UP Button
PG1 DOWN Button
PG2 CENTER Button
PG5 LEFT Button
PG6 RIGHT Button
The LED pins (PA0, PA2, and PA3) were configured as Output Push-Pull to allow the microcontroller to control their ON and OFF states.
The button pins (PG0, PG1, PG2, PG5, and PG6) were configured as Input Mode to detect button presses from the user.
3. System InitializationAfter powering the STM32 board, the microcontroller initialized all GPIO peripherals. During initialization, all LED output pins were set HIGH, causing the Blue, Green, and Red LEDs to illuminate simultaneously.
Inside the infinite loop (while(1)), the STM32 continuously checked the status of each push button using the HAL_GPIO_ReadPin() function.
The microcontroller repeatedly scanned the input pins and waited for a button press event.
When a specific button was pressed, the STM32 detected a HIGH signal on the corresponding input pin and immediately turned OFF the assigned LED by setting its output pin LOW.
Therefore, the experiment demonstrated the use of GPIO input and output control in an STM32 microcontroller. The LEDs were initially activated, and individual push buttons were used to deactivate specific LEDs. This activity provided practical experience in configuring GPIO pins, reading digital inputs, and controlling output devices using embedded C programming.
Documentation:/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "drv_lcd.h"
/* 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 ---------------------------------------------------------*/
SRAM_HandleTypeDef hsram3;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FSMC_Init(void);
/* USER CODE BEGIN PFP */
void MY_GPIO_Init(void);
void MY_LEDS_Init(void);
uint8_t switch_Up(void);
uint8_t switch_Down(void);
uint8_t switch_Left(void);
uint8_t switch_Right(void);
uint8_t switch_Center(void);
void RGBLED_Config(uint8_t red, uint8_t green, uint8_t blue);
void ToggleLEDS(void);
void print_switches(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t switch_Up()
{
return HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_0) == GPIO_PIN_RESET;
}
uint8_t switch_Down()
{
return HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_1) == GPIO_PIN_RESET;
}
uint8_t switch_Center()
{
return HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_2) == GPIO_PIN_RESET;
}
uint8_t switch_Left()
{
return HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_5) == GPIO_PIN_RESET;
}
uint8_t switch_Right()
{
return HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_6) == GPIO_PIN_RESET;
}
void RGBLED_Config(uint8_t red, uint8_t green, uint8_t blue)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2,
red ? GPIO_PIN_RESET : GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3,
green ? GPIO_PIN_RESET : GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,
blue ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
void ToggleLEDS()
{
RGBLED_Config(
switch_Up(),
switch_Center(),
switch_Down()
);
}
void print_switches()
{
if(switch_Up())
{
lcd_show_string(0, 0, 16, "Button UP Pressed ");
}
else if(switch_Down())
{
lcd_show_string(0, 0, 16, "Button DOWN Pressed ");
}
else if(switch_Left())
{
lcd_show_string(0, 0, 16, "Button LEFT Pressed ");
}
else if(switch_Right())
{
lcd_show_string(0, 0, 16, "Button RIGHT Pressed ");
}
else if(switch_Center())
{
lcd_show_string(0, 0, 16, "Button CENTER Pressed ");
}
else
{
lcd_show_string(0, 0, 16, "No Button Pressed ");
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_FSMC_Init();
/* USER CODE BEGIN 2 */
MY_GPIO_Init();
MY_LEDS_Init();
/* TURN ON LCD BACKLIGHT */
HAL_GPIO_WritePin(LCD_BL_GPIO_Port,
LCD_BL_Pin,
GPIO_PIN_SET);
/* RELEASE LCD RESET */
HAL_GPIO_WritePin(LCD_RST_GPIO_Port,
LCD_RST_Pin,
GPIO_PIN_SET);
HAL_Delay(50);
drv_lcd_hw_init();
HAL_Delay(50);
/* WHITE BACKGROUND */
lcd_clear(0xFFFF);
/* BLACK TEXT */
lcd_set_color(0x0000, 0xFFFF);
lcd_show_string(0, 0, 16, "Hello World!");
/* USER CODE END 2 */
while (1)
{
print_switches();
ToggleLEDS();
HAL_Delay(100);
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType =
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
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_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/* LCD BACKLIGHT */
HAL_GPIO_WritePin(LCD_BL_GPIO_Port,
LCD_BL_Pin,
GPIO_PIN_SET);
/* LEDS OFF */
HAL_GPIO_WritePin(GPIOA,
BLUEL_LED_Pin |
GREEN_LED_Pin |
RED_LED_Pin,
GPIO_PIN_RESET);
/* LCD RESET RELEASED */
HAL_GPIO_WritePin(LCD_RST_GPIO_Port,
LCD_RST_Pin,
GPIO_PIN_SET);
/* LCD BACKLIGHT PIN */
GPIO_InitStruct.Pin = LCD_BL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_BL_GPIO_Port,
&GPIO_InitStruct);
/* LED PINS */
GPIO_InitStruct.Pin =
BLUEL_LED_Pin |
GREEN_LED_Pin |
RED_LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA,
&GPIO_InitStruct);
/* BUTTON PINS */
GPIO_InitStruct.Pin =
UP_Pin |
DOWN_Pin |
CENTE_Pin |
LEFT_Pin |
RIGHT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOG,
&GPIO_InitStruct);
/* LCD RESET PIN */
GPIO_InitStruct.Pin = LCD_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_RST_GPIO_Port,
&GPIO_InitStruct);
}
/* FSMC initialization function */
static void MX_FSMC_Init(void)
{
FSMC_NORSRAM_TimingTypeDef Timing = {0};
hsram3.Instance = FSMC_NORSRAM_DEVICE;
hsram3.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
hsram3.Init.NSBank = FSMC_NORSRAM_BANK3;
hsram3.Init.DataAddressMux =
FSMC_DATA_ADDRESS_MUX_DISABLE;
hsram3.Init.MemoryType =
FSMC_MEMORY_TYPE_SRAM;
hsram3.Init.MemoryDataWidth =
FSMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram3.Init.BurstAccessMode =
FSMC_BURST_ACCESS_MODE_DISABLE;
hsram3.Init.WaitSignalPolarity =
FSMC_WAIT_SIGNAL_POLARITY_LOW;
hsram3.Init.WrapMode =
FSMC_WRAP_MODE_DISABLE;
hsram3.Init.WaitSignalActive =
FSMC_WAIT_TIMING_BEFORE_WS;
hsram3.Init.WriteOperation =
FSMC_WRITE_OPERATION_ENABLE;
hsram3.Init.WaitSignal =
FSMC_WAIT_SIGNAL_DISABLE;
hsram3.Init.ExtendedMode =
FSMC_EXTENDED_MODE_DISABLE;
hsram3.Init.AsynchronousWait =
FSMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram3.Init.WriteBurst =
FSMC_WRITE_BURST_DISABLE;
hsram3.Init.PageSize =
FSMC_PAGE_SIZE_NONE;
Timing.AddressSetupTime = 15;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 255;
Timing.BusTurnAroundDuration = 15;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FSMC_ACCESS_MODE_A;
if (HAL_SRAM_Init(&hsram3,
&Timing,
NULL) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void MY_GPIO_Init(void)
{
}
void MY_LEDS_Init(void)
{
RGBLED_Config(0, 0, 0);
}
/* USER CODE END 4 */
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif










Comments