Yet another MAX7219 question

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure if I am posting this in the correct forum or not, but I have a question.

I am working on a project that uses several MAX7219 chips to drive some 7 segment LED displays.

I have it working using an Arduino Uno and the LedControl library, and I am trying to somewhat port it over to "pure C".

I have searched the forum and have looked at several examples, and feel reasonably comfortable so far with how to communicate with one MAX7219.

What I'm not real clear about is how to address more than one MAX7219. I don't see anything clear regarding that in the datasheet other than the "Serial-Addressing Modes" paragraph where it states the following.

Quote:
Data at DIN is propagated through the shift register and appears at DOUT 16.5 clock cycles later. Data is clocked out on the falling
edge of CLK.

I am using the following:

atmega328p
stk500 programmer
Linux Fedora 19 (64 bit)
avr-gcc
Eclipse IDE
avrdude

One other thing to note, I am not using the SPI port/pins on the atmega328p.

Can any of you gurus give me an example or point me in the right direction to address say MAX7219 chip #3?

Here is what I have written so far. Keep in mind, I'm still learning so my code is probably not the best. Also keep in mind that this is in no way complete. Any pointers or corrections are certainly welcome.

#ifndef MAX7219_H_
#define MAX7219_H_

#include 
#include 


// Register Address Map
#define A_NOOP	0x00
#define A_DIG0	0x01
#define A_DIG1	0x02
#define A_DIG2	0x03
#define A_DIG3	0x04
#define A_DIG4	0x05
#define A_DIG5	0x06
#define A_DIG6	0x07
#define A_DIG7	0x08
#define A_DECODE	0x09
#define A_INTENSITY	0x0A
#define A_SCAN_LIMIT	0x0B
#define A_SHUTDOWN	0x0C
#define A_TEST_MODE	0x0F


// Character table for displaying digits
const uint8_t charTable[16] = {
		0b01111110,0b00110000,0b01101101,0b01111001,0b00110011,0b01011011,0b01011111,0b01110000,
	    0b01111111,0b01111011,0b01110111,0b00011111,0b00001101,0b00111101,0b01001111,0b01000111 };


// SPI pin definitions
#define SPI_DATA (1<<PORTB3)
#define SPI_CLK (1<<PORTB2)
#define SPI_LOAD (1<<PORTB1)
#define SPI_PORT PORTB


// Set up SPI
void initSpi() {
	DDRB |= (1<<DDB1);
	SPI_PORT |= SPI_LOAD;
}


#endif /* MAX7219_H_ */
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

40 views and no response? I was hoping that someone would be able to at least point me in the right direction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

to address say MAX7219 chip #3?

If this chip is like many seral/parallel, the short answer to your question is "you can't". You need to send a complete data stream and clock it through your chain of chips. then tell your chain to "latch".

I suppose you could send dummy data through the chain and have separate LOAD signals for each chip in the chain at the expense of more AVR pins. The data transfer time would be the same, though, so why burn more pins?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The MAX7219 is effectively a regular SPI device.
So you can always put multiple MAX7219s on the SPI bus and select one at a time.

The "LOAD" pin is the active-low "Chip-Select". Keep it high when inactive.

The regular way of operating several MAX7219s is to have a single CS (Load) pin.
Just chain one to the next. i.e. one 7219 takes a 16-bit instruction. Five MAX7219s need CS_low, 80 bits of data, CS_high. (which latches the data)

You can send data to the 4th 7219 by sending 3 NOP_instruction + your_instruction + NOP.

In practice, chaining is the normal method for 1-8 7219s.
If you are using more than 8 7219s, you possibly want to use separate chains.

David.

p.s. I bet you wondered why the 7219 had a NOP instruction !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
You can send data to the 4th 7219 by sending 3 NOP_instruction + your_instruction + NOP.
Depends which one is the 4th :)

If the 1st is closest to the processor and the 4th one is furthest away but one, then it would be 1 NOP_instruction (ends up in the 5th) + your_instruction (for the 4th) + 3 NOP_instructions (end up in the closest 3)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, thank you all very much. I get it now. I knew it was something simple that I was over looking.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
You can send data to the 4th 7219 by sending 3 NOP_instruction + your_instruction + NOP.

There is no need to waste time and code with serial NOPs.
Simple send 3 16bit words to set the 3 MAX7219 simultaneously.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't follow. Let's say that you have 5 7219s and you want to write '7' to the 3rd digit in the 4th 7219. e.g.

Old: 1111111122222222333333334444444455555555
New: 1111111122222222333333334474444455555555

You can either send NOP, NOP, NOP, 0x0307, NOP
Or you could send: 0x0301,0x0302,0x0303,0x0307,0x0305

If you just repeated 0x0307,0x0307,0x0307,0x0307,0x0307 you would get:

Old: 1111111122222222333333334444444455555555
New: 1171111122722222337333334474444455755555

Untested. I just typed from memory. You will need to look up the exact command format.

As Martin noted, it depends how you chain the 7219s.
I am happier with big-endian. So I would write MSB first into the RHS 7219, so I would be able to think in from left to right. A bit like how you enter digits into your pocket calculator.

David.