PICcoder.co.uk Forum  


::post new topic::
Getting ADC result
Date: 2007/04/27 13:27 By: rwillis Status: User  
Karma: 0  
Posts: 2
graphgraph
Hi All

First off, I've not much experience with PIC's etc, so any code posted will probably be a bit frightening to most of you. My main problem is I have a circuit, all tested and working, its an MCP3421 18bit ADC. I only need 14bits for my application, but I digress. I have a dsPIC33FJ256GP506, I am using the C30 compiler and the peripheral libraries, in my app. I want to just read one value from the ADC, to start with. I am reading temps using PT100 sensors.

I have emailled Microchip, who cannot provide me with any C examples, only asm for the 16F series, so I have a lot of reading to do.

Well I have tried to follow, and convert many asm examples, and the tech specs, etc. but I only get the same three sets of answers, either all 0's, F's or a 0x7F7F pattern. I feel it may be a setup problem, but If someone could look at the code for any glaring errors it would a great help. I'm just providing the relevant code here that does the ADC work,

Thanks for getting this far.

Russ

Code:

  #include <p33fj256gp506.h> #include <i2c.h> //---------------------------------------------------------------------------------------- void Analog_Init() {     unsigned int config2,config1;     config2 0x11;    // Set baud rate to 100KHz         config1 = ( I2C1_ON I2C1_IDLE_CON I2C1_CLK_HLD &                  I2C1_IPMI_DIS I2C1_7BIT_ADD I2C1_SLW_DIS &                 I2C1_SM_DIS I2C1_GCALL_DIS I2C1_STR_DIS &                 I2C1_NACK I2C1_ACK_DIS I2C1_RCV_DIS &                 I2C1_STOP_DIS I2C1_RESTART_DIS &                                 I2C1_START_DIS );     OpenI2C1(config1,config2); } //---------------------------------------------------------------------------------------- // Globals used for debugging unsigned char sensor_result1_1;    // H/L Results from sensor reading unsigned char sensor_result1_2;     //---------------------------------------------------------------------------------------- void Analog_Task() {     unsigned char setup_1_shot;        // Setup ADC config and initiate 1 shot conversion     unsigned char setup_only;          // Setup ADC config only     unsigned char setup_continuous// Setup ADC config and continuous conversion     setup_1_shot 0x87;            // 10001111 (8V/V - 14bit 60SPS - 1Shot - Do Conversion)     sensor_result1_1 0;     sensor_result1_2 0;     IdleI2C1();                        // Set I2C as idle     StartI2C1();                    // Request start up sequence     IdleI2C1();     MasterWriteI2C1(0x8B );           // RW/1 ADDR/000 DEV/1011 (8b)      IdleI2C1();     AckI2C1();     IdleI2C1();     //----------------------------------------------------------------     // Setup the ADC, then send the ONE SHOT CONVERSION code      //----------------------------------------------------------------     MasterWriteI2C1(setup_1_shot);    // Setup ADC      IdleI2C1();     AckI2C1();     IdleI2C1();     //----------------------------------------------------------------     // Read in sensor data, as it is 14bits long need to read in      // two byte values from the ADC.     //----------------------------------------------------------------     // SENSOR 1     I2C1RCV 0x00;                 // Make sure rx buffer is 0     MasterReadI2C1();                // Read value from I2C bus     IdleI2C1();     AckI2C1();     sensor_result1_1 I2C1RCV;        // Result of the 1 shot conversion     I2C1RCV 0x00;                 // 0 again, for testing     //IdleI2C1();     MasterReadI2C1();                // Read value from I2C bus     IdleI2C1();     AckI2C1();                    //IdleI2C1();     sensor_result1_2 I2C1RCV;        // Result of the 1 shot conversion     //----------------------------------------------------------------     StopI2C1();                        // Initiate stop sequence     IdleI2C1();     CloseI2C1(); }

reply | quote

Re:Getting ADC result
Date: 2007/05/01 14:32 By: dariog Status: User  
Karma: 6  
Posts: 107
graphgraph
I may be wrong, but I always see your code Writing bytes which end with "1", which in I2C terms usually means "Read". So, IMO, you're never Writing nor configuring the ADC.

I don't have datasheet for that part, but you should look again into it, to see the proper sequence to get it working.
reply | quote

Re:Getting ADC result
Date: 2007/05/03 12:05 By: rwillis Status: User  
Karma: 0  
Posts: 2
graphgraph
Hi

Thanks for your reply. I revised what I had done, and tried a differnet way, this works for me now, it may be of use to some one in the future.

Excuse the code, I'm new to this C stuff!

Code:

  // Configure I2C module unsigned int config2,config1; config2 0x11;        // Set baud rate to 100KHz       // Configure I2C for 7 bit address mode  config1 = (    I2C1_ON I2C1_IDLE_CON I2C1_CLK_HLD             I2C1_IPMI_DIS I2C1_7BIT_ADD             I2C1_SLW_DIS I2C1_SM_DIS &             I2C1_GCALL_DIS I2C1_STR_DIS &             I2C1_NACK I2C1_ACK_DIS I2C1_RCV_DIS &             I2C1_STOP_DIS I2C1_RESTART_DIS             I2C1_START_DIS ); OpenI2C1(config1,config2); StopI2C1(); // Initiate Stop IdleI2C1();                        // Stopped StartI2C1();                    // Initiate Start     while(I2C1CONbits.SEN);            // Wait till Start sequence is completed       MasterWriteI2C1(0xD1);            // Write Slave address and set master for transmission  while(I2C1STATbits.TBF);        // wait for 8 clock cycs while(I2C1STATbits.ACKSTAT);      MasterWriteI2C1(_1shot);         // Configure MCP3421 for 1 SHOT - 14Bit 60SPS - 8VV while(I2C1STATbits.TBF);        // wait for 8 clock cycs while(I2C1STATbits.ACKSTAT);      if(I2C1STATbits.ACKSTAT) {     Nop(); Nop(); Nop(); // NACK     I2C1CONbits.RCEN 1;     Nop(); Nop(); Nop(); Nop(); Nop(); } else {     Nop(); Nop(); Nop(); // ACK     // High Data byte 1     I2C1CONbits.RCEN 1;     while(I2C1CONbits.RCEN);        // RCEN cleared in HW     while(I2C1STATbits.ACKSTAT);     sensor_high_byte I2C1RCV;    // read RX buffer     I2C1CONbits.ACKDT 0;            // select ACK     I2C1CONbits.ACKEN 1;          // send ACK/NACK     while(I2C1CONbits.ACKEN);         // cleared in HW     while(I2C1STATbits.ACKSTAT);     // Low Data byte 2                 I2C1CONbits.RCEN 1;     while(I2C1CONbits.RCEN);        // RCEN cleared in HW     while(I2C1STATbits.ACKSTAT);     sensor_low_byte I2C1RCV;        // read RX buffer     I2C1CONbits.ACKDT 0;            // select ACK     I2C1CONbits.ACKEN 1;          // send ACK/NACK     while(I2C1CONbits.ACKEN);         // cleared in HW     while(I2C1STATbits.ACKSTAT);     // Configuration byte 3                 I2C1CONbits.RCEN 1;     while(I2C1CONbits.RCEN);        // RCEN cleared in HW     while(I2C1STATbits.ACKSTAT);     sensor_config_byte I2C1RCV;    // read RX buffer     I2C1CONbits.ACKDT 0;            // select ACK     I2C1CONbits.ACKEN 1;          // send ACK/NACK     while(I2C1CONbits.ACKEN);         // cleared in HW     while(I2C1STATbits.ACKSTAT);               StopI2C1();     Nop(); Nop(); Nop(); Nop();    Nop(); }//end if CloseI2C1();    



Thanks again

Russ
reply | quote

Re:Getting ADC result
Date: 2007/05/15 10:51 By: dariog Status: User  
Karma: 6  
Posts: 107
graphgraph
Ok, not sure how it went, but good anyway
reply | quote

Re:Getting ADC result
Date: 2008/06/16 10:22 By: RWillis Status: Visitor  
 
Hi

Sorry for delay in updating this code, but finally I have something that works and is tested, extensively. The code snippet below is just that a snippet, its what allows you to configure the MPC3421 and read a value from it into the ADCReading variable.

You can use this as a basis to setup your own routines, etc. It hasn't actually taken me all this time to figure this out its just I'm very busy and completely forget to post it here until now.

Anyway hope it will help someone somewhere.

Russ

Code:

  // set up the I2C and MCP3421 using the peripheral library // 400kHz using 40MHz clock OpenI2C1(0x800092); StopI2C1(); while(I2C1CONbits.PEN); // set the 3421 into 16bit mode StartI2C1(); while(I2C1CONbits.SEN); if (MasterWriteI2C1(0xD0) == 0)    {     // wait for data to end transmission     while(I2C1STATbits.TRSTAT);     // wait for ack     while(I2C1STATbits.ACKSTAT);     // set into continuous mode 16bit - 8V/V      MasterWriteI2C1(0x18);      while(I2C1STATbits.TRSTAT);     while(I2C1STATbits.ACKSTAT);     StopI2C1();     while(I2C1CONbits.PEN); } StartI2C1(); while(I2C1CONbits.SEN); // write Slave address if (MasterWriteI2C1(0xD1) == 0) {     // wait for the data to be written     while(I2C1STATbits.TRSTAT);     // wait for ACK     while(I2C1STATbits.ACKSTAT);     // now read 3 bytes of data     if (MastergetsI2C1(3i2c_data1000) == 0) {         // successful read so convert the result         // i2c_data[0:1] form the 16 bit result         // i2c_data[2] = config byte         if ((i2c_data[2] & 0x80) == 0) {             // new data available             ADCReading = (i2c_data[0] << 8) | i2c_data[1];         }         }     StopI2C1();     while(I2C1CONbits.PEN); }

reply | quote

::post new topic::