Saturday, October 30, 2021

7-Segment multiplexed display

In the past I designed my 7-segment multiplexed displays using the traditional method using transistors and a crap load of resistors, but recently I found the MAX7219 integrated circuit that performed the same functionality with a minimal of support components.

The MAX7219 is capable of displaying from 1 to 8 7-segment displays or an 8x8 dot matrix LED display. I wrote another article on using this IC with a dot matrix display, see MAX7219 DotMatrix library

As a proof of concept and to find out how to program the device I first wired it up on a breadboard. After discovering how easy it was to not only wire but also to program I decided to send off for a PCB from one of the inexpensive offshore production houses. The result is shown in Figure 1. I am new at PCB design so I let the IDE auto route the board and although it works it's not the prettiest.

Figure 1. Schematic of the 7-segment multiplexed display board .

The chip is programmed using a 3-wire SPI communications protocol. The MISO pin is not used since you can only output to the device. The display and segments may be access independently and provide a very flexible way of managing the displays.

    \
       #define F_CPU 16000000UL
       
       #include 
       #include 
       #include "CSpiChip.h"
       
       #define ENABLE		0x0C
       #define TEST        0x0F
       #define INTENSITY	0x0A
       #define SCAN_LIMIT  0x0B
       #define DECODE      0x09
       
       void Send(uint8_t cmd, uint8_t data);
       
       CSpiChip spi;
       
       int main(void)
       {
           spi.ConfigureChannel(0, &PORTB, PORTB1);
           
           uint8_t ary[] = {  0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f,
                                        0x73,0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47 };
           
           Send(TEST, 0);
           Send(DECODE, 0);
           Send(SCAN_LIMIT, 0x05);
           Send(ENABLE, 0x01);
           Send(INTENSITY, 0x01);
           
           while (1) 
           {
               for (uint8_t i = 0; i < 16; i++)
               {
                   Send(0x01, ary[i]);
               
                   _delay_ms(1000);
               }
           }
       }
       
       void Send(uint8_t cmd, uint8_t data)
       {
           spi.SetCSState(0, LOW);
                   
           spi.TransferData(cmd);
           spi.TransferData(data);
                   
           spi.SetCSState(0, HIGH);
       }       
    
    
Listing 1. Count from 0-F on the first digit.

The reason I wrote this piece of code is that I'm writing a Z80 monitor application and I was having a lot of problems with displaying the data. I had just received the display board from the PCB house and didn't know if the board was bad or my code. I had written some C++ code when I was doing the POC so I knew it was working. The board turned out to work fine it was my code that was at fault, but it's always good to be able to test the hardware with code that is known to be working.

Top ^