/*
Test sketch for the MCP3304 and MCP4822
Both are bit-banged to get them working.
In this demo:
DAC channel A will count up from 0v to 4.096V
DAC Channel B will mirror what is being read on ADC Channel 0
Arduino MCP3304 MCP4822
*/
#define ADC_CS 10 // ADC chip-select
#define DAC_CS 9 // DAC chip-select
#define ADC_MOSI 11 // ADC_MOSI
#define ADC_MISO 12 // ADC_MISO
#define SPI_CLK 13 // Clock
#define MCP4822_DAC_A_BUFFERED_GAIN_1X_NON_SHDN 0x70 // DAC A, Buffered, Gain 1x, Output power control
#define MCP4822_DAC_A_BUFFERED_GAIN_2X_NON_SHDN 0x50 // DAC A, Buffered, Gain 2x, Output power control
#define MCP4822_DAC_A_NON_BUFFERED_GAIN_1X_NON_SHDN 0x30 // DAC A, Non buffered, Gain 1x, Output power control
#define MCP4822_DAC_A_NON_BUFFERED_GAIN_2X_NON_SHDN 0x10 // DAC A, Non buffered, Gain 2x, Output power control
#define MCP4822_DAC_B_BUFFERED_GAIN_1X_NON_SHDN 0xF0 // DAC B, Buffered, Gain 1x, Output power control
#define MCP4822_DAC_B_BUFFERED_GAIN_2X_NON_SHDN 0xD0 // DAC B, Buffered, Gain 2x, Output power control
#define MCP4822_DAC_B_NON_BUFFERED_GAIN_1X_NON_SHDN 0xB0 // DAC B, Non buffered, Gain 1x, Output power control
#define MCP4822_DAC_B_NON_BUFFERED_GAIN_2X_NON_SHDN 0x90 // DAC B, Non buffered, Gain 2x, Output power control
int test2=0;
long test3=0;
void pulse_MCP_clock(void)
{
digitalWrite(SPI_CLK, LOW); delayMicroseconds(50);
digitalWrite(SPI_CLK, HIGH); delayMicroseconds(50);
}
long read_MCP(int channel)
{
long value=0;
signed int x=0;
digitalWrite(ADC_CS, LOW);
digitalWrite(DAC_CS, HIGH);
delayMicroseconds(50);
digitalWrite(ADC_CS, LOW);
delayMicroseconds(50);
digitalWrite(ADC_MOSI, HIGH); //start pulse
pulse_MCP_clock();
digitalWrite(ADC_MOSI, HIGH); //single mode
pulse_MCP_clock();
for(x=2; x>=0; --x)
{
if(bitRead(channel,x))
{
digitalWrite(ADC_MOSI, HIGH);
}
else
{
digitalWrite(ADC_MOSI, LOW);
}
pulse_MCP_clock();
}
digitalWrite(ADC_MOSI, LOW);//put low throughout
for(x=1;x<=3;++x)
{
//blank, Null, and sign bit (always 0 in single mode)
pulse_MCP_clock();
}
//now get twelve bits
for(x=11; x>=0; --x)
{
pulse_MCP_clock();
if (digitalRead(ADC_MISO))
{
bitSet(value,x);
}
else
{
bitClear(value,x);
}
}
digitalWrite(ADC_CS, HIGH);
digitalWrite(DAC_CS, HIGH);
return value;
}
void init_ADC(void)
{
digitalWrite(SPI_CLK,HIGH); //clock
digitalWrite(ADC_MISO, LOW); //output -- supposed to be float but not sure how to do this on Arduino
digitalWrite(ADC_MOSI, HIGH); //input
digitalWrite(ADC_CS, HIGH);
delayMicroseconds(50);
digitalWrite(ADC_CS, LOW);
delayMicroseconds(50);
digitalWrite(ADC_CS, HIGH);
digitalWrite(DAC_CS, HIGH);
}
int get_adc_avg(int channel)
{
long tempx = 0;
byte ax = 0;
for (ax=0;ax<10;ax++)
{
tempx+=read_MCP(channel);
}
tempx/=10;
return (tempx);
}
void mcp4822_init() {
digitalWrite(DAC_CS,HIGH);
digitalWrite(SPI_CLK, LOW);
digitalWrite(ADC_CS,HIGH);
digitalWrite(ADC_MOSI, LOW);
}
void mcp4822_write(byte control,int data) {
byte i;
int tempx=0x00;
tempx = data|(control<<8);
digitalWrite(ADC_CS,HIGH);
delayMicroseconds(10);
digitalWrite(SPI_CLK,LOW);
delayMicroseconds(10);
digitalWrite(DAC_CS,LOW);
delayMicroseconds(10);
digitalWrite(ADC_MOSI,LOW);
for(i=16;i>0;--i)
{
digitalWrite(SPI_CLK,LOW);
digitalWrite(ADC_MOSI,bitRead(tempx,i-1));
digitalWrite(SPI_CLK,HIGH);
}
digitalWrite(DAC_CS,HIGH);
delayMicroseconds(10);
}
void setup() {
//set pin modes
pinMode(ADC_CS, OUTPUT);
pinMode(DAC_CS, OUTPUT);
pinMode(ADC_MOSI, OUTPUT);
pinMode(ADC_MISO, INPUT);
pinMode(SPI_CLK, OUTPUT);
init_ADC();
mcp4822_init();
digitalWrite(ADC_CS, HIGH);
digitalWrite(DAC_CS, HIGH);
Serial.begin(115200);
Serial.print("Hello2"); // Just to show the serial is working
}
void loop() {
int tempx2 = 0;
if (test3++>0xFFF) test3=0;
tempx2 = read_MCP(0);
mcp4822_write(MCP4822_DAC_A_NON_BUFFERED_GAIN_2X_NON_SHDN, test3);
mcp4822_write(MCP4822_DAC_B_NON_BUFFERED_GAIN_2X_NON_SHDN, tempx2);
delay(10);
}