FFT
Joined: 07 Jul 2010 Posts: 92
|
AD5627 Dual Channel I2C DAC Driver |
Posted: Mon Jan 10, 2022 3:12 am |
|
|
Tested AD5627 Dual Channel I2C DAC Driver
Code: | /*
AD5627 I2C DAC Driver
AD5627R/AD5647R/AD5667R, AD5627/AD5667
Tested on AD5627BCPZ-REEL7
Dual channel I2C DAC
*/
/*
Pin connections:
ADDR -> GND
LDAC -> GND
EP -> GND
CLR -> VDD
VREFIN -> VDD
In this case VDD is 5V
*/
/*
Address is 0x0F when ADDR->GND (datasheet)
We shift-left the address by 1 bit
LSB bit determines the operation is write or read R/W
LSB = 0 is write
LSB = 1 is read
0x0F << 1 is 0x1E (write)
0x0F << 1 | 0x01 is 0x1F (read)
*/
#define DAC_ADDRESS 0x1E // write address
#define DAC_REF_VOLTAGE 5000.0 // mV
#define DAC_RESOLUTION 4096.0 // 12 bits DAC
/*
Hardware I2C selected
*/
#use i2c(MASTER, I2C1, FORCE_HW, NOINIT)
/*
Commands
*/
#define DAC_A 0x18 // Command: DAC A one block write
#define DAC_B 0x19 // Command: DAC B one block write
/* All commands
#define _CA1 0x18; // Command: DAC A one block write
#define _CB1 0x19; // Command: DAC B one block write
#define _CA2 0x58; // Command: DAC A multiple block write
#define _CB2 0x59; // Command: DAC B multiple block write
#define _CA3 0x00; // Command: DAC A using LDAC to update.
#define _CB3 0x01; // Command: DAC B using LDAC to update.
*/
/*
Initialize I2C
*/
#define DAC_init() i2c_init(100000) // supports up to 400000
/*
Voltage set on channel in millivolts
param ch : command, used as channel DAC_A or DAC_B
param v : voltage in millivolts, 0...5000 mV
returns false on error
*/
bool DAC_set(int8 ch, int16 v)
{
int8 ack; // 0: ack - else nack or collusion
int16 out;
int8 H, L;
out = (int16)((float)v * DAC_RESOLUTION / DAC_REF_VOLTAGE);
if(out > 4095) // limit the value to 12 bits
{
out = 4095;
}
/*
4095 -> 0xFFF is maximum value where generates 5000.0 mV on DAC output
When sending 0xFFF over I2C;
H holds the 0xFF (whole byte)
L holds the 0xF left aligned (a nibble)
so L holds left aligned 4 bits only
*/
H = out >> 4;
L = (out << 4) & 0xF0;
i2c_start();
ack = i2c_write(DAC_ADDRESS); // Device address
if(0 == ack) // check ack to send data to avoid errors
{
i2c_write(ch); // CMD
i2c_write(H);
i2c_write(L);
}
i2c_stop();
return 0 == ack;
}
/*
Sawtooth signal generation test on both channels
*/
void DAC_test() // Call this function in a loop
{
static int16 q = 0; // [mV]
q++;
if(q > 5000) // [mV]
q = 0;
DAC_set(DAC_A, q);
DAC_set(DAC_B, q);
}
/*
Pseudo main function
*/
void main()
{
DAC_init();
for(;;)
{
DAC_test();
}
}
|
|
|