7-segment display and STM32 using ChibiOS

7-segment display and STM32 using ChibiOS

A compact display driver: the MAX7219

We have already introduced MAX7219 in STM32, ChibiOS and a 8×8 LED Matrix, so we are going to jump directly to code section. For convenience we just report link to documentation:

MAX7219 Datasheet

Note that even if pins are arranged in a different way, pin-out remains the same of the 8×8 LED matrix.

Proposed demo

In this demo we are going to use Code-B decode to write with ease some number on our 8 digit 7-segment display.

Demo explained

In the demo shown in the video above we set up MAX7219 as normal operation mode, Code-B decode mode for each digit, scanning the whole display with the maximum display intensity. After that we use chVTGetSystemTime() to get system time and with simple operation we compute milliseconds, seconds, minutes and hours since ChibiOS is alive.

    PLAY Embedded demos - Copyright (C) 2014-2016 Rocco Marco Guglielmi

    This file is part of PLAY Embedded demos.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at


    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

    Tested under ChibiOS/RT 3.0.1, Project version 1.0
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "max7219.h"

static systime_t time, hours, minutes, seconds, millisec;
static BaseSequentialStream* chp = (BaseSequentialStream*) &SD2;
/* Numeric display related code.                                             */

#define DOT                                  1<<7

/* SPI related code.                                                         */

#define  GPIOB_SPID1_CS                 6
#define  GPIOA_SPID1_SCK                5
#define  GPIOA_SPID1_MISO               6
#define  GPIOA_SPID1_MOSI               7

static const SPIConfig spicfg = {
  GPIOB,                                          /*   port of CS  */
  GPIOB_SPID1_CS,                                 /*   pin of CS   */
  SPI_CR1_BR | SPI_CR1_DFF                        /*   CR1 register */

/* Generic code.                                                             */

 * Application entry point.
int main(void) {

   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.

   * SPID1 I/O pins setup.(It bypasses board.h configurations)
                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   /* New SCK */
                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   /* New MISO*/
                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   /* New MOSI*/
  palSetPadMode(GPIOB, GPIOB_SPID1_CS,
  sdStart(&SD2, NULL);
  spiStart(&SPID1, &spicfg);
  max7219WriteRegister(&SPID1, MAX7219_AD_DISPLAY_TEST, FALSE);
  max7219WriteRegister(&SPID1, MAX7219_AD_SHUTDOWN, MAX7219_OM_Normal);
  max7219WriteRegister(&SPID1, MAX7219_AD_SCAN_LIMIT, MAX7219_SL_7);
  max7219WriteRegister(&SPID1, MAX7219_AD_DECODE_MODE,
  max7219WriteRegister(&SPID1, MAX7219_AD_INTENSITY,
  while (TRUE) {

    time = chVTGetSystemTime();
    hours = time / 36000000;
    minutes = (time / 600000) % 60;
    seconds = (time / 10000) % 60;
    millisec = (time / 10) % 1000;
    chprintf(chp, "%d:%2d:%2d.%3d\n\r", hours, minutes, seconds, millisec);
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_7, (millisec % 10));
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_6, ((millisec / 10) % 10));
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_5, (millisec / 100));
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_4, (seconds % 10) | DOT);
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_3, (seconds / 10));
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_2, (minutes % 10) | DOT);
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_1, (minutes / 10));
    max7219WriteRegister(&SPID1, MAX7219_AD_DIGIT_0, hours | DOT);

Project download

The attached demo has been tested under ChibiOS 20.3.x.


Be the first to reply at 7-segment display and STM32 using ChibiOS

Leave a Reply