Arduino Uno with Texas Instrument AMC7834 via SPI

Hi all, I am pretty newby in Arduino but for an RF project I would like to interface the Arduino Uno to the https://www.ti.com/product/AMC7834. I would like to start reading Device ID only but the fact that I have to read 24 bits (3 bytes) is confusing me. Here below the code, if someone can help.

#include <SPI.h>

//pin 13 SCLK
//pin 12 MISO on Arduino side, SDO on TXS
//pin 11 MOSI on Arduino side, SDI on TXS

const int csPin = 10;  // Pin di selezione dello slave (CS)

void setup() {

  Serial.begin(9600);
  
  pinMode(csPin, OUTPUT);
  digitalWrite(csPin, HIGH);  // Deseleziona l'SPI slave

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2); // Imposta la velocità SPI
  SPI.setDataMode(SPI_MODE0); // Imposta il modo di SPI
}

void loop() {

  byte devID = readdevID();
  Serial.print("Device ID: ");
  Serial.println(devID);

  delay(1000);
}

byte readdevID() {
  
  digitalWrite(csPin, LOW);

  // First byte is to read the register (0x80 per leggere)
  byte command = 0x80 | 0x04;
  SPI.transfer(command);

  // Leggi i dati (2 byte)
  byte msb = SPI.transfer(0x000); // Ottieni il byte più significativo
  byte lsb = SPI.transfer(0x000); // Ottieni il byte a meno significativo

  digitalWrite(csPin, HIGH);

  byte devID = msb | lsb;
  return devID;
}

The AMC7834 datasheet specifies that the device ID is a 24-bit register, meaning it consists of three bytes. Your code needs some modification in this regard:

#include <SPI.h>

// Pin connections to the SPI interface
const int csPin = 10;  // Chip Select (CS) pin

void setup() {
  Serial.begin(9600);
  
  pinMode(csPin, OUTPUT);
  digitalWrite(csPin, HIGH);  // Deselect the SPI slave

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2); // Set SPI speed
  SPI.setDataMode(SPI_MODE0); // Set SPI mode
}

void loop() {
  // Read and print the device ID
  uint32_t devID = readDeviceID();
  Serial.print("Device ID: 0x");
  Serial.println(devID, HEX);  // Print in hexadecimal format
  delay(1000);
}

uint32_t readDeviceID() {
  digitalWrite(csPin, LOW);  // Select the SPI slave

  // Send command to read the device ID register
  byte command = 0x80 | 0x04; // Assuming 0x04 is the correct register address
  SPI.transfer(command);

  // Read the three bytes from the device ID register
  byte msb = SPI.transfer(0x00);    // Most significant byte
  byte mid = SPI.transfer(0x00);    // Middle byte
  byte lsb = SPI.transfer(0x00);    // Least significant byte

  digitalWrite(csPin, HIGH);  // Deselect the SPI slave

  // Combine the three bytes into a single 24-bit value
  uint32_t devID = ((uint32_t)msb << 16) | ((uint32_t)mid << 8) | lsb;
  return devID;
}

@stem88

Your main problem is incompatible logic levels. The 7834 I/O are 3.3V and the Uno is 5V.
So first thing is to buy a level translator.

read 24 bits (3 bytes)

No, the ID is only 16 bits. All registers are only 16 bits (2 bytes)

Don't use setClockDiviseo or setDataMode
Use instead

SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0))

https://docs.arduino.cc/language-reference/en/functions/communication/SPI/SPISettings/

Also add a 10us delay after you bring CS low and before you bring it high

1 Like

You are misinterpreting. Transfers are 24 bits composed of an 8-bit register address and a 16-bit register value.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.