Interfacing LED driver MAX6954 using SPI


Perhaps some of you already worked with the SPI interface and could help me here?

This is my situation:

I want to use the arduino nano to control an LED driver from Maxim (MAX6954), which supports the SPI protocol. In my first step I tried to light up one LED with the help of the display test register. This should turn on all LEDs. But I saw no reaction!

So I made a step back and wanted to find out if my code communicates with the MAX at all. Therefore in the code below I am trying to read a special register and send the result back over the serial interface to the serial monitor. But the result I was getting confused me again, because in every loop another result was printed. some of them I could identify, but I think I made a fundamental mistake in the SPI communication.

I would be grateful for every hint you could give me!

Here is my code with the help of

#define SLAVESELECT 10//ss
#define DATAOUT 11//MOSI DataIn bei max
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck

// define max6954 registers
byte max6954_reg_noop        = 0x00;
byte max6954_reg_decodeMode  = 0x01;
byte max6954_reg_global_intensity   = 0x02;
byte max6954_reg_scanLimit   = 0x03;
byte max6954_reg_configuration = 0x04;
byte max6954_reg_displayTest = 0x07;
byte max6954_reg_digitType = 0x0c;  // 16 segment or 7 segment (default)

byte clr;

void setup()

  pinMode(DATAIN, INPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device 

  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR); // 01000000 v 00010000 = 01010000

char spi_transfer(volatile char data)
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  return SPDR;                    // return the received byte

byte setRegister(byte address, byte value)
  digitalWrite(SLAVESELECT, LOW);
  digitalWrite(SLAVESELECT, HIGH);

byte readRegister(byte address)
  int data;
  address = address | B10000000; // set the read bit
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer((char)0x03);           // just some dummy data
  digitalWrite(SLAVESELECT, HIGH);
  digitalWrite(SLAVESELECT, LOW);
  data = spi_transfer((char)0x05);    // just some dummy data
  digitalWrite(SLAVESELECT, HIGH);
  return data;

void loop()
  Serial.print('-', BYTE);

This is the result I am getting over the serial monitor:


datasheet of the MAX6954
Page 8 and 9 told me how to read a device register.

Apropos of not very much:

char spi_transfer(volatile char data)
  SPDR = data;

That "volatile" looks pretty redundant. ::)

Thank you for your reply.

I declared the variable volatile, since it is also used in the Arduino SPI tutorial, but it also seemed reasonable for me, because this function is working with data that is changed by the SPI from the Arduino, and it is changing data by shifting without my control.

I have already tried to remove this keyword but there is no change, but this could also be just one mistake in a row.

Do you think volatile could make some troubles?

because this function is working with data that is changed by the SPI

In this case, it is not, since the value of "data" is immediately written to SPDR.

I don't think removing "volatile" will help though; it's simply redundant.

After some research I found out that there was a problem with the pin13 on the NG, because the same is used for the clock signal and the LEDpin with a build in resistor.

Does anyone know if this problem still exists with the Arduino nano and if so how to deal with it?