In this tutorial, we will learn to interface multiple 8×8 LED Matrix with pic microcontroller. MAX7219 will be used as a driver to control the LED matrix. As you know, to drive an 8×8 LED matrix consists of 16 pins and therefore, we need 16 GPIO pins of a pic microcontroller to drive a single display. Furthermore, if we want to interface four displays, we will become short of digital output pins of pic microcontroller. Therefore, we will MAX7219 to interface multiple 8×8 LED matrix. In the last tutorial, we have learned MAX7219 Interfacing with 8-digit 7 Segment Display and PIC16F877A.
How to use MAX7219 with Pic microcontroller?
Max7219 display driver IC consists of sixteen output pins that we can use to connect with a single LED matrix. In this tutorial, we will use four display modules. Hence, we will need four display driver ICs. It can be easily interfaced with any microcontroller using SPI communication mode. We will use the PIC16F877A microcontroller that comes with a built-in SPI communication module. If you don’t know about SPI communication and how to use pic microcontroller SPI module, you should read the following tutorials first:
Interfacing Circuit diagram
To interface MAX7219 with PIC16F877A microcontroller and 8×8 LED Matrix, make connections according to this circuit diagram. This diagram is not clear. Therefore, I provided a connections reference in the table below.
PIC16F877A | MAX7219 |
---|---|
RC0 (15) | DIN (1) |
RC1 (16) | LOAD (12) |
RC2 (17) | CLOCK (13) |
MAX7219 | 8×8 LED Matrix (four) |
---|---|
A to DP | Each row Pin 0 to Pin 7 |
DIG0 to DIG7 | Each column Pin 0 to Pin 7 |
Complete schematic diagram with output will look this:
Pic Microcontroller Code
In this section, we will see how to write code to control four 8×8 LED matrices with max7219 LED driver IC.
First, we should define an array of characters ASCII values that we want to display on each LED matrix. Here, we define a constant array with the name of “symbol” and it contains hex values of 94 characters.
#ifndef ASCII_CHART_H
#define ASCII_CHART_H
//------------------------------------------------------------------------------
unsigned const char symbol[97][8] =
{
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, //Ascii-32
{ 0x00,0x00,0x00,0x5F,0x5F,0x00,0x00,0x00 }, //Ascii-33
{ 0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00 }, //Ascii-34
{ 0x24,0x7E,0x7E,0x24,0x7E,0x7E,0x24,0x00 }, //Ascii-35
{ 0x00,0x24,0x2E,0x6B,0x6B,0x3A,0x12,0x00 }, //Ascii-36
{ 0x00,0x66,0x36,0x18,0x0C,0x66,0x62,0x00 }, //Ascii-37
{ 0x30,0x7A,0x4F,0x5D,0x37,0x72,0x50,0x00 }, //Ascii-38
{ 0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00 }, //Ascii-39
{ 0x00,0x00,0x00,0x3E,0x7F,0x63,0x41,0x00 }, //Ascii-40
{ 0x00,0x41,0x63,0x7F,0x3E,0x00,0x00,0x00 }, //Ascii-41
{ 0x08,0x2A,0x3E,0x1C,0x1C,0x3E,0x2A,0x08 }, //Ascii-42
{ 0x00,0x08,0x08,0x3E,0x3E,0x08,0x08,0x00 }, //Ascii-43
{ 0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x00 }, //Ascii-44
{ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00 }, //Ascii-45
{ 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00 }, //Ascii-46
{ 0x00,0x60,0x30,0x18,0x0C,0x06,0x03,0x00 }, //Ascii-47
{ 0x00,0x3E,0x7F,0x49,0x45,0x7F,0x3E,0x00 }, //Ascii-48
{ 0x00,0x40,0x42,0x7F,0x7F,0x40,0x40,0x00 }, //Ascii-49
{ 0x00,0x42,0x63,0x71,0x59,0x4F,0x46,0x00 }, //Ascii-50
{ 0x00,0x21,0x61,0x45,0x4F,0x7B,0x31,0x00 }, //Ascii-51
{ 0x00,0x18,0x1C,0x16,0x7F,0x7F,0x10,0x00 }, //Ascii-52
{ 0x00,0x27,0x67,0x45,0x45,0x7D,0x39,0x00 }, //Ascii-53
{ 0x00,0x3E,0x7F,0x49,0x49,0x79,0x30,0x00 }, //Ascii-54
{ 0x00,0x01,0x71,0x79,0x0D,0x07,0x03,0x00 }, //Ascii-55
{ 0x00,0x36,0x7F,0x49,0x49,0x7F,0x36,0x00 }, //Ascii-56
{ 0x00,0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00 }, //Ascii-57
{ 0x00,0x00,0x00,0x36,0x36,0x00,0x00,0x00 }, //Ascii-58
{ 0x00,0x00,0x40,0x76,0x36,0x00,0x00,0x00 }, //Ascii-59
{ 0x00,0x00,0x08,0x1C,0x36,0x63,0x41,0x00 }, //Ascii-60
{ 0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00 }, //Ascii-61
{ 0x00,0x41,0x63,0x36,0x1C,0x08,0x00,0x00 }, //Ascii-62
{ 0x00,0x02,0x03,0x51,0x59,0x0F,0x06,0x00 }, //Ascii-63
{ 0x00,0x3E,0x7F,0x41,0x5D,0x57,0x5E,0x00 }, //Ascii-64
{ 0x00,0x7C,0x7E,0x13,0x13,0x7E,0x7C,0x00 }, //Ascii-65
{ 0x00,0x7F,0x7F,0x49,0x49,0x7F,0x36,0x00 }, //Ascii-66
{ 0x00,0x3E,0x7F,0x41,0x41,0x63,0x22,0x00 }, //Ascii-67
{ 0x00,0x7F,0x7F,0x41,0x63,0x3E,0x1C,0x00 }, //Ascii-68
{ 0x00,0x7F,0x7F,0x49,0x49,0x49,0x41,0x00 }, //Ascii-69
{ 0x00,0x7F,0x7F,0x09,0x09,0x09,0x01,0x00 }, //Ascii-70
{ 0x00,0x3E,0x7F,0x41,0x49,0x79,0x79,0x00 }, //Ascii-71
{ 0x00,0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00 }, //Ascii-72
{ 0x00,0x00,0x41,0x7F,0x7F,0x41,0x00,0x00 }, //Ascii-73
{ 0x00,0x20,0x60,0x40,0x40,0x7F,0x3F,0x00 }, //Ascii-74
{ 0x00,0x7F,0x7F,0x1C,0x36,0x63,0x41,0x00 }, //Ascii-75
{ 0x00,0x7F,0x7F,0x40,0x40,0x40,0x40,0x00 }, //Ascii-76
{ 0x7F,0x7F,0x06,0x0C,0x06,0x7F,0x7F,0x00 }, //Ascii-77
{ 0x00,0x7F,0x7F,0x0E,0x1C,0x7F,0x7F,0x00 }, //Ascii-78
{ 0x00,0x3E,0x7F,0x41,0x41,0x7F,0x3E,0x00 }, //Ascii-79
{ 0x00,0x7F,0x7F,0x09,0x09,0x0F,0x06,0x00 }, //Ascii-80
{ 0x00,0x3E,0x7F,0x51,0x21,0x7F,0x5E,0x00 }, //Ascii-81
{ 0x00,0x7F,0x7F,0x09,0x19,0x7F,0x66,0x00 }, //Ascii-82
{ 0x00,0x26,0x6F,0x49,0x49,0x7B,0x32,0x00 }, //Ascii-83
{ 0x00,0x01,0x01,0x7F,0x7F,0x01,0x01,0x00 }, //Ascii-84
{ 0x00,0x3F,0x7F,0x40,0x40,0x7F,0x7F,0x00 }, //Ascii-85
{ 0x00,0x1F,0x3F,0x60,0x60,0x3F,0x1F,0x00 }, //Ascii-86
{ 0x7F,0x7F,0x30,0x18,0x30,0x7F,0x7F,0x00 }, //Ascii-87
{ 0x00,0x63,0x77,0x1C,0x1C,0x77,0x63,0x00 }, //Ascii-88
{ 0x00,0x07,0x0F,0x78,0x78,0x0F,0x07,0x00 }, //Ascii-89
{ 0x00,0x61,0x71,0x59,0x4D,0x47,0x43,0x00 }, //Ascii-90
{ 0x00,0x00,0x00,0x7F,0x7F,0x41,0x41,0x00 }, //Ascii-91
{ 0x00,0x03,0x06,0x0C,0x18,0x30,0x60,0x00 }, //Ascii-92
{ 0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00 }, //Ascii-93
{ 0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00 }, //Ascii-94
{ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00 }, //Ascii-95
{ 0x02,0x06,0x0C,0x08,0x00,0x00,0x00,0x00 }, //Ascii-96
{ 0x00,0x20,0x74,0x54,0x54,0x7C,0x78,0x00 }, //Ascii-97
{ 0x00,0x7F,0x7F,0x44,0x44,0x7C,0x38,0x00 }, //Ascii-98
{ 0x00,0x38,0x7C,0x44,0x44,0x44,0x00,0x00 }, //Ascii-99
{ 0x00,0x38,0x7C,0x44,0x44,0x7F,0x7F,0x00 }, //Ascii-100
{ 0x00,0x38,0x7C,0x54,0x54,0x5C,0x18,0x00 }, //Ascii-101
{ 0x00,0x04,0x7E,0x7F,0x05,0x05,0x00,0x00 }, //Ascii-102
{ 0x00,0x98,0xBC,0xA4,0xA4,0xFC,0x7C,0x00 }, //Ascii-103
{ 0x00,0x7F,0x7F,0x04,0x04,0x7C,0x78,0x00 }, //Ascii-104
{ 0x00,0x00,0x44,0x7D,0x7D,0x40,0x00,0x00 }, //Ascii-105
{ 0x00,0x80,0x80,0xFD,0x7D,0x00,0x00,0x00 }, //Ascii-106
{ 0x00,0x7F,0x7F,0x10,0x38,0x6C,0x44,0x00 }, //Ascii-107
{ 0x00,0x00,0x41,0x7F,0x7F,0x40,0x00,0x00 }, //Ascii-108
{ 0x7C,0x7C,0x0C,0x18,0x0C,0x7C,0x78,0x00 }, //Ascii-109
{ 0x00,0x7C,0x7C,0x04,0x04,0x7C,0x78,0x00 }, //Ascii-110
{ 0x00,0x38,0x7C,0x44,0x44,0x7C,0x38,0x00 }, //Ascii-111
{ 0x00,0xFC,0xFC,0x44,0x44,0x7C,0x38,0x00 }, //Ascii-112
{ 0x00,0x38,0x7C,0x44,0x44,0xFC,0xFC,0x00 }, //Ascii-113
{ 0x00,0x7C,0x7C,0x04,0x04,0x0C,0x08,0x00 }, //Ascii-114
{ 0x00,0x48,0x5C,0x54,0x54,0x74,0x24,0x00 }, //Ascii-115
{ 0x00,0x04,0x04,0x3E,0x7E,0x44,0x44,0x00 }, //Ascii-116
{ 0x00,0x3C,0x7C,0x40,0x40,0x7C,0x7C,0x00 }, //Ascii-117
{ 0x00,0x1C,0x3C,0x60,0x60,0x3C,0x1C,0x00 }, //Ascii-118
{ 0x1C,0x7C,0x60,0x30,0x60,0x7C,0x1C,0x00 }, //Ascii-119
{ 0x00,0x44,0x6C,0x38,0x38,0x6C,0x44,0x00 }, //Ascii-120
{ 0x00,0x9C,0xBC,0xA0,0xA0,0xFC,0x7C,0x00 }, //Ascii-121
{ 0x00,0x44,0x64,0x74,0x5C,0x4C,0x44,0x00 }, //Ascii-122
{ 0x00,0x00,0x08,0x3E,0x77,0x41,0x41,0x00 }, //Ascii-123
{ 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00 }, //Ascii-124
{ 0x00,0x41,0x41,0x77,0x3E,0x08,0x00,0x00 }, //Ascii-125
{ 0x0C,0x06,0x06,0x0C,0x18,0x18,0x0C,0x00 }, //Ascii-126
{ 0x00,0x60,0x78,0x5E,0x46,0x58,0x60,0x00 } //Ascii-127
};
//------------------------------------------------------------------------------
#endif
We will use soft SPI library to communicate with PIC16F877A microcontroller and MAX7219. Hence, we should define the pins of PIC16F877A used for soft SPI communication library.
These functions provides a definition of each soft SPI function such as initialization, SPI data transmit and receive functions.
#ifndef SPI_H
#define SPI_H
//------------------------------------------------------------------------------
#include "Soft_SPI_Pins.h"
//------------------------------------------------------------------------------
void SPI_init(void)
{
SCLK_dir = 0;
SDOUT_dir = 0;
SDIN_dir = 1;
CS0_dir = 0;
CS1_dir = 0;
}
//--------------------------TX: transmit data-----------------------------------
void SPI_write(char send)
{
for(int Tx = 0 ; Tx < 8 ; Tx++ )
{
SCLK = 0;
SDOUT = ( (send << Tx) & 0x80 ) ? 1 : 0; //MSB first.
SCLK = 1;
}
}
//--------------------------RX: recieve data------------------------------------
char SPI_read(void)
{
char data = 0;
for(int Rx = 0 ; Rx < 8 ; Rx++ )
{
SCLK = 0;
data += (SDIN << (7-Rx)); //MSB first.
SCLK = 1;
}
return data;
}
//------------------------------------------------------------------------------
#endif
These functions are used to send data from pic microcontroller to MAX7219 using above define SPI communication library.
void MAX7219_init(char noChips)
{
SPI_init();
while(noChips)
MAX7219_config(--noChips);
}
//------------------------------------------------------------------------------
void MAX7219_config(char chip)
{
MAX7219_write(DECODE_MODE_REG,DISABLE_DECODE,chip);
MAX7219_write(INTESITY_REG,BRIGHTNESS,chip);
MAX7219_write(SCAN_LIMIT_REG,SCAN_ALL_DIGITS,chip);
MAX7219_write(SHUTDOWN_REG,NORMAL_OPERATION,chip);
MAX7219_write(DISPLAY_TEST_REG,DISABLE_TEST,chip);
}
//------------------------------------------------------------------------------
void MAX7219_write(char regName,char data,char chip)
{
CS0 = 0;
SPI_write(regName);
SPI_write(data);
while(chip--)
MAX7219_NoOperation(); //Used for daisy chained (Cascaded) arrangements
CS0 = 1;
}
//------------------------------------------------------------------------------
void MAX7219_displayText(char* text)
{
char chip = 0;
while(*text)
{
char row = (*text++) - 32;//(Text-32)...because the first 32 ASCII character codes are none Printable (control chars)
for(int col = 0; col < 8; col++)
{
MAX7219_write( col, symbol[row][col], chip );
}
chip++;
}
}
//-----------Passes the data to the adjacent MAX7219 in the Daisy Chain---------
void MAX7219_NoOperation()
{
SPI_write(NO_OP_REG);
SPI_write(0x00); //Don't care (Can be any arbitrary value)
}
//------------------------------------------------------------------------------
How Code works?
This code is for MPLAB XC8 Compiler. If you don’t know how to use MPLAB and XC8 compiler, you can read this complete in-depth guide:
This is a main function of the code. Include all libraries in a header file as shown below. This example code prints “ABCD” on 8×8 LED matrix.
#include <stdio.h>
#include <stdlib.h>
//------------------------------------------------------------------------------
#include "ascii_chars.h"
#include "MAX7219.h"
//------------------------------------------------------------------------------
int main(int argc, char** argv)
{
MAX7219_init(4); //Pass number of Chips as argument
while(1)
{
MAX7219_displayText("ABCD");
}
return (EXIT_SUCCESS);
}
//------------------------------------------------------------------------------
Now lets change the text to “MCU1” by changing the string inMAX7219_displayText() fucntion.
MAX7219_displayText("MCU1");
As you can see from the figure below, now it displays MCU1 string.
Other Articles:
Good very easy & useful
Thanks/
8×8 matrix interfacing with pic MC is useful
Can you write a simple program where you use every command in this program?
I am working on it project of 8×8 led matrix date time.
Hello,
Good job. 👏 . I could implement the project on Pic18f48q10 MCU. Would it be possible to share the code for the scrolling text? Thanks.