|
|
View previous topic :: View next topic |
Author |
Message |
andibaciu
Joined: 06 Feb 2006 Posts: 6
|
MAX5821 some problems ... help |
Posted: Thu Aug 09, 2007 11:21 pm |
|
|
I want to communicate with 1 MAX5821 - i2c communication, 10bit DAC, voltage output and i have some problems .... If somebody could help me i'll appreciate.
for MAX5821 i write a driver:
Code: |
// MAX5821M.c -- Dual 10 bit Voltage Output DAC
// MAX5821 commands
#define MAX5821_CMD_LOAD_DAC_A_UPDATE 0x00
#define MAX5821_CMD_LOAD_DAC_B_UPDATE 0x10
#define MAX5821_CMD_LOAD_DAC_A_NOUPDATE 0x40
#define MAX5821_CMD_LOAD_DAC_B_NOUPDATE 0x50
#define MAX5821_CMD_UPDATE_ALL_LOAD_DAC_A 0x80
#define MAX5821_CMD_UPDATE_ALL_LOAD_DAC_B 0x90
#define MAX5821_CMD_LOAD_ALL_UPDATE_ALL 0xC0
#define MAX5821_CMD_LOAD_ALL_NOUPDATE 0xD0
#define MAX5821_CMD_UPDATE_ALL_NO_D9_D6 0xE0 //no more OR opperation
#define MAX5821_CMD_POWER_DOWN_MODE 0xF0 //no more OR opperation
#define MAX5821_CMD_READ_DAC_A 0xF1 //no more OR opperation
#define MAX5821_CMD_READ_DAC_B 0xF2 //no more OR opperation
#define MAX5821_POWER_UP 0x00 //Start device.
#define MAX5821_POWER_DOWN_MODE_1 0x01 //high impedance; output floating
#define MAX5821_POWER_DOWN_MODE_2 0x02 //pulled to GND by 1Kohm
#define MAX5821_POWER_DOWN_MODE_3 0x03 //pulled to GND by 100Kohm
#define MAX5821_DEVICE_ADDRESS_1 0xB0 //MAX5821M with ADD connected to GND
#define MAX5821_DEVICE_ADDRESS_2 0xB2 //MAX5821M with ADD connected to Vdd
//======================================
void MAX5821_init(int address,int dac, int power_mode)
{
int mode=0;
i2c_start();
i2c_write(address);
i2c_write(MAX5821_CMD_POWER_DOWN_MODE);
if(dac==1)
mode=power_mode|0x04;
if(dac==2)
mode=power_mode|0x08;
i2c_write(mode);
i2c_stop();
}
void MAX5821_cmd_dac(int address,int command,int16 value)
{
int val1,val2;
int16 temp;
temp=value;
val1=temp>>6;
val1=command|val1;
temp=value;
val2=temp;
val2=val2<<2;
i2c_start();
i2c_write(address);
i2c_write(val1);
i2c_write(val2);
i2c_stop();
}
void MAX5821_write_dac(int address,int dac,int16 value)
{
int val1,val2;
int16 temp;
temp=value;
temp=shift_right(temp,6,0);
val1=make8(temp,0);
val1=val1&0x0F;
if(dac==1)
val1=MAX5821_CMD_LOAD_DAC_A_UPDATE|val1;
if(dac==2)
val1=MAX5821_CMD_LOAD_DAC_B_UPDATE|val1;
temp=value;
temp=shift_left(temp,2,0);
val2=make8(temp,0);
val2=val2&0xFC;
i2c_start();
i2c_write(address);
i2c_write(val1);
i2c_write(val2);
i2c_stop();
}
int MAX5821_read_dac_power_mode(int address,int dac)
{
int val1,val2;
i2c_start();
i2c_write(address);
if(dac==1)
i2c_write(MAX5821_CMD_READ_DAC_A);
if(dac==2)
i2c_write(MAX5821_CMD_READ_DAC_B);
i2c_start();
i2c_write(address+1);
val1=i2c_read();
val2=i2c_read(0);
i2c_stop();
val1=val1<<2;
val1=val1>>6;
return val1;
}
int16 MAX5821_read_dac_value(int address,int dac)
{
int val1,val2;
int16 value;
i2c_start();
i2c_write(address);
if(dac==1)
i2c_write(MAX5821_CMD_READ_DAC_A);
if(dac==2)
i2c_write(MAX5821_CMD_READ_DAC_B);
i2c_start();
i2c_write(address+1);
val1=i2c_read();
val2=i2c_read(0);
i2c_stop();
val1=val1<<4;
val1=val1>>4;
value=make16(val1,val2);
value=value>>2;
return value;
}
|
and to call this driver i write a little program where i put:
Code: |
MAX5821_init(MAX5821_DEVICE_ADDRESS_1,1,MAX5821_POWER_UP);
MAX5821_init(MAX5821_DEVICE_ADDRESS_1,2,MAX5821_POWER_UP);
delay_ms(10);
MAX5821_write_dac(MAX5821_DEVICE_ADDRESS_1,2,0);
MAX5821_write_dac(MAX5821_DEVICE_ADDRESS_1,1,0);
|
when i start with this code all things are ok ... but when i try to set some value in DAC registers:
Code: |
MAX5821_write_dac(MAX5821_DEVICE_ADDRESS_1,2,xxx);
MAX5821_write_dac(MAX5821_DEVICE_ADDRESS_1,1,xxx);
|
my program crash and stop.
Could somebody help me to solve this problem ? or maybe somebody already have a good driver for MAX5821and want to share.
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 10, 2007 12:03 am |
|
|
Quote: | void MAX5821_write_dac(int address,int dac,int16 value)
{
int val1,val2;
int16 temp;
temp=value;
temp=shift_right(temp,6,0);
val1=make8(temp,0);
val1=val1&0x0F;
if(dac==1)
val1=MAX5821_CMD_LOAD_DAC_A_UPDATE|val1;
if(dac==2)
val1=MAX5821_CMD_LOAD_DAC_B_UPDATE|val1;
temp=value;
temp=shift_left(temp,2,0);
val2=make8(temp,0);
val2=val2&0xFC;
i2c_start();
i2c_write(address);
i2c_write(val1);
i2c_write(val2);
i2c_stop();
} |
The two lines with the shift functions have problems.
1. The first parameter must be the address of a variable or an array.
'temp' is an int16, so if you want pass the address of temp, you
must do it like this:
2. The middle parameter is the number of bytes that are to be involved
in the shift operation. 'temp' is only 2 bytes, so the middle parameter
should be 2, at most. It can't be 6. The shift functions only do a
shift of 1 bit position per call. This is in the manual.
3. The shift functions only return a value of 1 or 0. They don't return
the complete shifted variable.
I didn't look at the program in detail. There might be other problems. |
|
|
andibaciu
Joined: 06 Feb 2006 Posts: 6
|
|
Posted: Fri Aug 10, 2007 12:45 am |
|
|
Thanks PCM programmer ...
I think I made a big confusion between shift_right and >> and between shift_left and <<.
so .. in my case my function must be:
Code: |
void MAX5821_write_dac(int address,int dac,int16 value)
{
int val1,val2;
int16 temp;
temp=value;
temp=temp>>6;
val1=make8(temp,0);
val1=val1&0x0F;
if(dac==1)
val1=MAX5821_CMD_LOAD_DAC_A_UPDATE|val1;
if(dac==2)
val1=MAX5821_CMD_LOAD_DAC_B_UPDATE|val1;
temp=value;
temp=temp<<2;
val2=make8(temp,0);
val2=val2&0xFC;
i2c_start();
i2c_write(address);
i2c_write(val1);
i2c_write(val2);
i2c_stop();
}
|
so... in this case I must make a new test ....
I'll keep you inform about my problem ... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|