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

MCP3208 driver vs SPI Library functions
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Barney



Joined: 18 Oct 2004
Posts: 41
Location: Newark, CA

View user's profile Send private message

MCP3208 driver vs SPI Library functions
PostPosted: Mon Apr 10, 2006 2:05 pm     Reply with quote

I have to revisit my old nemesis, SPI, and last time it whipped me. (I wimped out with I2C). No choice now as I need an 8 channel 12 bit ADC (MCP3208). This time around I found the MCP3208.c driver (thank you forum) and am wondering why I need to use it and bang bits instead of the built in SPI library functions?

Thanks
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Mon Apr 10, 2006 2:22 pm     Reply with quote

Barney,

I've been using multiple MCP3208's in a design for a couple of years and never had any trouble with it. I have some functions that I can post later this evening that should get you started. The biggest problem is setting up the SPI hardware correctly. I'll include that, too. In the mean time, tell us which processor you are using and the version of your compiler.
Barney



Joined: 18 Oct 2004
Posts: 41
Location: Newark, CA

View user's profile Send private message

PostPosted: Tue Apr 11, 2006 12:20 pm     Reply with quote

Thanks, a more generous offer than what I was looking for, but I won't look a gift horse in the mouth. I am using the 16F87 & PCM 3.212

I had tried using the built in SPI functions about a year ago and it didn't work. I didn't have time to really get into the assemby code and verify how the hardware was being setup by the SPI commands and I got some really weird clock/data signals that didn't make sense so I went back to the tried & true I2C. I can't find a 12 bit 8 channel I2C ADC, so I have to get SPI working.

The "C" drivers is new information for me and may be the solution. Haven't had a chance to try them out on the hardware yet.

My real question is this, Why were the drivers were written given the built in SPI functions?

Thanks
Barney
dr
Guest







OT:Gift Horse
PostPosted: Tue Apr 11, 2006 2:13 pm     Reply with quote

Barney wrote:
Quote:
Thanks, a more generous offer than what I was looking for, but I won't look a gift horse in the mouth.
I am using the 16F87 & PCM 3.212

I had tried using the built in SPI functions about a year ago and it didn't work. I didn't have time to really get into the assemby code and verify how the hardware was being setup by the SPI commands and I got some really weird clock/data signals that didn't make sense so I went back to the tried & true I2C. I can't find a 12 bit 8 channel I2C ADC, so I have to get SPI working.

The "C" drivers is new information for me and may be the solution. Haven't had a chance to try them out on the hardware yet.

My real question is this, Why were the drivers were written given the built in SPI functions?

Thanks
Barney


I think you would use the Gift Horse saying if he had offered you less than what you were looking for..............
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Tue Apr 11, 2006 4:40 pm     Reply with quote

Well, time flies when you are having fun????

I got caught up in the real world of production problems.

Here we go:

spi definitions header file:
Code:
// Defines for new spi mode parameters
//

#define SPI_MODE_0_0 0x4000
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0010
#define SPI_MODE_1_1 0x4010


Version 3 of the compiler sets up the spi in a non-standard mode with the basic parameters. Insert the following line in you initialization section:

Code:
setup_spi(SPI_MASTER|SPI_MODE_0_0|SPI_CLK_DIV_16);

You can change the clock part for your system clock, etc.

Here's my adc_io.h file:
Code:
// Header file for adc_io.c file
// Contains function prototypes for adc_io.c

int adc_address_temp, adc_cs_temp;

long read_ext_adc (int ext_adc_channel);

long const start_ext_adc [8] =
{
   0x0600, 0x0640, 0x0680, 0x06C0,
   0x0700, 0x0740, 0x0780, 0x07C0
};

struct s_long
{
   int l;
   int h;
};

union u_long
{
   long int l_temp;
   struct s_long s_temp;
} long_temp0, long_temp1, long_temp2;


And here's my acd_io.c file:
Code:
// Code file for ADC access functions
// Also add adc_io.h file
/*
   ADC I/O functions:

   read_ext_adc(int ext_adc_channel)
*/

long read_ext_adc (int ext_adc_channel)
{
   adc_address_temp = ext_adc_channel & 0x07;

   // select the proper adc start sequence for our channel
   long_temp0.l_temp = start_ext_adc[adc_address_temp];

   adc1_cs = 0;

   // then start the adc reading by sending the start sequence
   //  and reading the data
   spi_write (long_temp0.s_temp.h);
   long_temp1.s_temp.h = spi_read();
   spi_write (long_temp0.s_temp.l);
   long_temp1.s_temp.h = spi_read();
   spi_write (long_temp0.s_temp.l);
   long_temp1.s_temp.l = spi_read();

   adc1_cs = 1;

   long_temp1.l_temp = 0x0FFF & long_temp1.l_temp;
   return (long_temp1.l_temp);

}


You will need to sort out your chip select and define a pin for it. Just use the read_ext_adc(channel); as you would any other function.

Code:
MyLongInt = read_ext_adc(channel);  // channel is 0-7


Try this out and let us know if it works for you. I had to edit the functions a bit because my system has 2 of these and the chip selects are controlled by external latches.

edited to correct the set up parameters. Thanks PCM!
Barney



Joined: 18 Oct 2004
Posts: 41
Location: Newark, CA

View user's profile Send private message

Gift Horse
PostPosted: Tue Apr 11, 2006 8:50 pm     Reply with quote

DR,

Nope, I got much more than I asked for. Muchos.

"You are looking a gift horse in the mouth when you receive a gift and then you question the value of that gift. Like a person who has been given a horse as a gift (a gift-horse) and you are looking into the horse's mouth to see if it is in good health."
magnoedu



Joined: 29 May 2009
Posts: 11

View user's profile Send private message MSN Messenger

y need to driver for the multiples mcp3208 can you help-me?
PostPosted: Sat Sep 25, 2010 4:55 am     Reply with quote

I need an driver for ccs to work with multiples mcp3208, I search by the all net but not find, I read one post you use multiples mcp3208, I trying to make changes to ex_ad12 by the ccs but not have success.
please help-me
sorry my bad english I live in Brazil
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

Suggested Changes
PostPosted: Tue Jul 19, 2011 10:19 am     Reply with quote

Hello Charlie U,

I've been using your functions and they've been very helpfull to me. However I think I've found a bug in your code. My english is not very good but I'll try to make myself understood.

I was using your library to sequentially measure 6 consecutive ADC channels with MCP3208 Proteus Model. I realized that I obtained correct measures only in some channles, having wrong measures in some others.

Looking at the chronogram in the datasheet we observe that there is a bit that is slightly wider than the others in the address word (as they use 7 leading zeroes before the strat bit the wider bit is the SGL/DIFF bit in this example).

http://imageshack.us/photo/my-images/855/mcp3008driverbug.jpg/

Meanwhile, as you're using 5 leading zeroes in your code, the wider bit is exactly the most significant bit of the Channel selection field (D2). I've found that because of this bit D1 is ¿overlapped? by D2 and thus it always take the same value than D2, making it impossible to select channels 2,3,4 and 5 properly, as they have D2 != D1.

So, my suggestion (it has worked for my application) is to change the contents of start_ext_adc array, i.e.:

Code:
long const start_ext_adc [8] =
{
   0x0600, 0x0640, 0x0680, 0x06C0,
   0x0700, 0x0740, 0x0780, 0x07C0
};


changed as:

Code:
long const start_ext_adc [8] =
{
   0x0180, 0x0190, 0x01A0, 0x01B0,
   0x01C0, 0x01D0, 0x01E0, 0x01F0
};




Maybe I'm wrong but it has worked for me. I'll be glad of hearing comments or corrections if what I've said is wrong.

Thank you again for your work Charlie.

Regards,

Pablo
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Tue Jul 19, 2011 5:28 pm     Reply with quote

Hello Pablo,

Thanks for the suggestion, but you are using a different ADC chip. Yours is the MCP3004/8 which is a 10 bit part. Your start array will work correctly for it. However, my driver is for an MCP3208 which is a 12 bit part. My original start array is correct for this part. It has been used in many production test systems for many years quite successfully.

Charlie
krugger



Joined: 12 Jul 2011
Posts: 18
Location: El Salvador

View user's profile Send private message

PostPosted: Tue Jul 19, 2011 8:53 pm     Reply with quote

Embarassed

Thank you again!
nuclear__



Joined: 24 Jan 2015
Posts: 63

View user's profile Send private message

3V7 operation
PostPosted: Sun Mar 28, 2021 12:45 pm     Reply with quote

Hi. It's being too long since this thread was created.
I use mcp3208 with 3.7v supply (reference too).

I have an external power supply ( common ground with pic etc) and i test the digital output by adding 0.1v each time.
It looks working up to 1.0V . Then when i go to 1.1V my digital reading goes from around 1000(for 1Volt) to 1600(for 1.1Volt) then it keeps growing but not linear. It stops growing at 2 Volts.

I tried that on more than one channel and i get the same result.

I guess i get corrupted reading . Any idea how to check it more?

Here are variable readings after each command, as shown in file adc_io.c


Code:
spi_write (long_temp0.s_temp.h);
long_temp1.s_temp.h = spi_read();
printf(usb_cdc_putc,"\r\ntemp.h:%u ",long_temp1.s_temp.h);
spi_write (long_temp0.s_temp.l);
long_temp1.s_temp.h = spi_read();
printf(usb_cdc_putc," temp.h:%u ",long_temp1.s_temp.h);
spi_write (long_temp0.s_temp.l);
long_temp1.s_temp.l = spi_read();
printf(usb_cdc_putc," temp.l:%u ",long_temp1.s_temp.l);


Voltage 0.9Volt :
temp.h:0 temp.h:3 temp.l:219 adc1:976

Voltage 1.0Volt :
temp.h:0 temp.h:3 temp.l:251 adc1:1008

Voltage 1.1Volt :
temp.h:0 temp.h:6 temp.l:111 adc1:1648

Voltage 1.2Volt :
temp.h:0 temp.h:6 temp.l:247 adc1:1776
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 3:05 pm     Reply with quote

To display long ints with printf in CCS, you need to use "%lu".
nuclear__



Joined: 24 Jan 2015
Posts: 63

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 3:31 pm     Reply with quote

h and l are int.
It doesn't compile with lu .

actualy you can see adc1 variable which is shown with %lu and is over 255. This is the output .
I just added the rest variables in a destructive way to help me find out the problem . But i cant
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 3:40 pm     Reply with quote

OK, well what happens if you use the CCS driver, mcp3208.c ?
temtronic



Joined: 01 Jul 2010
Posts: 9240
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 6:59 pm     Reply with quote

You don't post HOW you convert the 2 ADC bytes into the 'voltage' ! That is important for us to see.
Also, you say that Vref is 3.7 volts, same as VDD of the PIC. Is it the SAME power supply ? If so Vref will vary depending on what the PIC is doing !
The ADc Vref needs to be from a 'voltage reference' chip, well filtered Vin, bypassed, and laidout according to mfr's specs !
As a 10 bit ADC, you need a LOT of GREAt PCB design/layout/ components before you can get ANY reliable, accurate readings
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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