PIC Assembly Tutorial 7 – Graphics on an 8×8 LED Matrix.

Now first things first, I don’t recommend making your own 8×8 LED matrix out of individual LED’s (because it is very time consuming!) I do recommend purchasing yourself one (or more) of the 8×8 Bi-colour LED matrix displays off ebay. they are incredibly cheap and are very easy to use.
I buy mine from sure electronics. make sure you check out their website.

Also, if you are interested in buying in bulk from sure electronics, make sure you email them because when I made the 8×8 game system kit, i ordered 50 of the 8×8 matrix’s and all up it cost me $50 including postage!

And now into the lesson…

The 8×8 LED matrix display’s are (believe it or not) connected in a matrix. This means that you don’t just have 2 connections for each led (of which there are 64 LED’s) instead, the LED’s are connected in such a way that we can light up every LED in the matrix and to do this, we only require 16 connections (rather than 128 doing it individually)
Here is a diagram showing you how the LED’s are connected together to form the matrix.

matrix_pinout

 

 

You will notice the image on the left has 64 LED’s connected in an 8×8 LED matrix. There are 8 Columns where the cathodes are all connected together and also 8 Rows where the anodes are all connected together. The image on the right will be used to demonstrate how we get the matrix to do what we want.

Le’s start out nice and simple. What if we wanted to turn on just the top right LED. Well. we would need to ground the right most cathode and then connect the top Anode to our power supply (+5v) through a resistor, just like this next picture:
top_right_led

 

You may also have guessed that if we connect +5v to the top row of anodes then EVERY anode up the top will have +5v connected to it. The reason that only the top right LED turns on is because we have only connected ground to the right most column of cathodes. We need the combination of +5v AND ground in order to complete the circuit to turn on whatever LED or LED’s that we want.

What about if we wanted to turn on an entire Column of LED’s? We’ll you would connect your matrix as follows:
led_column

 

Or perhaps an entire row?
led_row

 

Now, having finished the introduction, this is the circuit that we are going to be working with when experimenting with our matrix.
8x8_led_schematic

 

We are using a helper chip in this excercise – the 7442 ( 1 of 10 decoder) this is going to help us with ‘scanning’ the cathodes. Let’s have a look at how the 7442 works:

7442

 

This is a 16 pin chip, of course it has a +5v connection and ground in order to power it up. It also has four inputs namely A, B, C and D. lastly, it has 10 outputs – 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. It is quite a simple chip to work with. The outputs will vary depending on what combination of 1’s and 0’s are on the inputs. All outputs of this chip will be a logic high EXCEPT for one. That one will depend on the input. Here is a chart showing you what the output will be for all combinations of inputs:

7442_table

 

 

So anyway, having a look at the 7442 output, we can make any one of the outputs low (or pretty much connect it to ground) by giving a certain combination on the input. If we wanted output 0 to be low then we would input 0000 OR if we wanted output 6 to be low then we would input 0110 etc…
We only require 8 (of the 10) outputs from this chip therefor we use these 8 combinations on the input:

000
001
010
011
100
101
110
111

This means that we don’t need to use the fourth input line (D) so that is why I have connected it straight to ground and only the first three inputs (A, B and C) are connected to the microcontroller so we can control them. So this means that we will have any one of these eight combinations on the inputs:

0000
0001
0010
0011
0100
0101
0110
0111

So hopefully you can see that by using this chip, we can ‘Activate’ one column of Cathodes at a time by connecting one column at a time to ground (logic 0) and to do this it only required 3 I/O lines from the microcontroller – whereas without the 7442, we would have required 8 I/O lines and we only have seven to spare (because PORTB is used for the anodes and PORTA pin 5 cannot be an output)

So now we are working towards drawing a picture on the screen. Here is what we want to draw:
8x8_face

 

Now you may very well be asking “That’s a pretty picture, BUT how do we draw a picture with all of those LED’s lit up at once if we can only ‘activate’ one column at a time?”
We’ll I am glad that you asked that question! there is a little bit of a trick to it.
What you see on the 8×8 matrix is a face. BUT not all columns are on at the same time – infact only one column is drawn at any one time but we ‘scan’ through the columns so fast, that to the human eye it just looks like one steady image.

You can download the source code at the bottom of this page.

PLEASE NOTE: I HAVE NOT TESTED THE SOURCECODE! IT SHOULD WORK FINE THOUGH. I WILL GET AROUND TO TESTING IT WHEN I BUILD THE CIRCUIT.

In this first piece of sourcecode we are ‘drawing’ the face on the screen BUT the rate at which we scan the display is so slow that our brains can’t put all of the eight columns together to make one complete image. So what you will infact see on your display is something like this:
8x8_anim_slow

 

This animation hopefully will help you understand what is going on.
We first ‘activate’ the right most column by putting 000 on the 7442 input. This means that the first output is low and all other outputs are high. Now at the same time that we have activated the right most column – we also output 8-bits of data to PORTB. All LED anodes are connected to PORTB but only the right most column will do anything because that is the only column with a complete circuit connecting us to ground. This is how the beauty of multiplexing works.

So we want to output the first column of our face, in this case it is 00111100. so if you have a look at the animation, when the right most column is activated, we have 00111100 on PORTB and so those particular LED’s light up. We hold that there for just a moment and then we turn off the LED’s and then move onto the next column to the left by sending 001 to the 7442. We then output another 8-bits to PORTB but only the second column will light up with anything because this column is the only one connected to ground.  Then we repeat the process of activating the next column in sequence, and then sending the correct 8-bits that corresponds to that column in the picture to PORTB. once we have drawn the complete image, we just loop back to the begging and do it all again!

So now that you can see how one complete image is drawn, go back to the sourcecode and decrease the delay time. I.E it is set to 255, try changing it to 100 and then 50, 20, 10, 05, 02 etc… What happens?
We’ll the lower your delay routine, the faster it will scan through drawining each column. You will notice that you will start to see the complete picture but it will be quick flickery. Then you will eventually get to a point where there is no longer any flicker – what is the delay set to in order to achieve this?

Homework:
1. I have purposely designed the sourcecode to be very basic and not efficient. Can you redesign the sourcode so that it does the same thing but in a more efficent manner? E.G use the incf instruction to increment PORTA instead of doing it by movlw.

2. Design your own piece of code so that you have one LED lit – starting at the top left and then the led will do laps around the outside edge of the display. I.E it goes from top left to top right, then down, then left again and then back up to the starting position.

 

God Bless.

Downloads

smiley_face_8x8_matrix.asm_