Pages: [1]   Go Down
Author Topic: Interfacing LED driver MAX6954 using SPI  (Read 1248 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi!

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 http://www.arduino.cc/en/Tutorial/SPIEEPROM:
Code:
#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()
{
  
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  
  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
  clr=SPSR;
  clr=SPDR;
  delay(10);
}

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);
  spi_transfer((char)address);
  spi_transfer((char)value);
  digitalWrite(SLAVESELECT, HIGH);
  delay(10);
}

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

void loop()
{
  Serial.print((readRegister(max6954_reg_displayTest)),DEC);
  //setRegister(max6954_reg_displayTest,0x01);
  Serial.print('-', BYTE);
  delay(200);
}

This is the result I am getting over the serial monitor:
Code:
255-5-0-0-5-255-255-0-0-0-7-255-255-0-0-0-255-255-5-0-0-5-255-0-0-0-255-255-0-0-0-255-255-5-0-0-255-255-0-

datasheet of the MAX6954
http://www.datasheetcatalog.org/datasheet/maxim/MAX6954.pdf
Page 8 and 9 told me how to read a device register.
« Last Edit: May 15, 2009, 06:54:07 am by savage » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 241
Posts: 24480
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Apropos of not very much:
Code:
char spi_transfer(volatile char data)
{
  SPDR = data;      

That "volatile" looks pretty redundant.  :smiley
« Last Edit: May 15, 2009, 07:03:48 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 241
Posts: 24480
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
« Last Edit: May 15, 2009, 09:48:05 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Pages: [1]   Go Up
Jump to: