Hey,
i want to read values from an MCP3564. This is my sketch for my teensy 4.1.
#include <Arduino.h>
#include <SPI.h>
#define DEBUG false //DEBUG MODE
#define MCLK_INTERNAL true //true for internal clock, false for external
#define MCLK_FREQ 20000000 //disabled if MCLK_INTERNAL is true
#define OSR_SETTING OSR_128 //oversampling ratio
//Unchanging Definitions, Objects, and Variables
enum OSR : uint8_t {
OSR_32 = 0x00,
OSR_64 = 0x01,
OSR_128 = 0x02,
OSR_256 = 0x03,
OSR_512 = 0x04,
OSR_1024 = 0x05,
OSR_2048 = 0x06,
OSR_4096 = 0x07,
OSR_8192 = 0x08,
OSR_16384 = 0x09,
OSR_20480 = 0x0A,
OSR_24576 = 0x0B,
OSR_40960 = 0x0C,
OSR_49152 = 0x0D,
OSR_81920 = 0x0E,
OSR_98304 = 0x0F
};
enum Channel : uint8_t {
CH_0 = 0x00,
CH_1 = 0x01,
CH_2 = 0x02,
CH_3 = 0x03,
CH_4 = 0x04,
CH_5 = 0x05,
CH_6 = 0x06,
CH_7 = 0x07,
A_Vdd = 0x08,
A_GND = 0x09,
REFIN_pos = 0x0B,
REFIN_neg = 0x0C,
TEMP_P = 0x0D,
TEMP_M = 0x0E,
VCM = 0x0F
};
constexpr uint32_t SPI_Speed = 20000000;
constexpr uint8_t DEV_ADDR = 0b01000000;
constexpr uint8_t ADC_REG_ADDR = 0b00000000;
constexpr uint8_t CONFIG0_ADDR = 0b00000100;
constexpr uint8_t CONFIG1_ADDR = 0b00001000;
constexpr uint8_t CONFIG2_ADDR = 0b00001100;
constexpr uint8_t CONFIG3_ADDR = 0b00010000;
constexpr uint8_t IRQ_ADDR = 0b00010100;
constexpr uint8_t MUX_ADDR = 0b00011000;
constexpr uint8_t SCAN_ADDR = 0b00011100;
constexpr uint8_t TIMER_ADDR = 0b00100000;
constexpr uint8_t OFFSETCAL_ADDR = 0b00100100;
constexpr uint8_t GAINCAL_ADDR = 0b00101000;
constexpr uint8_t LOCK_ADDR = 0b00110100;
constexpr uint8_t FAST_CMD = 0b00000000;
constexpr uint8_t CONV = 0b00101000;
constexpr uint8_t STBY = 0b00101100;
constexpr uint8_t RESET = 0b00111000;
constexpr uint8_t READ = 0b00000001;
constexpr uint8_t INC_WRITE = 0b00000010;
constexpr uint8_t INC_READ = 0b00000011;
constexpr uint8_t CONFIG0 = 0b11000010 | (MCLK_INTERNAL <<5);
constexpr uint8_t CONFIG1 = 0b00000000 | (OSR_SETTING <<2);
constexpr uint8_t CONFIG2 = 0b10001011; //Contains Gain
constexpr uint8_t CONFIG3 = 0b11000000; //Contains Mode
constexpr uint8_t IRQ = 0b01110110; //contains IRQ stuff
constexpr uint8_t MUX = 0b00000001; //contains channel selection MUX_VIN+ = CH0 vs MUX_VIN- = CH1
constexpr uint32_t SCAN = 0b000000000000000100000000; //contains scan stuff 24 bits
constexpr uint32_t TIMER = 0; //contains timer stuff 24 bits
constexpr uint8_t OFFSETCAL = 0; //contains offset stuff
constexpr uint8_t GAINCAL = 0; //contains gain calibration stuff
constexpr uint8_t RESERVED = 0; //contains dummy for reserved registers
constexpr uint8_t LOCK = 0b10100101; //contains Write Access Password
#define SPI_CS_PIN 10
#define SPI_MOSI_PIN 11
#define SPI_MISO_PIN 12
#define SPI_SCK_PIN 13
#define ADC_INT_PIN 3
#define ADC_MCLK_PIN 2
//Function Prototypes
void ADC_Init();
void readADC();
void setup() {
Serial.begin(115200);
delay(2000);
ADC_Init();
startADC();
pinMode(ADC_INT_PIN, INPUT);
}
void ADC_Init() {
SPI.begin();
SPI.usingInterrupt(digitalPinToInterrupt(ADC_INT_PIN));
pinMode(SPI_CS_PIN, OUTPUT);
delay(100);
SPI.beginTransaction(SPISettings(SPI_Speed, MSBFIRST, SPI_MODE0));
digitalWriteFast(SPI_CS_PIN, LOW);
delayNanoseconds(100);
SPI.transfer(DEV_ADDR | RESET | FAST_CMD);
digitalWriteFast(SPI_CS_PIN, HIGH);
delayMicroseconds(1);
SPI.endTransaction();
delay(1);
Serial.println("Reset erfolgreich durchgeführt ...");
SPI.beginTransaction(SPISettings(SPI_Speed, MSBFIRST, SPI_MODE0));
digitalWriteFast(SPI_CS_PIN, LOW);
delayNanoseconds(500);
SPI.transfer(DEV_ADDR | CONFIG0_ADDR | INC_WRITE);
SPI.transfer(CONFIG0);
SPI.transfer(CONFIG1);
SPI.transfer(CONFIG2);
SPI.transfer(CONFIG3);
SPI.transfer(IRQ);
SPI.transfer(MUX);
SPI.transfer(0xFF&(SCAN>>16));
SPI.transfer(0xFF&(SCAN>>8));
SPI.transfer(0xFF&(SCAN));
digitalWriteFast(SPI_CS_PIN, HIGH);
delayMicroseconds(1);
SPI.endTransaction();
delay(1);
}
void startADC() {
SPI.beginTransaction(SPISettings(SPI_Speed, MSBFIRST, SPI_MODE0));
digitalWriteFast(SPI_CS_PIN, LOW);
SPI.transfer(DEV_ADDR | CONV | FAST_CMD);
digitalWriteFast(SPI_CS_PIN, HIGH);
SPI.endTransaction();
}
void readADC() {
SPI.beginTransaction(SPISettings(SPI_Speed, MSBFIRST, SPI_MODE0));
digitalWriteFast(SPI_CS_PIN, LOW);
SPI.transfer(DEV_ADDR | ADC_REG_ADDR | READ);
uint32_t ADC_DATA = SPI.transfer32(0);
digitalWriteFast(SPI_CS_PIN, HIGH);
SPI.endTransaction();
Serial.print("ADC raw: ");
Serial.println(ADC_DATA);
delay(500);
}
void loop() {
readADC();
}
So at first, i initialize the ADC (reset and write registers so it is in the configuration i want it to be, after that i fire a fast command to get the adc in conversion mode). After that, i want to read the values. But when i run my sketch, i only get zeros. I have an accelerometer (ADXL1002) connected to my ADC. So i should see the Vref (coming from an external voltage regulator) instead of zeros. Is there a mistake in my SPI communication process or anywhere else? Is there a possibility to check if the SPI commands where successfull? I didn't even manage to get a register red out.