MAX7219 Display Driver

This is a new library unit for employing the MAX7219 display driver. It's quite extensive and can handle either multiplexed 7-segment displays (up to eight digits) or 8X8 matrix LED displays.

Actually, there are two units. The second one contains the font data and is invoked automatically when the first library unit is used. The download package contains both, zipped together.

Overview


For 7-segment displays, the internal decoder of the MAX7219 only supports  decimal digits, a minus sign, the letters in the word  "HELP," and a blank (codes 0 through 15). Using external codes instead (which is the default when the compiler constant  described below is not defined) permits up to 128 possible  characters, taken from the MAX7219_FONTS.pas library.

As it stands now, the hexadecimal digits 0 through F are defined there, along with the blank and the minus sign. Feel free to add in some new characters. Note that the Seg7_Hex() command (to be described shortly) cannot print the hex digits should you decide to use the chip's internal decoder. A warning will be issued. All other commands work equally well with either internal or external decoding.

The Pascal standard output may be connected to the Seg7_Write() procedure by means of:

assign(output, Seg7_Write);

In this way, you can then use write() and writeln() to directly print bytes, shortints, words, integers, longwords and longints. Remember that you can use format specifiers in write() and writeln() to right justify the numbers within specific field widths. If a person were to extend the external HexCode[] array in the font library to include decent letters, then even strings would be possible. Not all letters are reasonable on a 7-segment display, however.

The LED orientation for the matrix commands is to have column 1 on the left and row 1 on the top. Therefore, the point (1, 1) is in the upper lefthand corner, and (8, 8) is in the lower righthand corner.


Compilation Constants


The three following conditional compilation constants set  the operating mode, shown below with sample values. The  first indicates how many digits are in the seven-segment  display device. If not specified, then the value defaults  to eight. The second indicates if you wish to use the  on-chip decoding instead of the more extensive external  character set. The third specifies whether you are driving a seven-segment display (default) or a matrix LED display.

{$DEFINE MAX7219_DIGITS 8}      // number of digits
{$DEFINE MAX7219_INTERNAL_CODE} // internal decoder
{$DEFINE MAX7219_MATRIX}        // matrix LED mode


Bear in mind that the number of digits you set should  accurately reflect how many you're actually using, or  else you'll need to increase the resistor which sets the current reference to the chip. The data sheet warns  about choosing three digits or less without bumping this  resistor. The default of eight digits helps guard  against excess current flow should you forget to set a  value.

Three pins are required by this chip and their connection to the PIC is established by the following conditional compiler constants (shown with example values for the PIC16F88):

// LOAD (CS) pin 
{$DEFINE MAX7219_LOAD_PORT 'PORTB'}  
{$DEFINE MAX7219_LOAD_PIN 0}

// CLOCK (CLK) pin 
{$DEFINE MAX7219_CLOCK_PORT 'PORTB'} 
{$DEFINE MAX7219_CLOCK_PIN 1}

// DATA (DIN) pin
{$DEFINE MAX7219_DATA_PORT 'PORTB'}   
{$DEFINE MAX7219_DATA_PIN 2}

All of these pins are automatically initialized when the unit is used with your programs. The display is also initialized and cleared.

Global Constants and Types


The global constant NUM_DIGITS is available to your program, if needed. Obviously, its value is the number of digits in your 7-segment display.

The global data type tSegment is also available. It is defined by:

tSegment = (Seg7_g, Seg7_f, Seg7_e, Seg7_d, Seg7_c, Seg7_b, Seg7_a, Seg7_dp);

Commands


Put on your seatbelts! Here come the commands for manipulating a 7-segment display. The matrix LED commands follow afterward.

procedure Seg7_Enable(state : boolean);
Enable/disable display.
state : false = disable (but maintains all stored data), true = enable

procedure Seg7_Clear;
Clear all 7-segment digits.

procedure Seg7_Intensity(value : byte);
Set brightness of the 7-segment display.
value = 0 (dim) to 15 (bright)

procedure Seg7_Segment(address : byte; segment : tSegment);
Turn on a single segment within a specific device, leaving all others turned off. address: device address (1..8)
segment : segment to light (Seg7_g..Seg7_dp)

procedure Seg7_Digit(address, data : byte; dp : boolean);
Display a character on the specified 7-segment digit.
address: specified digit (1..8)
data: value to display there (0..9) or (0..F) if using external codes
dp: show decimal point, yes or no

procedure Seg7_Dec(data : longint);
Print decimal value on display, up to the current max number of digits.
data : value to be printed

procedure Seg7_Hex(data : longint);
Print hex value on display, up to the current max number of digits.
REMINDER: hex digits A..F are not available with internal chip decoder.
data : value to be printed

procedure Seg7_Write(ch : char);
Print character at current position. Obviously, the character may only be what's in the internal or external font set.
ch : character to be printed

And the following commands are for an 8X8 matrix display.

procedure MTX_Enable(state : boolean);
Enable/disable display.
state : false = disable (but maintains all data), true = enable

procedure MTX_Intensity(value : byte);
Set brightness of the display.
value = 0 (dim) to 15 (bright)

procedure MTX_Clear;
Turn all LEDs off.

procedure MTX_Column(column : byte; state : boolean);
Light or extinguish an entire column.
column : 1 through 8,
state : 0 = extinguish, 1 = light

procedure MTX_Row(row : byte; state : boolean);
Light or extinguish an entire row.
row : 1 through 8
state : 0 = extinguish, 1 = light

procedure MTX_LED(row, column : byte; state : boolean);
Light or extinguish a single LED.
row, column : 1 through 8
state : 0 = extinguish, 1 = light

procedure MTX_Load(character : char; update : boolean);
Load a character into the buffer(s).
update : false = load character into NextBuffer only, true = load character into NextBuffer and CurrentBuffer

procedure MTX_Update;
Update display with data in current buffer

procedure MTX_Print(character : char);
Print a character to the display.

procedure MTX_SlideL(speed : byte);
Slide character left off of the display.
speed : how fast the character slides

procedure MTX_SlideR(speed : byte);
Slide character right off of the display.
speed : how fast the character slides

procedure MTX_SlideU(speed : byte);
Slide character up off of the display.
speed : how fast the character slides

procedure MTX_SlideD(speed : byte);
Slide character down off of the display.
speed : how fast the character slides 

procedure MTX_ScrollL(character : char; speed : byte);
Slide current character out left as next character slides in from right.
character : next character to slide in to replace the current one
speed : how fast the characters scroll

procedure MTX_ScrollR(character : char; speed : byte);
Slide current character out right as next character slides in from left.
character : next character to slide in to replace the current one
speed : how fast the characters scroll

procedure MTX_Msg(st : string;  speed : byte);
Print a message, one character at a time, scrolling left.
st : string
speed : how fast the characters scroll

Add It to Your Library Collection


And here are the two new library units, "MAX7219.pas" and "MAX7219_FONTS.pas" for you to download:


Be sure to read over the source code for additional details on how to use it.

Try It Out


There are two exercises on this blog which can demonstrate this library unit. The first shows how to drive an eight-digit, 7-segment display. Go to it here. The second one shows how to drive an 8X8 LED matrix. You'll find it here.

No comments:

Post a Comment