Hello all
For once, this thread is not an ask for help
For my autodidactic learning of electronics, the last step I took was understanding and using the SPI protocol. For this I used an arduino Uno and a max7219 chip (with 4 7-segment displays). Of course, the goal was not to use the LedControl library, but do everything on my own.
Doing this, I ran in several issues which sometimes took me a long time to understand and solve. Thus I decided to write down this post mortem, in order to help learning people out. I will explain the problems I ran into, and how to solve them, providing tips about important things to understand.
I am aware that for most of you that's easy peasy stuff, but hope it will help someday.
I - the SPI protocol
Before we start coding, a few words about the SPI protocol. This protocol is really easy to understand, there are 3 wires (in our case). One for the clock signal, one for the data (data is read by the target chip at each clock edge, and one for chip select. But there a few subtleties!
But, for the rest, no text explaining it. I had to check the timing diagram to find the answers.
If we look closely, we see that data is needed to be ready at clock rising edge. Also, we see that D15 (data 15) bit is read first. This means we need to be in MSB first mode.
For my own implementation, I use SPI with clock speed of 1MHz (but this works @10MHz), an MSBFirst bit order and clock mode 2 (data is spit out at falling edge, see diagram)
II - Arduino's SPI
The Arduino Uno board contains a couple of traps not to fall into when doing SPI:
Yellow = clock
Pink = data
Blue = chip select.
(One can notice that the clock stops as soon as the data is sent. This allows us to set the CS pin high fast enough without bothering - the 7219 datasheet states that the CS pin must be set high before the next rising edge of the clock)
The decoder says here :
0x0C00 => shutdown (I did a mistake, the register shall be set to 1 in order to exit shutdown mode)
0x0F01 => test mode on
0x0A0F => intensity set to maximum
0x0B00 => maximum number of 7 segment displays set to 1
III - The Max 7219
The Max 7219 also contains some traps which made me lose some time too:
I think this is all! I hope this thread will help you if you encountered one or more of these problems. I wish the tutorial I read had all of this information in it.
For once, this thread is not an ask for help
For my autodidactic learning of electronics, the last step I took was understanding and using the SPI protocol. For this I used an arduino Uno and a max7219 chip (with 4 7-segment displays). Of course, the goal was not to use the LedControl library, but do everything on my own.
Doing this, I ran in several issues which sometimes took me a long time to understand and solve. Thus I decided to write down this post mortem, in order to help learning people out. I will explain the problems I ran into, and how to solve them, providing tips about important things to understand.
I am aware that for most of you that's easy peasy stuff, but hope it will help someday.
I - the SPI protocol
Before we start coding, a few words about the SPI protocol. This protocol is really easy to understand, there are 3 wires (in our case). One for the clock signal, one for the data (data is read by the target chip at each clock edge, and one for chip select. But there a few subtleties!
- The order in which data is sent can be either MSB first and LSB first;
- The data can be set to be read at the rising or the falling edge of the clock;
- The clock speed must be configured, too.
But, for the rest, no text explaining it. I had to check the timing diagram to find the answers.
If we look closely, we see that data is needed to be ready at clock rising edge. Also, we see that D15 (data 15) bit is read first. This means we need to be in MSB first mode.
For my own implementation, I use SPI with clock speed of 1MHz (but this works @10MHz), an MSBFirst bit order and clock mode 2 (data is spit out at falling edge, see diagram)
II - Arduino's SPI
The Arduino Uno board contains a couple of traps not to fall into when doing SPI:
- The built-in LED accessed via the pin LED_BUILTIN is connected to the same pin as the SPI clock (PIN_SPI_SCK). You can not use the LED while SPI is writing or reading data or you may have problems;
- The pins used by the SPI bus are PIN_SPI_SCK, PIN_SPI_MOSI and PIN_SPI_MISO. You can use whatever pin you want for the chip select, among them the pin PIN_SPI_SS:
- you have to manually set the used pins as output / input (for MISO), the SPI class does not do this for you;
- you will have to set the chip select pin LOW and HIGH yourself, the SPI class does not do this for you.
Yellow = clock
Pink = data
Blue = chip select.
(One can notice that the clock stops as soon as the data is sent. This allows us to set the CS pin high fast enough without bothering - the 7219 datasheet states that the CS pin must be set high before the next rising edge of the clock)
The decoder says here :
0x0C00 => shutdown (I did a mistake, the register shall be set to 1 in order to exit shutdown mode)
0x0F01 => test mode on
0x0A0F => intensity set to maximum
0x0B00 => maximum number of 7 segment displays set to 1
III - The Max 7219
The Max 7219 also contains some traps which made me lose some time too:
- The 7219 seems to have an over current protection mode: when too much current is drained, the chips enter in shutdown mode automatically. At first, I used a 9.6kΩ resistor as suggested in a tutorial, but this was too much. Each time I reset the circuit, one digit flashed and nothing was displayed after. Increasing the resistance to more than 60kΩ fixed this for me.
- The 7219 test mode always uses the maximum intensity for the displays, whatever value you set. It is written but well hidden in the datasheet. So don't worry if you don't see your intensity changes when in test mode.
I think this is all! I hope this thread will help you if you encountered one or more of these problems. I wish the tutorial I read had all of this information in it.