CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MCP3421

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Markdem



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

MCP3421
PostPosted: Fri Feb 02, 2007 7:17 pm     Reply with quote

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

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Fri Feb 02, 2007 8:44 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 02, 2007 9:50 pm     Reply with quote

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

View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger

PostPosted: Fri Feb 02, 2007 10:12 pm     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Sat Feb 03, 2007 6:40 pm     Reply with quote

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 Rolling Eyes

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

View user's profile Send private message

PostPosted: Sun May 10, 2009 2:15 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

Working MCP3421 code
PostPosted: Wed Dec 15, 2010 8:21 am     Reply with quote

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

View user's profile Send private message

Proteus simulation
PostPosted: Tue Aug 14, 2012 12:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 14, 2012 2:02 am     Reply with quote

Why waste time with Proteus?

Use real hardware from the outset.

Mike
hasimi20



Joined: 04 Sep 2010
Posts: 19

View user's profile Send private message

PostPosted: Tue Aug 14, 2012 2:34 am     Reply with quote

thanks for the suggestion
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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