{"id":2163,"date":"2015-08-10T10:25:14","date_gmt":"2015-08-10T08:25:14","guid":{"rendered":"https:\/\/playembedded.org\/?p=2163"},"modified":"2021-07-29T11:01:49","modified_gmt":"2021-07-29T09:01:49","slug":"7-segment-display-and-stm32-using-chibios","status":"publish","type":"post","link":"https:\/\/playembedded.org\/blog\/7-segment-display-and-stm32-using-chibios\/","title":{"rendered":"7-segment display and STM32 using ChibiOS"},"content":{"rendered":"<h3 id=\"1_A_compact_display_driver_the_MAX7219\" class=\"level_1\">A compact display driver: the MAX7219<\/h3>\n<p>We have already introduced <b>MAX7219<\/b> in <a href=\"https:\/\/playembedded.org\/en\/2015\/08\/02\/stm32-chibios-and-a-8x8-led-matrix\/\" target=\"_blank\" rel=\"noopener noreferrer\">STM32, ChibiOS and a 8&times;8 LED Matrix<\/a>, so we are going to jump directly to code section. For convenience we just report link to documentation:<\/p>\n<p><a href=\"https:\/\/playembedded.org\/wp-content\/uploads\/2016\/04\/Datasheet_MAX7219.pdf\" rel=\"\">MAX7219 Datasheet<\/a><\/p>\n<p>Note that even if pins are arranged in a different way, pin-out remains the same of the 8&times;8 LED matrix.<\/p>\n<h3 id=\"2_Proposed_demo\" class=\"level_1\">Proposed demo<\/h3>\n<p>In this demo we are going to use Code-B decode to write with ease some number on our 8 digit 7-segment display.<\/p>\n<h4 id=\"3_Demo_explained\" class=\"level_2\">Demo explained<\/h4>\n<p>In the demo shown in the video above we set up <b>MAX7219<\/b> as <b>normal operation mode<\/b>, Code-B decode mode for each digit, scanning the whole display with the maximum display intensity. After that we use <b>chVTGetSystemTime()<\/b> to get system time and with simple operation we compute milliseconds, seconds, minutes and hours since ChibiOS is alive.<!--more--><\/p>\n<pre class=\"lang:c decode:true \">\/*\n    PLAY Embedded demos - Copyright (C) 2014-2016 Rocco Marco Guglielmi\n\n    This file is part of PLAY Embedded demos.\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n        http:\/\/www.apache.org\/licenses\/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*\/\n\n\/*\n    Tested under ChibiOS\/RT 3.0.1, Project version 1.0\n *\/\n#include \"ch.h\"\n#include \"hal.h\"\n#include \"chprintf.h\"\n#include \"max7219.h\"\n\nstatic systime_t time, hours, minutes, seconds, millisec;\nstatic BaseSequentialStream* chp = (BaseSequentialStream*) &amp;SD2;\n\/*===========================================================================*\/\n\/* Numeric display related code.                                             *\/\n\/*===========================================================================*\/\n\n#define DOT                                  1&lt;&lt;7\n\n\/*===========================================================================*\/\n\/* SPI related code.                                                         *\/\n\/*===========================================================================*\/\n\n#define  GPIOB_SPID1_CS                 6\n#define  GPIOA_SPID1_SCK                5\n#define  GPIOA_SPID1_MISO               6\n#define  GPIOA_SPID1_MOSI               7\n\nstatic const SPIConfig spicfg = {\n  NULL,\n  GPIOB,                                          \/*   port of CS  *\/\n  GPIOB_SPID1_CS,                                 \/*   pin of CS   *\/\n  SPI_CR1_BR | SPI_CR1_DFF                        \/*   CR1 register *\/\n};\n\n\/*===========================================================================*\/\n\/* Generic code.                                                             *\/\n\/*===========================================================================*\/\n\n\/*\n * Application entry point.\n *\/\nint main(void) {\n\n\n  \/*\n   * System initializations.\n   * - HAL initialization, this also initializes the configured device drivers\n   *   and performs the board-specific initializations.\n   * - Kernel initialization, the main() function becomes a thread and the\n   *   RTOS is active.\n   *\/\n  halInit();\n  chSysInit();\n\n  \/*\n   * SPID1 I\/O pins setup.(It bypasses board.h configurations)\n   *\/\n  palSetPadMode(GPIOA, GPIOA_SPID1_SCK,\n                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   \/* New SCK *\/\n  palSetPadMode(GPIOA, GPIOA_SPID1_MISO,\n                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   \/* New MISO*\/\n  palSetPadMode(GPIOA, GPIOA_SPID1_MOSI,\n                PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGHEST);   \/* New MOSI*\/\n  palSetPadMode(GPIOB, GPIOB_SPID1_CS,\n                PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);\/* New CS  *\/\n  sdStart(&amp;SD2, NULL);\n  spiStart(&amp;SPID1, &amp;spicfg);\n  max7219WriteRegister(&amp;SPID1, MAX7219_AD_DISPLAY_TEST, FALSE);\n  max7219WriteRegister(&amp;SPID1, MAX7219_AD_SHUTDOWN, MAX7219_OM_Normal);\n  max7219WriteRegister(&amp;SPID1, MAX7219_AD_SCAN_LIMIT, MAX7219_SL_7);\n  max7219WriteRegister(&amp;SPID1, MAX7219_AD_DECODE_MODE,\n                       MAX7219_DM_CodeB_7);\n  max7219WriteRegister(&amp;SPID1, MAX7219_AD_INTENSITY,\n                       MAX7219_IM_31_32);\n  while (TRUE) {\n\n    time = chVTGetSystemTime();\n    hours = time \/ 36000000;\n    minutes = (time \/ 600000) % 60;\n    seconds = (time \/ 10000) % 60;\n    millisec = (time \/ 10) % 1000;\n    chprintf(chp, \"%d:%2d:%2d.%3d\\n\\r\", hours, minutes, seconds, millisec);\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_7, (millisec % 10));\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_6, ((millisec \/ 10) % 10));\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_5, (millisec \/ 100));\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_4, (seconds % 10) | DOT);\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_3, (seconds \/ 10));\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_2, (minutes % 10) | DOT);\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_1, (minutes \/ 10));\n    max7219WriteRegister(&amp;SPID1, MAX7219_AD_DIGIT_0, hours | DOT);\n    chThdSleepMilliseconds(1);\n  }\n  spiStop(&amp;SPID1);\n}<\/pre>\n<h3 id=\"4_Project_download\" class=\"level_1\">Project download<\/h3>\n<p>The attached demo has been tested under ChibiOS 20.3.x.<\/p>\n<p><a href=\"https:\/\/playembedded.org\/wp-content\/uploads\/2021\/07\/RT-STM32F401RE-NUCLEO64-MAX7219-7_segment_display-216.7z\" rel=\"\">RT-STM32F401RE-NUCLEO64-MAX7219-7_segment_display-216<\/a><\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>A compact display driver: the MAX7219 We have already introduced MAX7219 in STM32, ChibiOS and a 8&times;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 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":2383,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1225],"tags":[],"coauthors":[241],"class_list":["post-2163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-interfacing-externals","red"],"views":10976,"jetpack_featured_media_url":"https:\/\/playembedded.org\/blog\/wp-content\/uploads\/2016\/04\/7-segment-display-and-STM32-using-ChibiOS.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/2163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/comments?post=2163"}],"version-history":[{"count":0,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/posts\/2163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media\/2383"}],"wp:attachment":[{"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/media?parent=2163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/categories?post=2163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/tags?post=2163"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/playembedded.org\/blog\/wp-json\/wp\/v2\/coauthors?post=2163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}