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

Problem width MCP3302(A/D Converter)

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



Joined: 03 May 2007
Posts: 4
Location: Spain

View user's profile Send private message

Problem width MCP3302(A/D Converter)
PostPosted: Thu May 03, 2007 5:15 am     Reply with quote

Halo, my english is very poor so I ask for pardon.

hardware:

MCP3301 -> 13-Bit Differential Input, Low Power A/D Converter with SPI™ Serial Interface (microchip)



PIC18F2550

code:

Code:


// Added SPI Mode define because CCS and Microchip made a very confusing mess of it.
//     MOTOROLA              MICROCHIP                 CCS
//---------------------------------------------------------------------------------
//   SPI Mode 0,0   ==    CKP = 0, CKE = 1   ==   SPI_L_TO_H | SPI_XMIT_L_TO_H
//   SPI Mode 0,1   ==    CKP = 0, CKE = 0   ==   SPI_L_TO_H
//   SPI Mode 1,0   ==    CKP = 1, CKE = 1   ==   SPI_H_TO_L
//   SPI Mode 1,1   ==    CKP = 1, CKE = 0   ==   SPI_H_TO_L | SPI_XMIT_L_TO_H

#define MCP3301_CS        PIN_B2
#define MCP3301_CLK    PIN_B1
#define MCP3301_SDI    PIN_B0

void init_mcp3301()
{
output_low(MCP3301_CS);
output_low(MCP3301_SDI);
output_low(MCP3301_CLK);
setup_spi( SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 );
//setup_spi( SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16 );
}

int16 read_mcp3301()
{
BYTE byte_low=0,byte_high=0;
output_high(MCP3301_CS);
while( !spi_data_is_in() )
   {
   byte_high = spi_read();
   byte_low  = spi_read();
   }
output_low(MCP3301_CS);
byte_high <<3>>= 3;
return (make16(byte_high,byte_low));
}

void main(void)
{
int16 dato;
printf("Init mcp3301...\r\n");
delay_ms(100);
init_mcp3301();
delay_ms(100);
while(1)
   {
   dato = read_mcp3301();
   printf("Dato: %Ld \r\n",dato);
   delay_ms(100);
   }
}



Problem:

spi_data_is_in() always is false.
RolandAldridge



Joined: 26 Mar 2007
Posts: 7
Location: Southern California

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

PostPosted: Thu May 03, 2007 10:08 am     Reply with quote

I think you have the chip select lines the wrong way up - bring it low while you write to or read from it, high when you are not doing so.

Here is my code for a 3204, using a 16C67:

byte first_data_out, second_data_out;
struct adc_data_type{ byte hi; byte lo;} adc_data;
long data_in = 0;
first_data_out = 0x06; // See MP3204 data sheet

// Set up the data_out byte to tell the ADC what channel to look at.
If (ADC_Channel > 3) ADC_Channel = 0; // We'll look at the reading, what the hell
second_data_out = ADC_Channel << 6; // 0 is oxygen, 1 is Alarm 1, 2 is Alarm 2, 3 is span value
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16|SPI_SS_DISABLED);
//Set up the SPI for 0,0 operation
CKE = TRUE; // data out transmitted on clock rising edge
SMP = FALSE; // input data sampled in middle of data output time

// set the /cs pin high then low to initiate communication
// Output_HIGH(ADC_CS);
Output_LOW(ADC_CS);

//Now tell it what we want
//Dump any data in the buffer
If ( SPI_DATA_IS_IN() )data_in = spi_read();
// Write the command data into the chip
SPI_write(first_data_out);
adc_data.lo = SPI_read(); // garbage
SPI_write(second_data_out);
adc_data.hi = spi_read(); // of which the first four bits are garbage
SPI_write(second_data_out); // so as to clock in the lower byte
adc_data.lo = spi_read();
adc_data.hi &= 0x0F; // Dump the top four bits
data_in = adc_data.hi;
data_in <<= 8;
data_in += adc_data.lo;

Output_HIGH(ADC_CS); // set the /cs high again

return( data_in);

Roland
_________________
Roland Aldridge
www.amio2.com
nina



Joined: 20 Apr 2007
Posts: 111

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

mcp
PostPosted: Sat May 05, 2007 4:23 am     Reply with quote

what means these lines?

byte_high <<3>>= 3;
return (make16(byte_high,byte_low));

tks
kaos



Joined: 03 May 2007
Posts: 4
Location: Spain

View user's profile Send private message

PostPosted: Sat May 05, 2007 4:35 am     Reply with quote

In the picture you can to see that 3 bytes don't use so first, <<3, move 3 bytes to left an them, >>3, move 3 bytes to right. Now there is 0.
nina



Joined: 20 Apr 2007
Posts: 111

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

high_byte
PostPosted: Sat May 05, 2007 7:53 am     Reply with quote

kaos...

why do I need use this line?

tks
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Sat May 05, 2007 10:38 am     Reply with quote

Quote:

byte_high <<3>>= 3;

The statement is wrong.

you wanted to do this:
byte_high << 3;
byte_high >> 3;

in one statement.

If you want to discard the 3 MSB:
byte_high = (0x1F & byte_high);

Anyway you need something like this:
Code:

signed long read_mcp3301()
{
int byte_low=0,byte_high=0;
signed long out_value;

  output_low(MCP3301_CS);
  byte_high = spi_read();      // clock out the MSByte
  byte_low  = spi_read();      // clock out the LSByte
  output_high(MCP3301_CS);     // disable the converter
 
  out_value = make16(byte_high,byte_low);
 
  if(bit_test(out_value,12))   // get the sign
    {bit_set(out_value,15);}   // format propperly a signed long 
  else
    {bit_clear(out_value,15);}
 
  return(out_value);
}

void main(void)
{
signed long dato;
 
 delay_ms(100);
 printf("Init mcp3301...\r\n");
 init_mcp3301();
 delay_ms(100);

 while(1)
    {
     dato = read_mcp3301();
     dato = dato & 0x9FFF; // discard bit 14 and 13   
     printf("Dato: %Ld \r\n",dato); // Signed output
     delay_ms(1000);
    }
}



I don´t have the MCP3301 to test it, i would like to know your results.


Humberto
kaos



Joined: 03 May 2007
Posts: 4
Location: Spain

View user's profile Send private message

PostPosted: Sun May 06, 2007 5:04 am     Reply with quote

Crying or Very sad Crying or Very sad Crying or Very sad It does not work. I dont't understand, because the A/d is very simple but only send 514 and dont change.

Thank you anyhow.

pd:

I writed

byte_high <<= 3;
byte_high >>= 3;

but the foro changed it ;).
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