RUNNING DISPLAY
Library of Routines: A-E  E-P  P-Z
PIC12F629 INSTRUCTION SET

8x8 Display Module kit
Buy 8x8 Dot Matrix Module from eBay
Buy Running Display project
THE FILES:
test-1.asm  .txt    .hex
test-2.asm  .txt    .hex
test-3.asm  .txt    .hex

8x8 Display.asm
8x8 Display.txt
8x8 Display.hex

CASCADING THE 8x8
PONG



This project combines two modules. 8x8 Dot Matrix Module from eBay for $5.00 and our "Running Display" for $7.00
Our "Running Display" project allows the
8x8 Dot Matrix Module to produce running messages.

The
8x8 Dot Matrix Module from eBay is one of the most popular projects on the web, but you can't do much with it without a lot of instructions for the MAX chip to activate the display. That's what our project does. It drives the MAX chip.

THE 8x8 DOT MATRIX MODULE
This project is available for less than $5.00 on eBay:
MAX7219 Dot led matrix module MCU control LED Display module
(The Module comes ready-built with 5 connecting leads)
Here are photos of the module with leads. The display showing the part number indicates where pin1 is located.


Make sure you buy the 8x8 kit with leads.

 
The part-number indicates pin 1

And it is very easy to use when you know the secrets.
The 8x8 Matrix (module) has been presented in many projects but none of the them have shown how to interface it to a microcontroller for beginners.
That's what this project will do - it will interface it to one of the smallest micros on the market - the PIC12F629 - to produce a "RUNNING SIGN" that you can program with any message. 
You can also cascade the modules by connecting the output of the first to the input of the second etc.
There are over 3,000 videos of projects using the MAX7219 chip and many of them use the 8x8 Display module.
These videos will give you a good idea of what can be done:
http://tube.7s-b.com/max-7219/page1.html
 



You need two lines from a micro to pass data to the 8x8 display. One line (called the clock line) provides the clock pulses and the second line (called the data line) delivers the data. You need two bytes (16 bits) to load each column (one byte contains the data to illuminate the 8 LEDs in the column and the second byte contains other data - that we will explain later).
One more line is required to "open up" the chip and this line is called "chip select" or "load."  Load means: "Deliver the Information."  The chip contains 8 registers and you can access any register at any time via the address bits: D8, D9, D10, D11. To activate all 64 LEDs requires 8 packets of 16-bits. You can access just one column if needed, so updating can be very quick.
The "chip select" line must be LOW for the chip to accept data and immediately taken HIGH after the data has been delivered, to lock it into the registers.
It is then available for display.
You need to send two more packets of information: "noshutdown" to tell the 8x8 to illuminate the display and "Scancols" to tell the 8x8 to scan 8 columns.
A routine in the chip then sends the data to the 8x8 as a SCAN ROUTINE and scans the rows 800 times per second.   
Finally the micro and chip must have the same 0v rail so all voltages (signals) will perform their required task.
This takes a total of 5 lines.



For the MAX7219, serial data at Din, sent in 16-bit packets, is shifted into the internal 16-bit shift register with each rising edge of CLK regardless of the state of LOAD. For the MAX7221, CS must be low to clock data in or out. The data is then latched into either the digit or control registers on the rising edge of LOAD/CS. (In other words, LOAD must be taken HIGH then LOW to latch the information.
LOAD/CS must go high concurrently with or after the 16th rising of each clock edge, but before the next rising clock edge or data will be lost. Data at Din is propagated through the shift register and appears at DOUT 16.5 clock cycles later. (This is used when cascading displays). Data is clocked out on the falling edge of CLK. Data bits are labeled D0–D15 (picture above). D8–D11 contain the register address. D0–D7 contain the data, and D12–D15 are “don’t care” bits. The first received is D15, the most significant bit (MSB).

This uses 3 lines from our micro - in other words 3 port lines. Our micro has 5 in/out lines plus one input-only line.
We use another input-output line to connect 4 mini switches to create a keyboard and one output with a LED and resistor to test the keypad during set-up. This leaves one input-only line for expansions.

The first kit you need to buy is the 8x8 Dot Matrix Module from eBay for about $5.00:



 

 

 


The 8x8 Dot Matrix Module does not do anything without a lot of instructions sent to the MAX chip to illuminate the required pixels on the display.
That is what our Running Display project does. It sends the commands to the MAX chip. Our project stores the bit-patterns for the alphabet and numbers so a "Running Message" can be produced on the display.

You don't need to know anything about the connections of the MAX chip to the display as the module comes with a double-sided printed circuit board, IC socket and pins to accepts the 8x8 Dot Matrix Module.
This module is constructed as shown in the photo above but the 5 lower pins are replaced with 5 leads and a socket, so the lines can be connected to our Running Display project.
If you have bought the MAX chip and 8x8 Dot Matrix Display separately, all the 8x8 Displays supplied in the kits have the same pin-out, although they have different part numbers. We can assume the 8x8 you have bought will have the same pin-out.

There is only one other difference between the 8x8 Dot Matrix modules: The PC boards have 5 input pins: Vcc, Gnd, Din, Chip Select and Clock. However, Chip Select and Clock may be Clock and Chip Select, but this does not cause any problems.
If you are building the 8x8 Display Module from individual components, here is an important point to note:
The 8x8 Displays are mounted with Pin 1 in the position shown in the photo above and this means the connections to the chip are different to the designated pinout for the MAX7219. All the lines from the chip are connected to the designated places as specified on the pin-out diagram, except segments A to G have been reversed. The decimal point (segment G) remains the same.
Buying the 8x8 Dot Matrix Module kit on eBay is cheaper than buying the individual components (less than half the cost) and it makes you wonder why we are charged so much for individual components - especially the MAX chip, where some suppliers want more than $16.00 for the chip! (X-ON Components).
 
Our project connects to the 8x8 Dot Matrix Module via 5 lines and these need to be connected to our project via a plug so it can be disconnected when programming the chip.

Here is a sample of the bit-patterns you can produce on the display:

Click HERE for the hex values of the bit-patterns above.

THE "RUNNING DISPLAY" Project
The "Running Display" project consists of a microcontroller and 4 switches.  It contains a program to drive the MAX chip as well as a set of numbers and letters to show on the display.


The micro and surrounding circuitry comprise the "Running Display" project to drive the 8x8 Dot Matrix Display Module. These are two different kits and the suppliers are shown on the circuit.


The 4 "buttons" to increment (UP)
and decrement (DOWN) the letters on
the display, then STORE the
required letter.
RUN produces the final message.
Push RUN before turning on the
project to delete memory.

It actually sets the number of characters in location 7Fh in EEPROM to zero.

CONSTRUCTION
The Running Display project is built on Talking Electronics "Designer Board" so you can easily modify the circuit. The board contains the 5 "In-Circuit Programming" pins and the 5-pin socket for the 8x8 Dot Matrix Module.
The kit comes with all components and the 5 leads to connect the 8x8 Dot Matrix Module to the Running Display project, but not the indicator-LEDs.

THE SUPPLY
The supply must be 6v as the project uses a diode to drop the voltage to the microcontroller to 5.4v. This is the maximum voltage for the micro. The MAX chip and the display are connected to 6v. 

 

Running Display
Parts List

Cost: au
$7.00 plus $6.50postage
Kits are available

2   -  220R (221) SM resistors
4  -  47k  (473) SM resistors

1  -  330p  ceramic capacitor
1  -  100u electrolytic

1  -  SPDT mini slide switch

1  -  1N4148 SM diode
1  -  indicator LED SM red

1  -  PIC12F629 chip (with RUN routine)
1  -  8 pin IC socket 
4  -  tactile switches
1  -  10cm fine tinned copper wire
1  -  10cm fine enamelled wire
1  -  20cm very fine solder 
1  -   5 - component header pins
2  -   5 machine pins
5  -  leads to connect the 8x8 Display
1  -  Designer PC board

1 - 4 x AA cell battery box needed (not in kit)

THE PROGRAM
One of the first things to organise is the detection of the tactile switches.
These switches are detected by a circuit called a TIME DELAY, made up of a "resistor and capacitor" in series.
When a resistor and capacitor are connected in series, it takes a certain period of time to charge the capacitor (and also discharge it).
When the capacitor value is very small and the resistor is large, this time-interval will be very small, but when we are using a microcontroller to detect this interval of time, we can measure in microseconds.
You can see the capacitor is connected to a chain of resistors in the circuit above and one line (called a port-line) from the micro is connected to the capacitor.
The routine starts by the micro making the port-line an output and creating a HIGH on the line. This charges the capacitor and then the micro turns the line into an input and monitors it to see when the capacitor is discharged.
At the moment, the capacitor is connected to the full string of resistors that are not connected to 0v rail and the timing will be long (in the order of many microseconds). The program neglects this reading and classifies it as "no switch pressed."
But if a switch (also called a button) is pressed, the time will be reduced and this timing is detected by the sub-routine.


TESTING THE SWITCHES
The first program we produce to do this is called a TEST PROGRAM or TEST ROUTINE to find out the number of  microseconds for each switch. Each group of 6 microseconds will increment a register called "flashes" and this value is used in our program to detect the particular switch.
This test program is called Test-1.asm
Since the value of the capacitor may have very wide tolerance, our Test Program will generated a value for the capacitor you have used and you must make sure it corresponds with our value.
This is especially noticeable for switch 4 with 10 units of "timing."
To check the value for the switches, button 1 is pressed BEFORE the circuit is turned ON. The circuit is turned ON and the button is released after 1 second (it odes not matter if the switch is released or not). The LED will flash 10 times for button 1. Repeat this for buttons 2, 3, 4 and 5. The LED will flash 7, 5 and 3 times for the other switches. Make sure the LED flashes the same number of times for the capacitor you have used, so the switches will be detected correctly. If not, button 1 will be detected when button 2 is pressed or button 2 will be detected when button 1 is pressed.
The switches are now ready to be detected.


TESTING THE 8x8 MODULE
After building the 8x8 module (containing the 8x8 display and MAX 7219 chip), you will want to get something on the display.
The chip contains 8 registers. Each register holds 8 bits to show the 64 bits of information for the screen and 5 other registers to hold information to:
Decode mode - used for 7-segment displays - not used for 8x8 display    address 9h
Intensity - determines the brightness of the screen    address 0Ah
Scan Limit  - used for  3 x 7Sement displays   address 0Bh
Shutdown -
 turn the display ON or turn it OFF   address 0Ch
Test Display  - turns on all LEDs   address 0Fh
To get something on the screen, you need to
produce 3 sub-routines.
These are contained in Test-2.asm
The first sub-routine loads the address and data to create a column of illuminated LEDs.
The top LED has the value 01. The next LED: 02, 04 08 102040 and the bottom LED 80.
We have used the value 0AAh for column 7 and this means the 2nd 4th 6th and 8th LED will be illuminated.
Don't worry about the other columns. They will be showing JUNK from the other 7 registers as the chip does not clear the registers when it is turned ON.
The next sub-routine in Test-2.asm creates to non-shut-down mode. This make sure the display will illuminates the LEDs.
The next sub-routine tells the chip to scan all 8 columns.
We have added 100mS delays between each of the clock pulses so you can see the chip receiving the data and clock pulses.
Three LEDs are added to the PC board on lines Data, Chip Select and Clock to observe the signals entering the chip.
This is an important aid to getting the circuit to work correctly, if the display fails to illuminate. 
As soon as this information is passed to the chip and Chip Select is taken HIGH, the display will scan.

In Test-3.asm we remove the 100mS delays and see the display illuminate immediately.

Three things we learnt from the "delayed routine:"
1. The chip works at low clock-rate.
2. A small delay must be added between changing bits on the output port. This applies to changing a bit in any PIC register and then wanting to change another bit in the same register. The chip required 300uS between commands for this operation to be reliable (in our routine).
3. The MAX chip must be closed after each sub-routine and opened for the next sub-routine.   

We can now "drive the display" and the rest of the program can be created to show letters and numbers on the display as well as detect the buttons to Increment the Display (button 1), Decrement the Display (button 2), Store the values (button 3) and "RUN" the message across the display (button 4). 

CREATING A RUNNING MESSAGE
Each letter and number uses the 6 middle columns.
This means 6 bytes are required from a table.
The program puts the first byte of a letter into location 48h and a sub-routine shifts the data from location 48h to 47h.
When you push "Run" the display is blank but the shift sub-routine takes the data from 41h and places it is 40h. Then 42h to 41h etc to finally transferring 48h to 747h. This creates the shift on the screen. 
The program then sends the 8 bytes to the 8x8 Display and calls 200mS delay to show the screen.
The program then places the second byte into location 48h and shifts the data to the left.
The data is then sent to the display and shown on the screen for 200mS.
This continues for the 6 bytes of the letter and then the EEPROM is accessed for the address in table1 for the next letter.


The data is shifted LEFT

When all the letters in the message have been displayed, the program starts from the beginning of EEPROM memory and repeats the message.
The hex value for each pixel is shown in the diagram above. These values are needed when you want to create your own images on the display. The table above shows 256 images and the link provides the .hex values for each image.

ICSP FAILURE (In-Circuit Serial Programming Failure)
Sometimes a chip will fail to program on the 6th or 10th programming and it will not program on further attempts.
The reason is one of the cells inside the chip is preventing the signal being recognised by the programmer.
You need to remove the chip from the project so all voltage is removed from the chip to reset the cells, or you can swap the chip for another.
Another problem with ICSP is the fact that the chip starts to run the program in its memory as soon as the programmer is connected and if any of the outputs co-inside with the programming lines, you will get a clash that prevents the programmer recognising the chip.
 

THE SWITCHES  -  BUTTONS
The project has 4 tactile switches - UP  - DOWN - STORE - RUN
The first switch increments the alphabet and numbers.
The second switch decrements the letters and numbers.
The third switch allows you to store the letter showing on the screen.   
The fourth switch creates a RUNNING MESSAGE on the 8x8 DISPLAY.
To delete the message, press RUN before turning the project ON.
Turn the project OFF. The next time it is turned ON, the letter-counter has already been set to zero.
When writing a message, the last character must be a "space" to make the message easy to read.
When the project is turned off, and turned ON again, the message can be played on the display by pushing "Run."
You can add to the message by turning the project off then on again and adding letters.
Messages can be as long as 255 letters. The program does not detect when memory is full. You need to keep track.

PROGRAMMING THE CHIP
The chip comes pre-programmed when you buy the Running Display kit, however if you want to program your won chip or make modifications to the chip in the kit, you will need to add the In-Circuit Programming pins shown in the photo above.
The following circuit shows the connections of the 5 lines from the programming socket to the chip:

ADDING SUB-ROUTINES TO THE PROGRAM
The program is created by adding a few lines of code then testing the result.
It is saved with a new name so you can go back to previous developments, if something does not work.
Our system of "copy-and-paste" (from other programs and our Library of Subroutines) will help you develop each routine. The library will also answer many of your questions.
It consists of 3 pages:
A-E  E-P  P-Z
You will notice we added 3 LEDs to the lines on our development board to observe the clock, data and chip select lines.
By adding delays in the program you can see the number of clock pulses to confirm the information is being correctly transferred.
This was essential in getting the 8x8 Dot Matrix Module to display the characters as it requires a number of routines to set-up the MAX chip.
By using assembly-mode for creating a program, you can see exactly what happens at each stage of testing a new set of instructions and it eliminates a lot of frustration. You don't have to learn any high-level language and you are not left wondering how to write an instruction or what is actually happening. All the assembly instructions are provided in a list with their explanation.
See INSTRUCTION SET.
Our method is the simplest way to produce a program and is ideal for beginners. There are only about 35 instructions you need to remember to produce a program plus about 100 other instructions to "set-up" various conditions.
This is called "HAND CODING" and is suitable for a program up to about 1,000 instructions.
The 8x8 Module program is just over 350 instructions long, with a 250 byte table, so  you can see how much can be contained in this very small microcontroller.
A completely new set of characters can be shown on the display and this program can be access by pressing switch A before turning on the project. This will access the new program and you have just over 400 locations available for sub-routines and a table. 
You can add 6 more characters to the table to be within the 256 byte boundary or produce a completely new table.
Even though this will give you less than 150 bytes for programming, you can achieve a lot of effects because you will be able to CALL already-prepared sub-routines.
This project shows you how to connect a number of switches to a single port-line, how to drive a MAX chip, how to create running messages on the 8x8 dot matrix display and how to store data in the EEPROM.
All these are valuable "building-blocks" for the time when you want to design your own project.


THE FILES:

test-1.asm  .txt    .hex
test-2.asm  .txt    .hex
test-3.asm  .txt    .hex

8x8 Display.asm
8x8 Display.txt
8x8 Display.hex

Do not put the following program into Notebook 2. Use the .asm file above. The following program may have formatting problems and it may not compile properly. Compiling is done with MPASM to produce .hex file (as well as other helpful files).


;*******************************
;;8x8 Module.asm
;
;  23-6-2013 
;*******************************


	list	p=12F629
	radix	dec
	include	"p12f629.inc"
	
	errorlevel	-302	; Don't complain about 
         ;BANK 1 Registers during assembly

	__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  
;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************

       Cblock  20h
temp1		;used in delays
temp2		;used in delays
temp3           ;used in EEPROM data fetching 
temp4           ;used in EEPROM data fetching
temp5           ;used in EEPROM data fetching 
temp6           ;used in EEPROM data fetching
current         ;holds current EEPROM location
letters         ;letters holds the number of letters in EEPROM

serial      
address	    
_data  
jump		;table1 jump value  
columns		;for 6 columns   
Sw_Flag         ;detecting sw-press
eefile          ;total number of characters in EEPROM

       endc

;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
rp1		equ	0x06
rp0		equ	0x05
GPIO 		equ     0x05
			

status		equ	03h
option_reg	equ     81h


	; bits on GPIO
				
pin7	equ	0	;GP0  LED - flashes to indicate key number
pin6	equ	1	;GP1  Data to 8x8 Module
pin5	equ	2	;GP2  Chip Select
pin4	equ	3	;GP3  
pin3	equ	4	;GP4  Clock
pin2	equ	5	;GP5  4 switches   
 

		;bits
				
rp0		equ	5	;bit 5 of the status register


;****************************************************************
;Beginning of program
;****************************************************************
		org	0x00
		goto    SetUp
		
		
		
;****************************************************************
;Table
;****************************************************************
		
table1 addwf 02h,1 ;add W to program counter

      dt  7Eh,09h,09h,09h,7Eh,00h ;A 
      dt  7Fh,49h,49h,49h,36h,00h ;B 
      dt  3Eh,41h,41h,41h,22h,00h ;C 
      dt  7Fh,41h,41h,22h,1Ch,00h ;D
      dt  7Fh,49h,49h,41h,00h,00h ;E
      dt  7Fh,09h,09h,01h,00h,00h ;F
      dt  3Eh,41h,49h,49h,3Ah,00h ;G
      dt  7Fh,08h,08h,08h,7Fh,00h ;H 
      dt  7Fh,00h,00h,00h,00h,00h ;I
      dt  20h,40h,40h,3Fh,00h,00h ;J
      dt  7Fh,08h,14h,22h,41h,00h ;K
      dt  7Fh,40h,40h,40h,00h,00h ;L
      dt  7Fh,06h,18h,18h,06h,7Fh ;M
      dt  7Fh,02h,0Ch,18h,20h,7Fh ;N
      dt  3Eh,41h,41h,41h,3Eh,00h ;O
      dt  7Fh,09h,09h,09h,06h,00h ;P
      dt  1Eh,21h,31h,21h,5Eh,00h ;Q
      dt  7Fh,09h,19h,29h,46h,00h ;R
      dt  26h,49h,49h,49h,32h,00h ;S
      dt  01h,01h,7Fh,01h,01h,00h ;T
      dt  3Fh,40h,40h,40h,3Fh,00h ;U
      dt  0Fh,30h,40h,30h,0Fh,00h ;V
      dt  3Fh,40h,38h,40h,3Fh,00h ;W
      dt  63h,14h,08h,14h,63h,00h ;X
      dt  03h,0Ch,70h,0Ch,03h,00h ;Y
      dt  61h,51h,49h,45h,43h,00h ;Z
      dt  42h,7Fh,40h,00h,00h,00h ;1 
      dt  72h,49h,49h,49h,46h,00h ;2 
      dt  22h,41h,49h,49h,36h,00h ;3
      dt  18h,14h,12h,7Fh,10h,00h ;4
      dt  2Fh,49h,49h,49h,31h,00h ;5
      dt  3Eh,49h,49h,49h,32h,00h ;6
      dt  01h,71h,09h,05h,03h,00h ;7
      dt  36h,49h,49h,49h,36h,00h ;8 
      dt  26h,49h,49h,49h,3Eh,00h ;9 
      dt  00h,00h,00h,00h,00h,00h ;space (0D8h)

;****************************************************************
;Set Up
;****************************************************************
			
SetUp	bsf	status, rp0 	;Bank 1			
       	movlw	b'11001000'	;Set TRIS GP0,1,2,4,5 out  GP3 not used
	movwf	TRISIO	
	bcf	status, rp0	;bank 0
	movlw   07h         	;turn off Comparator ports
        movwf   CMCON       	;must be placed in bank 0  
	clrf 	GPIO       	;Clear GPIO of junk	
	clrf    jump
		
			
	clrf    40h             ;clear files for RUN
	clrf    41h
	clrf    42h 
	clrf    43h	
	clrf    44h
	clrf    45h
	clrf    46h 
	clrf    47h
		
		
	;Delete EEPROM Data - pressing "RUN" before switch-ON 
        ;deletes DATA by zeroing the number of letters in address 07h
		
	call	SwPressed   
	btfss   Sw_Flag,4   ;see if "Run" switch pressed
	goto    Main        ;not pressed
			
	movlw   7Fh
	bsf	status,rp0	;select bank1	
	movwf	eeadr	
	bcf	status,rp0	;select bank0		
	clrw    
	bsf	status,rp0	;select bank1	
	movwf	eedata	
	bcf		status,rp0	;select bank0
	call	write
		
		
		
	call	SwPressed   
	btfsc   Sw_Flag,4   ;see if "Run" switch not pressed
	goto    $-2
	goto    Main
		
		
;****************************************************************
;* Delays 			*
;****************************************************************
		
_6uS	goto	$+1		
	retlw   00


_12uS	goto	$+1
	goto	$+1
	goto	$+1
	goto	$+1				
	retlw 	00	
		
_1mS	nop
	decfsz 	temp1,f
        goto 	$-2			
	retlw 	00		
		
_10mS   movlw	.10
	movwf	temp2
	call    _1mS
	decfsz 	temp2,f			
	goto 	$-2
	retlw 	00	
		

_50mS	movlw	.50
	movwf	temp2
_50	nop
	decfsz 	temp1,f
	goto 	_50
	decfsz 	temp2,f
	goto 	_50	
	retlw 	00		
		
_100mS	movlw	.100
	movwf	temp2
_100	nop
	decfsz 	temp1,f
	goto 	_100
	decfsz 	temp2,f
	goto 	_100	
	retlw 	00	

		
		
		
;****************************************************************
;* Sub Routines 			*
;****************************************************************


	
		
Dec_Jump
  	decf    jump,f	
  	decf    jump,f	
  	decf    jump,f	
  	decf    jump,f	
  	decf    jump,f	
  	decf    jump,f	
  	retlw   00	
		
	;creates blank column 1,data for cols:234567 and blank col8
		
Display	
		
	movlw   0D8h    ;Look for end of table
	xorwf   Jump,w
	btfss   status,z ;zero bit will be set if the same
	goto    $+2
	clrf    jump    ;start at top of table
		
		
	clrf    address   
	incf    address,1  ;col1 = address 1
	clrf    _data
	call	Load
		
	movlw   6
        movwf   columns	   ;load counter for 6 columns
        incf    address,1			
	movf	Jump,w	   ;move jump value into w			
	call	table1     ;get jump value for table1
	movwf	_data	   ;load data from table1 into _data
	call	Load
	incf    jump,1     ;increment jump value for table1	
	decfsz  columns,f
	goto    $-7		

	incf    address,1    ;col8 = address 8
	clrf    _data
	call	Load
	retlw   00
		
		
			
		;send 16 bits to 8x8 Module
		;address 0 - 7 for columns
		;and data for each column
		
Load	bcf     gpio,2     ;open chip to receive address and data
	movlw   8
        movwf   serial	   ;load loop counter with 8 to transfer 8 bits
        movf	address,w
        movwf   temp3
        rlf     temp3,f  ;move bit through carry
	rlf     temp3,f  ;move bit to bit0 position
	btfss   temp3,0  ;these 3 instructions are very clever!!!!
	bcf     gpio,1     ;to send LOW data bit
	btfsc   temp3,0  ;see if the lowest bit is 0 or 1
	bsf     gpio,1     ;to send HIGH data bit
	rlf     temp3,f  ;put here to separate two gpio commands	
	bsf     gpio,4     ;clock HIGH 
	call    _12uS       ;must have small delay between bsf and bcf
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9
				
		
		;send 8 bits DATA 
		
	movlw   8
        movwf   serial	   ;load loop counter with 8 to transfer 8 bits
	rlf     _data,f    ;move bit 7 to bit 0 position
	rlf     _data,f 
	btfss   _data,0
	bcf     gpio,1     ;to send LOW data bit
	btfsc   _data,0    ;see if the lowest bit is 0 or 1
	bsf     gpio,1     ;to send HIGH data bit
	rlf     _data,f    ;put here to separate two gpio commands	
	bsf     gpio,4     ;clock HIGH 
	call    _12uS
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9
	bsf     gpio,2     ;close chip 
	retlw   00
	
		
		
		;create non-shutdown mode
		
noshutdown
	bcf     gpio,2     ;open chip to receive address and data
	movlw   8
        movwf   serial	 ;load loop counter with 8 to transfer 8 bits
        movlw   0Ch      ;0Ch accesses shutdown register
	movwf   address
	rlf     address,f  ;move bit 7 to bit 0 position
	rlf     address,f  
	btfss   address,0  ;these 3 instructions are very clever!!!!
	bcf     gpio,1     ;to send LOW data bit
	btfsc   address,0  ;see if the lowest bit is 0 or 1
	bsf     gpio,1     ;to send HIGH data bit
	rlf     address,f  ;put here to separate two gpio commands	
	bsf     gpio,4     ;clock HIGH 
	call    _12uS
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9
		
	movlw   8
        movwf   serial	 ;load loop counter with 8 to transfer 8 bits
        movlw   7        ;1  needed in data register for normal operation
	movwf   _data    ;
	rlf     _data,f  ;move bit 7 to bit 0 position
	rlf     _data,f 
	btfss   _data,0
	bcf     gpio,1   ;to send LOW data bit
	btfsc   _data,0  ;see if the lowest bit is 0 or 1
	bsf     gpio,1   ;to send HIGH data bit
	rlf     _data,f  ;put here to separate two gpio commands	
	bsf     gpio,4   ;clock HIGH 
	call    _12uS
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9		
	bsf     gpio,2    ;close chip 
	retlw   00
			
			
        ;Run - scrolls message across screen data held in 40h to 4Fh
			
Run	movlw	7Fh	        ;get number of letters from EEPROM 7Fh
	bsf	status,rp0	; select bank 1
	movwf	eeadr		; look at 7Fh
	bsf	eecon1,rd	; initiate the read
	movf	eedata,w	; put the read data into w 		
	bcf	status,rp0	;
	movwf   letters     ;letters holds the number of letters
		
RunAA	clrf    current     ;holds current EEPROM location
		
RunA	movf	current,w	;first location in EEPROM		
	bsf	status,rp0	; select bank 1
	movwf	eeadr		; look at 00h
	bsf	eecon1,rd	; initiate the read
	movf	eedata,w	; put the read data into w 		
	bcf	status,rp0	;
	movwf   temp5       ;temp5 holds table jump value
				
		
    	movf    current,w	;end of message?
	xorwf   letters,w		
	btfsc   status,z    ;zero bit will be set if the same
	goto    RunAA       ;go to start of message
		
	movlw   6
	movwf   temp6       ;6 columns for each letter
		
RunB    movf    temp5,w     ;put jump-value into w
        call    table1
        movwf   48h         ;put column-value into ghost column        
        call    Shift       ;create "running effect"
        movlw   40h
        movwf   4           ;fsr for indirect addressing  		
	clrf    address     ;col1 = address 1        
    	movlw   8
        movwf   columns	   ;load counter for 8 columns
        incf    address,f  ;for column 1		
	movf	0,w	       ;move data from file 40h into w
	movwf	_data	   ;move data to _data file
	call	Load
	incf    4,f 	    ;increment FSR to look at file 41h
	decfsz  columns,f
	goto    $-6	
	call	noshutdown  ;tell8x8 to illuminate display 
	call    Scancols	;tell 8x8 to scan 8 columns	
	call	_100mS
	call	_100mS	
	incf    temp5,f    ;jump value for each letter
	decfsz  temp6,f    ;loop counter for 6 columns
    	goto    RunB
    	incf    current,f	
    	goto    RunA 	
    		
    		    		
        	
		;scan all columns
		
Scancols

	bcf     gpio,2    ;open chip to receive address and data
	movlw   8
        movwf   serial	  ;load loop counter with 8 to transfer 8 bits
        movlw   0Bh       ;0Bh accesses scan-limit register
	movwf   temp4
	rlf     temp4,f  ;move bit 7 to bit 0 position
	rlf     temp4,f  
	btfss   temp4,0  ;these 3 instructions are very clever!!!!
	bcf     gpio,1     ;to send LOW data bit
	btfsc   temp4,0  ;see if the lowest bit is 0 or 1
	bsf     gpio,1     ;to send HIGH data bit
	rlf     temp4,f  ;put here to separate two gpio commands	
	bsf     gpio,4     ;clock HIGH 
	call    _12uS
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9
		
	movlw   8
        movwf   serial	 ;load loop counter with 8 to transfer 8 bits
        movlw   7        ;7 is needed to scan 8 columns
	movwf   temp4  
	rlf     temp4,1  ;move bit 7 to bit 0 position
	rlf     temp4,1 
	btfss   temp4,0
	bcf     gpio,1   ;to send LOW data bit
	btfsc   temp4,0  ;see if the lowest bit is 0 or 1
	bsf     gpio,1   ;to send HIGH data bit
	rlf     temp4,f  ;put here to separate two gpio commands	
	bsf     gpio,4     ;clock HIGH 
	call    _12uS
	bcf     gpio,4     ;clock LOW to lock-in data bit	
	decfsz  serial,f
	goto    $-9			
	bsf     gpio,2    ;close chip 
	retlw   00
		
		
        ;shift columns to the LEFT also removes blank columns
        
Shift   movf    41h,w       ;shift columns to the left
        movwf   40h
        movf    42h,w
        movwf   41h
        movf    43h,w
        movwf   42h
        movf    44h,w
        movwf   43h
        movf    45h,w
        movwf   44h
        movf    46h,w
        movwf   45h
	movf    47h,w
        movwf   46h
	movf    48h,w
        movwf   47h
        retlw   00		
		
		
		
		;SwPressed sets bit 4, 3, 2, 1 in switch-flag
		
SwPressed

	clrf    Sw_Flag		;clear the switch flag
	bsf	status, rp0 	;Bank 1	 (see if switch is pressed)
	bcf 	TRISIO,5	;clear bit GPIO,5 as output to charge cap.
	bcf	status, rp0	;bank 0
	bsf	gpio,5		;make pin2 HIGH to charge cap. 
	call	_10mS           ;charge cap
	bsf	status, rp0 	;Bank 1			
       	bsf 	TRISIO,5	;set TRIS GP0,5 to detect discharged cap
	call	_1mS            ;create a delay to see if no sw pressed
	btfss   gpio,5
	goto    $+3
	bsf     Sw_Flag,7       ;no switch pressed
        retlw	00				
			      	
	bsf	status, rp0 	;Bank 1	    	
	bcf 	TRISIO,5	;clear bit GPIO,5 as output to charge cap.
	bcf	status, rp0	;bank 0
	bsf	gpio,5		;make pin2 HIGH to charge cap. 
	call	_10mS            ;charge cap
	bsf	status, rp0 	;Bank 1			
       	bsf 	TRISIO,5	;set TRIS GP0,5 to detect discharged cap
	bcf	status, rp0	;bank 0			
	call    _12uS
	call    _12uS
	call    _12uS
	call	_6uS			
	btfsc   gpio,5
	goto    $+3
	bsf     Sw_Flag,4	
	retlw	00	
	call    _12uS		
	btfsc   gpio,5
	goto    $+3
	bsf     Sw_Flag,3
	retlw	00
	call    _12uS
	call	_6uS		
	btfsc   gpio,5
	goto    $+3
	bsf     Sw_Flag,2	
	retlw	00			
	call    _12uS		
	btfss   gpio,5
	bsf     Sw_Flag,1
	retlw	00	
		
		
	
		
	;Sw3 = STORE  - stores address of character (table1) into EEPROM 
	;eefile - total number of characters in EEPROM 217Fh 
	;eedata will be jump value
	;eeadr will be zero at start-up
					
Store	        
                ;look at 7Fh in EEPROM
	movlw	7Fh	;get location in EEPROM for storing next value
	
	bsf	status,rp0	; select bank 1
	movwf	eeadr		; look at 7Fh
	bsf	eecon1,rd	; initiate the read
	movf	eedata,w	; put the read data into w
	bcf	status,rp0	;			
	movwf	eefile		;and move to eefile 
		


	movf	eefile,w    ;starts at 0 for EEPROM 1st location
	bsf	status,rp0	;select bank1	
	movwf	eeadr	
	bcf	status,rp0	;select bank0
	call    Dec_Jump		
	movf    jump,w      ;dec jump 6 times to get start of letter 
	bsf	status,rp0	;select bank1	
	movwf	eedata	
	bcf	status,rp0	;select bank0
	call	write
		
	incf    eefile,f    ;increment to store in next EEPROM location
		
	movlw    7Fh   ;store in EEPROM last location
	bsf	status,rp0	;select bank1	
	movwf	eeadr	
	bcf	status,rp0	;select bank0	
	movf    eefile,w    ;store the number of letters 
	bsf	status,rp0	;select bank1	
	movwf	eedata	
	bcf	status,rp0	;select bank0
	call	write
					
	retlw   00
	
		
					
					
write	bsf	status,rp0	;select bank1	
	bsf		eecon1,wren	;enable write		
	movlw	55h 		;unlock codes
	movwf	eecon2
	movlw	0aah
	movwf	eecon2
	bsf	eecon1,wr	;write begins
	bcf	status,rp0	;select bank0		
writeA	btfss	pir1,eeif	;wait for write to complete
	goto	writeA
	bcf	pir1,eeif
	bsf	status,rp0	;select bank1
	bcf	eecon1,wren	;disable other writes
	bcf	status,rp0	;select bank0
	retlw	00				
						

;****************************************************************
;* Main 							*
;****************************************************************

Main	
	clrf    Sw_Flag		;clear the switch flag
	call    Display     ;creates blank col1,
                            ;data for cols:234567 and blank col8
		
	call	noshutdown
	call    Scancols
	clrf    Sw_Flag     ;go to here for looping
	call	SwPressed		
	btfss   Sw_Flag,7  ;see if no switch pressed
	goto    $+2        ;sw pressed
	goto    $-4       ;no sw pressed
	btfss   Sw_Flag,1  ;see if "Forward" switch pressed
	goto    $+7        ;see if other switch pressed
Main1	call    Display       
	clrf    Sw_Flag
	call	SwPressed		
	btfss   Sw_Flag,7  ;see if no switch pressed
	goto    $-3
	goto    $-.12
	btfss   Sw_Flag,2  ;see if "Back" switch pressed
	goto    $+9
	call    Dec_Jump
	call    Dec_Jump	
	movlw   0FAh  
	xorwf   Jump,w
	btfss   status,z   ;zero bit will be set if the same
	goto    $+3		
	movlw   0D2h       ;address of last letter
	movwf   jump       ;go to bottom of table
	btfss   Sw_Flag,3  ;see if "Store" switch pressed
	goto    $+2
	call    Store
	btfss   Sw_Flag,4  ;see if "Run" switch pressed		
	goto    Main1     
	call    Run
		
		
		
		
;****************************************************************
;*EEPROM     Values to burn into EEPROM				*
;****************************************************************
				
				
	org	2100h	;org 2100h means the next byte of data will 
                        ;>be at location 00 in EEPROM	
		
	de	00h	;de means Data EEPROM
				
		
	org	217Fh
		
	de	00h	;newly burnt chip:  
                         ;00 for number of char in EEPROM
							
		
	END
	

CASCADING THE 8x8
The next thing you can do with the 8x8 is cascade the modules to make it easier to read the running message.
We have developed a program to run 3 modules, however it will run 1,2 or 3 modules without any modification.
See the next page for the program: 
CASCADING THE 8x8


ooo00000ooo
 

22-6-2013