7 Segment Display STM32 – Complete Guide (GPIO + Code)

Overview

What You Will Learn

  • How to drive a 7 segment display from an STM32 microcontroller
  • How to use GPIO output pins and the Output Data Register (ODR)
  • How to map display segments to STM32 pins
  • How to configure the project in STM32CubeIDE

Prerequisites

Basic familiarity with STM32CubeIDE, embedded C, GPIO concepts, and working with a simple breadboarded hardware setup is recommended.

Materials List

Hardware

Display Anatomy

7 Segment LED

Components

This project uses an STM32F103C8TX board, a common cathode 7 segment display, jumper wires, resistors, a breadboard, and an ST-Link programmer.

Schematic

Schematic

Pinouts

STM32F103C8Tx Blue Pill Pin Diagram

Header 1 Pins

In the diagram above, Header #1 pins are on the right starting from the bottom working upwards. The pin numbers DO NOT match the color coded pin assignment diagram, so count the pins in the below chart upwards from the bottom right side.

Header 1 Pin for STM32F103C8T6

Header 2 Pins

In the diagram above, Header #2 pins start at the bottom left and working upwards. The pin numbers DO NOT match the color coded pin assignment diagram above, so count the pins in the below chart upwards from the bottom left side.

Header 2 Pin for STM32F103C8T6

CubeIDE Configuration



Project Setup

Create a new STM32CubeIDE project for the STM32F103C8TX, configure the required GPIO pins on Port A as outputs, generate the code, and then add the display control logic to main.c.

Code Walkthrough

main.c

C
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

void delay(uint16_t delay) {
	HAL_Delay(delay);
}

void displayEachSeg() {
		      //      gfedcba
	GPIOA->ODR = 0b00000000;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00000001;                              //Write to port-A-seg-a
	delay(1000);
	GPIOA->ODR = 0b00000010;                              //Write to port-A-seg-b
	delay(1000);
	GPIOA->ODR = 0b00000100;                              //Write to port-A-seg-c
	delay(1000);
	GPIOA->ODR = 0b00001000;                              //Write to port-A-seg-d
	delay(1000);
	GPIOA->ODR = 0b00010000;                              //Write to port-A-seg-e
	delay(1000);
	GPIOA->ODR = 0b00100000;                              //Write to port-A-seg-f
	delay(1000);
	GPIOA->ODR = 0b01000000;                              //Write to port-A-seg-g
	delay(1000);
	GPIOA->ODR = 0b00000000;                              //Write to port-A-seg-none
	delay(1000);
}

void displayAllSeg() {
		      //      gfedcba
	GPIOA->ODR = 0b00000001;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00000011;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00000111;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00001111;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00011111;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00111111;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b01111111;                              //Write to port-A
	delay(1000);
	GPIOA->ODR = 0b00000000;                              //Write to port-A
	delay(1000);
}

void displayZero() {
		      //      gfedcba
	GPIOA->ODR = 0b00111111;                              //Write to port-A
	delay(1000);
}
void displayOne() {
		      //      gfedcba
	GPIOA->ODR = 0b00000110;                              //Write to port-A
	delay(1000);
}

void displayTwo() {
		      //      gfedcba
	GPIOA->ODR = 0b01011011;                              //Write to port-A
	delay(1000);
}

void displayThree() {
		      //      gfedcba
	GPIOA->ODR = 0b01001111;                              //Write to port-A
	delay(1000);
}

void displayFour() {
		      //      gfedcba
	GPIOA->ODR = 0b01100110;                              //Write to port-A
	delay(1000);
}

void displayFive() {
		      //      gfedcba
	GPIOA->ODR = 0b01101101;                              //Write to port-A
	delay(1000);
}

void displaySix() {
		      //      gfedcba
	GPIOA->ODR = 0b01111101;                              //Write to port-A
	delay(1000);
}

void displaySeven() {
		      //      gfedcba
	GPIOA->ODR = 0b00000111;                              //Write to port-A
	delay(1000);
}

void displayEight() {
		      //      gfedcba
	GPIOA->ODR = 0b01111111;                              //Write to port-A
	delay(1000);
}

void displayNine() {
		      //      gfedcba
	GPIOA->ODR = 0b01101111;                              //Write to port-A
	delay(1000);
}

void displayA() {
		      //      gfedcba
	GPIOA->ODR = 0b01110111;                              //Write to port-A
	delay(1000);
}

void displayB() {
		      //      gfedcba
	GPIOA->ODR = 0b01111100;                              //Write to port-A
	delay(1000);
}

void displayC() {
		      //      gfedcba
	GPIOA->ODR = 0b00111001;                              //Write to port-A
	delay(1000);
}

void displayD() {
		      //      gfedcba
	GPIOA->ODR = 0b01011110;                              //Write to port-A
	delay(1000);
}

void displayE() {
		      //      gfedcba
	GPIOA->ODR = 0b01111001;                              //Write to port-A
	delay(1000);
}

void displayF() {
		      //      gfedcba
	GPIOA->ODR = 0b01110001;                              //Write to port-A
	delay(1000);
}

/* 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();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	  displayEachSeg();
	  displayAllSeg();
    displayZero();
	  displayOne();
	  displayTwo();
	  displayThree();
	  displayFour();
	  displayFive();
	  displaySix();
	  displaySeven();
	  displayEight();
	  displayNine();
	  displayA();
	  displayB();
	  displayC();
	  displayD();
	  displayE();
	  displayF();
  }
  /* USER CODE END 3 */
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA0 PA1 PA2 PA3
                           PA4 PA5 PA6 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  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);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}