PDA

View Full Version : Shorter Subroutines for MAX7219



exelanoz
- 15th March 2007, 05:37
Hello!

I have cascaded together (6x) Max7219 display drivers. I have no problems driving them with my 16F628A, but the code I am using is a little space hungry. It is simple, it works, but I am sure there are other alternatives, but I am not seeing it.

I was wondering, can anyone assist me with making my subroutine codes a little shorter for the MAX7219 without altering the timing for SHIFT_OUT and LOAD High sequence?

To send data to other Max7219, you have to insert No-Op after the intended data. If you want to send to the third Max7219, you send out the 16bits and then follow with 2 No-Op 16bits, which are just all ‘0’

Have a look at my subroutines. I have set up a Transfer Label for each chip, with the required No-Ops in place…but the problem is it is space hungry on the 16F628A.


Transfer:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer1:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
ShiftOut Dta,Clk,msbfirst,[0,0] ' Send No-Op Command
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer2:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
ShiftOut Dta,Clk,msbfirst,[0,0] ' Send 2 sets of No-Op Commands
ShiftOut Dta,Clk,msbfirst,[0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer3:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer4:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer5:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
ShiftOut Dta,Clk,msbfirst,[0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Thinking I can make it shorter, I used the FOR…NEXT commands in combination with the IF…THEN,……it compiled well, wrote it on the chip……..BUT This method totally stuffed up the correct timing of pulling up the load.
So while the 16F628A was working with the FOR…NEXTcommands…the LOAD timing sequence had already lapsed and data was lost. I was thinking of further adding another 2 Max7219 for a total of eight, but I won't have any code space left for other functions...:-(

Apart from putting on the code for the 16F648 (More space) is there any other possibilities or ideas to make this subroutine a little more compact?

Many thanks

HenrikOlsson
- 15th March 2007, 06:29
Hi,
Here's a quick idea. I dont know if it works timingwise but it may be worth a try. I know you said you tried a FOR-NEXT loop but not how so here goes:


T Var Byte
i var byte

'Set T to 0 for first chip, 1 for second chip an so on then GOSUB transfer.

Transfer:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data

If T = 0 then Return 'Send to first chip so we're done

For i = 1 to T
ShiftOut Dta,Clk,1,[0,0] ' Send No-Op Command
Next i

High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return


It compiles to about 27% of the original in size and if it works it shouldn't matter how many 7219's you add the code is still the same.

/Henrik Olsson.

rhino
- 15th March 2007, 08:15
I'd tweek Henrik's example just a bit...

If T = 0 then
GOTO HERE 'Jump over "No-Op Commands"
EndIF

For i = 1 to T
ShiftOut Dta,Clk,1,[0,0] ' Send No-Op Command
Next i

HERE:
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return

exelanoz
- 15th March 2007, 12:02
Thanks Henrik & Rhino
Really appreciate your quick responses.
Henrik, - that is exactly the same thing I tried, but didn't work.
The MAX7219 seems very sensitive to timing, it is capable up to 10Mhz serial communication which is quite fast.
I believe that when you SHIFTOUT the 16bits it immediately expects to see a high load.
While the PIC is executing the FOR NEXT IF THEN statements the MAX7219 is still waiting for the load, but gives up.
Using this code the display puts out strange characters.
With my really basic code it seems fine and I can display anything.

Few other notes. The PIC16F628 is running @20Mhz
I have been diligently reading the data sheet over and over for the MAX7219 and other sources on the net and I have come up with a few basic ideas.

1) I will try to reduce the clock to 4Mhz to help serial communication. I don't need highspeed communication for this project.
2) I can also add a define statement at the top to further reduce the Clock

I was reading that if you slow down the communication it is less prone to error and it is better to use over longer wires.

It's late here, time to sleep...I'll get into it tomorrow when I get home and post results.

Hehe...little note... I also need to point out that where T=0, your IF THEN statement does not pull up the LOAD after SHIFTOUT. But easily fixed using the IF THEN ELSE ENDIF statements. Rhino I'll try your idea over a slower clock

Time to sleep, goodnight boys and girls! Many thanks.

Hi,
Here's a quick idea. I dont know if it works timingwise but it may be worth a try. I know you said you tried a FOR-NEXT loop but not how so here goes:


T Var Byte
i var byte

'Set T to 0 for first chip, 1 for second chip an so on then GOSUB transfer.

Transfer:
ShiftOut Dta,Clk,msbfirst,[Register,R_Val] ' Shift Out the Register first, then the data

If T = 0 then Return 'Send to first chip so we're done

For i = 1 to T
ShiftOut Dta,Clk,1,[0,0] ' Send No-Op Command
Next i

High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return


It compiles to about 27% of the original in size and if it works it shouldn't matter how many 7219's you add the code is still the same.

/Henrik Olsson.

HenrikOlsson
- 15th March 2007, 13:23
Hi,


Hehe...little note... I also need to point out that where T=0, your IF THEN statement does not pull up the LOAD after SHIFTOUT.

Aaargh....no, of course not....sorry about that.

What if you replace the multiple SHIFTOUT commands in the subs with just one, like this:


Transfer:
ShiftOut Dta,Clk,1,[Register,R_Val]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer1:
ShiftOut Dta,Clk,1,[Register,R_Val,0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer2:
ShiftOut Dta,Clk,1,[Register,R_Val,0,0,0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer3:
ShiftOut Dta,Clk,1,[Register,R_Val,0,0,0,0,0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer4:
ShiftOut Dta,Clk,1,[Register,R_Val,0,0,0,0,0,0,0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

Transfer5:
ShiftOut Dta,Clk,1,[Register,R_Val,0,0,0,0,0,0,0,0,0,0]
High Load ' Data is now latched in and displayed
@ Nop
Low Load ' Disable the MAX7219
Return ' Exit from Subroutine

It compiles smaller than the original but I have no way of testing here so I'm just throwing ideas your way. Hopefully we'll come up with a way that works (and saves some bytes).

/Henrik Olsson.

exelanoz
- 16th March 2007, 11:35
Hi Henry!

ShiftOut Dta,Clk,1,[Register,R_Val,0,0,0,0,0,0]

Now why didn't I think of that? It looks so obvious, I must be blind...

I do have some good news. I came home from work and playing around
I slowed the the Xtal to 4Mhz and using your original suggestions, it does work! but not at 20Mhz. Strange, isn't it? It is quite compact in code size though.

I have added tantalum capacitors on the MAX7219 Vdd + Vss and added a low pass filter on the Clk, Din, Load lines (560ohm + 220pF)...but I still suspect that by the time it reaches the last few chips the lines are noisy...and that is maybe the reason they are not responding as they should.
At 4Mhz all is fine, I can control any Chip, - at 20Mhz - - no good, corrupt data. Strangely my original long piece will work at any speed...I'm stumped on this one.

I've attached a JPG of one display module in action. I made 3 boards each, with 3 MAX7219 on each board. Single sided pc boards, but there is a possibility of interference on the boards. The board was home made and not professionally designed, so the routing of the tracks may also be part of the problem. I tried to keep the DC supply away from the rest and to use few links, but it is not easy. So for now, it will stay @ 4Mhz and later if I can work out whether this is a pic timing issue or just the lines are noisy I may attempt at going up to 20Mhz.

It is late again...time to sleep.

Many Thanks

AP