|
|
View previous topic :: View next topic |
Author |
Message |
Markdem
Joined: 24 Jun 2005 Posts: 206
|
MCP3421 |
Posted: Fri Feb 02, 2007 7:17 pm |
|
|
Hi All, i am tring to write a driver for the new MCP3421 ADC.
I have connected it to a known working I2C bus, and am just tring to read the ADC result for now. I am tring the following code;
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT
#use delay(clock=48000000)
#use i2c(MASTER, SDA=PIN_B0, SCL=PIN_B1)
#include <HDM64GS12.c>
#include <graphics.c>
#define LCDBacklightOUT PIN_E0
char lcddata[30];
int byte0, byte1, byte2;
void main()
{
delay_ms(10);
output_high(lcdbacklightout);
glcd_init(ON);
sprintf(lcddata,"Ready");
glcd_text57(1,1,lcddata,1,on);
while(1)
{
i2c_start();
i2c_write(0xD1); //send address of MCP3421
delay_us(10);
byte0 = i2c_read(1); //read first byte and send ack
byte1 = i2c_read(1); //read second byte and send ack
byte2 = i2c_read(0); //read last byte and dont ack
i2c_stop();
sprintf(lcddata,"%u, %u, %u", byte0, byte1, byte2);
glcd_text57(1,10,lcddata,1,on);
delay_ms(1000);
glcd_rect(0, 10, 128, 20, no, off);
}
}
|
All i get back formt he MCP3421 is all 1s. If I disconnect it, i will still get 1s. It looks like i am not talking to it, but i cant see why. I have read the datasheet meany time, but i cant work out what i am doing wrong.
Thanks,
Mark |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Fri Feb 02, 2007 8:44 pm |
|
|
Are you getting 0xFFFFFF or 0x03FFFF (18 ones or 24 ones)?
What reading do you expect? At what potential are Vin(+) and Vin(-)? Table 4-2 in the datasheet says that all 1s corresponds to the input of -1 LSB. A tiny bias could cause that.
I2C could be miss-wired at MCP3421 itself. Can you talk to other I2C devices, while MCP3421 is still connected to the bus?
Wrong slave address. You could get a chip with an address other than default 0xD0, although it's unlikely.
Fried chip is the last on the list. |
|
|
Markdem
Joined: 24 Jun 2005 Posts: 206
|
|
Posted: Fri Feb 02, 2007 9:50 pm |
|
|
Thanks Kender, I am getting 0xFFFFFF, so 24 ones.
I have +1v accross the inputs, so i should not be getting all ones.
I can still read from a DS1307 clock, so i think the bus is OK.
Does the code look OK? Is there any timing issues that i am not thinking about?
Thanks, Mark |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Fri Feb 02, 2007 10:12 pm |
|
|
The code looks fine. According to the fig 5-2 in the datasheet, you should be able to read the 3 value bytes back-to-back. Timing could be an issue. The datasheet says (5.5) that the high speed mode needs to be activated with a separate command. Try to reduce f_SCL to 100kHz. May be adding delays between the I2C bytes could help too.
By the way, is MCP3421 getting enough power? |
|
|
Markdem
Joined: 24 Jun 2005 Posts: 206
|
|
Posted: Sat Feb 03, 2007 6:40 pm |
|
|
OK, i have now added delays between the reads, but it did not help. I have checked that the MCP is getting 5v, and it is OK.
I am not tring to you high speed mode, but i have tried forcing the bus slow, but that also did nothing.
I wish i had a scope so i could check if the MCP is sending ack back
I think i will try to change the MCP to see if it is maybe damaged.
Thanks
Mark |
|
|
ohararp
Joined: 10 May 2009 Posts: 1
|
|
Posted: Sun May 10, 2009 2:15 pm |
|
|
Mark, I am reviving this thread because I am wondering if you ever had any luck getting the 18-bit mode to work with the MCP3421. I can get it working in 16-bit mode but not 18. Any help/update would be appreciated. |
|
|
servera
Joined: 15 Dec 2010 Posts: 2
|
Working MCP3421 code |
Posted: Wed Dec 15, 2010 8:21 am |
|
|
Code: | //
// This code setup the MCP3421 in 18bits mode and then enters
// a loop that continually reads and display the value read on
// a 2x20 character LCD.
//
// Use it as a starting point for your own code
//
#include <18F4520.h>
#include <PIC18F4520_registers.h>
#include <stdlib.h>
#include <string.h>
#USE DELAY( clock = 20000000 )
//
// Fuses
//
#FUSES HS // High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOFCMEN // Fail-safe clock monitor disabled
#FUSES NOIESO // Internal External Switch Over mode disabled
#FUSES PUT // Power Up Timer
#FUSES NOBROWNOUT // No brownout reset
#FUSES NOWDT // No Watch Dog Timer
#FUSES CCP2B3 // CCP2 input/output multiplexed with RB3
//CCP2C1 CCP2 input/output multiplexed with RC1
#FUSES NOPBADEN // PORTB pins are configured as digital I/O on RESET
//3.09 PBADEN PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC // Timer1 configured for low-power operation
#FUSES MCLR // Master Clear pin enabled
#FUSES STVREN // Stack full/underflow will cause reset
//4.00 NOSTVREN Stack full/underflow will not cause reset
#FUSES NOLVP // No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST // Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG // No Debug mode for ICD
#FUSES NOCPB // No Boot Block code protection
#FUSES NOCPD // No EE protection
#FUSES WRT // Program Memory Write Protected
#FUSES NOWRTC // configuration not registers write protected
#FUSES NOWRTB // Boot block not write protected
#FUSES NOWRTD // Data EEPROM not write protected
#FUSES NOEBTR // Memory not protected from table reads
#FUSES NOEBTRB // Boot block not protected from table reads
#FUSES NOPROTECT // Code not protected from reading
#USE FAST_IO( A )
#USE FAST_IO( B )
#USE FAST_IO( C )
#USE FAST_IO( D )
#USE FAST_IO( E )
#USE RS232( baud = 9600 , xmit = PIN_C6 , rcv = PIN_C7 , bits = 8 , parity = N , ERRORS )
#USE I2C( MASTER , SCL = PIN_C3 , SDA = PIN_C4 )
#ifndef DAL_SCL
#define DAL_SCL PIN_C3
#define DAL_SDA PIN_C4
#endif
void main( void );
void Setup( void );
#define LCD_ENABLE_PIN PIN_A1
#define LCD_RW_PIN PIN_A2
#define LCD_RS_PIN PIN_A3
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <LCD.c>
//
// 0 means ACK, 1 means NO ACK
//
#define _ACK 0
#define _NOACK 1
void main( void )
{
unsigned char Ack;
char byte0 , byte1 , byte2, conf;
int32 adc_in;
float Volts;
Setup();
lcd_init();
//
// Initialize the MCP3421
//
output_high(DAL_SDA);
output_high(DAL_SCL);
i2c_start();
//
// MCP3421 ADDRESS BYTE - MSB first
//
// 1 - 1 - 0 - 1 - A2 - A1 - A0 - R/W
//
/*
Part Number - Address Option - Code on package
MCP3421A0T-E/CH - A0 (000) - CANN
MCP3421A1T-E/CH - A1 (001) - CBNN
MCP3421A2T-E/CH - A2 (010) - CCNN
MCP3421A3T-E/CH - A3 (011) - CDNN
MCP3421A4T-E/CH - A4 (100) - CENN
MCP3421A5T-E/CH - A5 (101) - CFNN
MCP3421A6T-E/CH - A6 (110) - CGNN
MCP3421A7T-E/CH - A7 (111) - CHNN
*/
//
// Change the address depending on your ADC, check the code on package
// or the invoice from your supplier
//
// 1101XXX0
//
Ack = i2c_write( 0b11010010 ); // Write mode
//
// MCP3421 CONFIGURATION REGISTER - MSB first
// RDY - C1 - C0 - O/C - S1 - S0 - G1 - G0
//
//Ack = i2c_write( 0b00010000 ); // Continuous conversion - 12bit - PGA = 1V/V
Ack = i2c_write( 0b00011100 ); // Continuous conversion - 18bit - PGA = 1V/V
i2c_stop();
//
// Continuous conversion and display on LCD
//
while( 1 )
{
i2c_start();
Ack = i2c_write( 0b11010011 ); // Send address of MCP3421
delay_us( 10 );
//
// NOTE: Don't ack the last byte read
//
byte0 = i2c_read( 1 ); // read first byte and send ack
byte1 = i2c_read( 1 ); // read second byte and send ack
byte2 = i2c_read( 1 ); // read third byte and send ack
conf = i2c_read( 0 ); // read configuration byte - optional
i2c_stop();
//
// Build a int32 from the 3 bytes read
//
byte0 &= 0b00000001; // Mask unused bits, probably not neccesary
adc_in = byte0;
adc_in <<= 8;
adc_in += byte1;
adc_in <<= 8;
adc_in += byte2;
//
// Display the 3 bytes, the conf byte, and adc_in in decimal and hex formats
//
//printf( lcd_putc , "\f%03u, %03u, %03u %X\n%06Lu %LX" , byte0 , byte1 , byte2 , conf , adc_in , adc_in );
//
// Display adc_in in decimal and hex formats
//
printf( lcd_putc , "\f%06Lu %LX" , adc_in , adc_in );
//
// Convert adc_in to Volts
//
/*
Bit Resolutions
12 bits 1 mV
14 bits 250 uV
16 bits 62.5 uV
18 bits 15.625 uV
*/
//Volts = (float)adc_in * 0.001; // 12 bits ADC - NOT TESTED
//Volts = (float)adc_in * 0.000250; // 14 bits ADC - NOT TESTED
//Volts = (float)adc_in * 0.0000625; // 16 bits ADC - NOT TESTED
Volts = (float)adc_in * 0.000015625; // 18 bits ADC
//
// Display the measured voltage
//
printf( lcd_putc , "\nVolts = %04f" , Volts );
delay_ms( 500 );
}
}
void Setup( void )
{
//
// Port configuration. 1 = Inputs, 0 = Outputs. MSB first
//
set_tris_a( 0b11111111 );
set_tris_b( 0b00000001 );
set_tris_c( 0b11111001 );
set_tris_d( 0b00000000 );
set_tris_e( 0b11111111 );
} |
|
|
|
hasimi20
Joined: 04 Sep 2010 Posts: 19
|
Proteus simulation |
Posted: Tue Aug 14, 2012 12:12 am |
|
|
I have made a Proteus simulation on servera's program. However the voltage displayed on the lcd just giving a constant value that is "voltage = 2.047984"at any voltage supplied to MCP3421 adc input. My question is
1. Why you include #include <PIC18F4520_registers.h> in the program?what is it contain?
2. If I built the circuit on a breadboard, does it working? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Aug 14, 2012 2:02 am |
|
|
Why waste time with Proteus?
Use real hardware from the outset.
Mike |
|
|
hasimi20
Joined: 04 Sep 2010 Posts: 19
|
|
Posted: Tue Aug 14, 2012 2:34 am |
|
|
thanks for the suggestion |
|
|
|
|
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
|