Using the BX24 SPI Port to Interface with a MAX7219 8-Digit LED Display Driver

copyright, Peter H Anderson, Baltimore, MD, Feb 00


This discussion illustrates the use of the BX24's SPI Port to interface with the MAX7219 eight 7-seg LED Driver. The advantage in using the SPI interface is that the MAX7219 may be controlled using only one (vs three) of the precious 16 general purpose IO pins. SCK and MOSI on the BX24 SPI interface are used and these may also be shared with other SPI devices as well.

Earlier routines developed in Dec, '99, used three of the 16 general purpose IO terminals on the BX24 for CLK, DAT and CS. A minor revision was made in Feb, '00 to modify the MAX7219Init() routine to write a zero to MAX7219 register 15 (&H0F) so as to place the MAX7219 in "normal" operation as opposed to "test" operation where all segments of all LEDs are continually turned on.

The following routine MAX7219_1B.Bas is a rework of MAX7219_1.Bas from Dec, '99 which uses the BX24's SPI interface. Note that SCK (hole 3) on the BX24 is connected to CLK (term 13) on the MAX7219 and MOSI (Master Out Slave In) at hole 5 of the BX24 is connected to DIn (term 1) on the MAX7219. One general purpose IO is used to select the specific SPI address.

A schematic of this arrangement is included with our MAX7219 Kit.

The software revisions are minor. In Sub Main() an SPI channel is opened using the OpenSPI() command. I happened to define this as SPI channel 2 using terminal 12 as the chip select.

Sub Max7219Out16(ByVal X as Integer) was modified to use the SPICmd() routine as opposed to "bit banging" as was used in the December version. Note that the high and low bytes of X are placed in contiguous locations beginning at the address of PutData(1) and are then output using the SPICmd()

I will leave it for you to modify the various routines which were developed in Dec, '99. Simply open an SPI channel in Main() and substitute this modified implementation of Sub Max7219Out16().

' MAX7219_1B.Bas
' Illustrates the use of a MAX7219 Serially Interfaced, 8-Digit Display 
' Driver.  Same as MAX7219_1.Bas except uses BX24's SPI Bus.
' The only differences are that in Sub Main, an SPI Channel is opened;
'   Call OpenSPI(2, SPISetUpByte, MAX7219CS)	' CS is terminal 12
' and in Sub Max7219Out16(ByVal X as Integer), the integer X is split into 
' high and low bytes and output using the SPICmd()
' Example uses four MAN74 7-Segment LEDs (Common Cathode) as Digits 3, 2, 
' 1 and 0.
'   BX-24 			MAX7219
'  SCK (Hole 3)  ----------- CLK (term 13)
'  MOSI (Hole 5) ----------- DIN (term 1)
'  CS (term 12) ------------ LOAD (term 12)
' Note that the "holes" refer to the array of seven holes at the top of the 
' BX24.  Hole 1 is closest to terminal 24.  
' In initializing the MAX7219;
'    Decode Mode (Register 9) set for Code B on all digits.
'    Intensity (Register 10) set for 15/32
'    Scan Limit (Register 11) set for Digits 0, 1, 2, 3
'    Display Test (Register 15) set for normal operation.
' The numbers 0000 - 9999 are sequentially displayed.  No sign and no zero
' suppression.
' Note that in outputting the 16 bit quantity, the quantity is split into
' a high and low byte and each is then output.
' This was a part of a Senior Project by Kenrick David.
' copyright, Peter H. Anderson, Baltimore, MD, Feb, '00

   Const DecodeModeCode as Integer = &H900
   Const IntensityCode as Integer = &Ha00
   Const ScanLimitCode as Integer = &Hb00
   Const TurnOnCode as Integer = &Hc00
   Const DisplayTestCode as Integer = &Hf00

   Const MAX7219CS as Byte = 12
					' define SPI Setup Bits
   Const SPI_LSB as Byte = &H20 'lsb transmitted first 
   Const SPI_CPOL as Byte = &H08 'sck is mostly high 
   Const SPI_CPHA as Byte = &H04 'clock phase, see atmel docs for timing
   Const SPI_SCK4 as Byte = &H00 'clock speed f/4 
   Const SPI_SCK16 as Byte = &H01 'clock speed f/16 
   Const SPI_SCK64 as Byte = &H02 'clock speed f/64 
   Const SPI_SCK128 as Byte = &H03 'clock speed f/128 

Sub Main()

   Dim Q as Integer
   Dim N as Integer
   Dim SPISetUpByte as Byte

   Call OpenSerialPort(1, 19200)	' used for debugging
   SPISetUpByte = 0	' most sig first, 0 0 clocking, f/4

   Call OpenSPI(2, SPISetUpByte, MAX7219CS)	' open an SPI channel 
						' using term 12 as CS

      Call Max7219Init()
      For N = 0 to 9999
         Call Max7219PutUI(N)	' unsigned intger, no zero suppression
         Call Sleep(1.0)
End Sub

Sub Max7219Init() 	
' initialize, Code B, 15/32 intensity, Digits 0, 1, 2, 3, Display On, 
' Test Mode Off

   Call Max7219Out16 (DisplayTestCode) ' Normal Operation vs Test
   Call Max7219Out16 (DecodeModeCode OR &Hff) 'Sets Decode Mode
   Call Max7219Out16 (IntensityCode  OR &H07) 'Sets Intensity
   Call Max7219Out16 (ScanLimitCode OR &H03) 'Sets Scan Limit  
   Call Max7219Out16 (TurnOnCode OR &H01) ' Turn it on

End Sub

Sub Max7219PutUI(ByVal Q as Integer)	' 4 Digits
   Dim D as Integer
   D = Q\1000
   Call Max7219Out16(4*256 + D)	' note 00000100 in high byte - Digit 3
   Q = Q Mod 1000
   D = Q\100
   Call Max7219Out16(3*256 + D)	' 0000 0011 in high byte - Digit 2
   Q = Q mod 100
   D = Q\10
   Call Max7219Out16(2*256 + D)	' Digit 1
   Q = Q Mod 10 
   D = Q
   Call Max7219Out16(1*256 + D)	' Digit 0	  
End Sub  
Sub Max7219Out16(ByVal X as Integer)
' shifts out 16-bit quantity, most sig bit first
   Dim PutData(1 to 2) as Byte, H as Byte, L as Byte
   Dim GetData as Byte

   H = CByte(X\256)	' Split into high and low bytes
   L = CByte(X - (CInt(H)*256))
   PutData(1) = H	' and put into contiguous addresses	
   PutData(2) = L
   ' Call PutB(H)		' used for debugging
   ' Call PutByte(Asc(" "))
   ' Call PutB(L)
   ' Call NewLine()
   Call SPICmd(2, 2, PutData(1), 0, GetData)	' Output two bytes beginning 
						' at location of PutData(1)
End Sub