Pages: [1]   Go Down
Author Topic: SPI-transfer trouble Using SPIEEPROM as example  (Read 5930 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I need a SPI-connection between the arduino and a DDS-chip. The DDS chip generates a signal with an adjustable frequency and phase. The frequency and phase is determined by a frequency or phase word which will be send through the SPI-connection. So I'm trying to write something easy to start, but I can't get it too work. I've read the datasheet and SPCR is OK. I thought that the compiler would recognize the function spi_transfer, which he don't. Since I absolutely have no clue, I wonder how I could send the byte DATA_H_MSB2 through the SPI connection.

Ty for reading.

 My code:
Code:
#define DATAOUT 11
#define SPICLOCK 13//sck
#define FSYNC 12 //LOW=readmode for the DDS

byte DATA_H_MSB2;

void setup(){
   DATA_H_MSB2=00100011;
    
   Serial.begin(9600);
   digitalWrite(FSYNC, HIGH);
   pinMode(DATAOUT, OUTPUT);
   pinMode(SPICLOCK,OUTPUT);
   pinMode(FSYNC, OUTPUT);
  
   SPCR = (1<<SPE) |(1<<MSTR) | (1<<CPHA);  
   delay(300);
  
   digitalWrite(FSYNC, LOW);
   spi_transfer(DATA_H_MSB2);
   digitalWrite(FSYNC,HIGH);
   delay(100);
  
}

void loop(){}

Playground link for the SPIEEPROMhttp://www.arduino.cc/en/Tutorial/SPIEEPROM

Here's the code:

Code:
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
}

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
}

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);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
  Serial.print('h',BYTE);
  Serial.print('i',BYTE);
  Serial.print('\n',BYTE);//debug
  delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  if (address == 128)
    address = 0;
  delay(500); //pause for readability
}
« Last Edit: December 14, 2010, 07:06:47 am by panteraa » Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 525
Posts: 26554
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I used SPI with another device, it seemed pretty straight forward.

You need this in the code before void setup()
#include <SPI.h>
// SPI uses hardware Chip Select (SS in this example) vs having device address

and this to actually send out data:

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip
  // I was sending 2 bytes out, an address,
  SPI.transfer(SHUTDOWN_ADDRESS);    
  // and some data
  SPI.transfer(0x00);      
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

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

I'm interested in this as well.  It looks like there are some SPI setups to take care of. e.g. Clock divider, bit order, etc.  Does anyone know what it defaults to if the bits in the SPCR register are not set up?

Thanks,
-Ryan
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 525
Posts: 26554
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's the code for writing to a MAX7221, compare to the data sheet. Nothing was changed from whatever the defaults are.
The only pin you need to define is the SS pin to be used, the rest are taken care of by the library (and are not changeable in the ATMega hardware).

Code:
 // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI  <--- Need this here before any SPI writes?

  //  MAX7221: write shutdown register  
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  // Serial.println("shutdown register, dislays off");

http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf
« Last Edit: January 23, 2011, 07:19:29 pm by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

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

It looks like the MAX7219 wants to transfer data bits on the rising edge of the clock cycles.  If I'm using a AD9833, the data sheet indicates the data transfer needs to happen on the falling edges.  I guess I need to set the CPOL bit in the SPCR register.   Not sure if there is an easy way to do this other than a brute force write to the register?

Logged

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

After some digging... It looks like this command might do the trick:

 SPI.setDataMode(SPI_MODE2);
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 525
Posts: 26554
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep, looks like there are several options you can manipulate here:

http://arduino.cc/en/Reference/SPI
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Pages: [1]   Go Up
Jump to: