|
|
View previous topic :: View next topic |
Author |
Message |
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
Help with UNI-DS 3 with PIC18F4520 and onboard ADC MCP3204 |
Posted: Fri Dec 11, 2009 10:41 am |
|
|
Hi,
I am a newbee in this area and I DESPERATELY need help.
I managed to get to work LCD with flex_pic.c driver.
I´m now trying to get external ADC mcp3204 to work.
I use UNI-DS3 development board http://www.mikroe.com/en/tools/unids3/ from Mikroelektronika.
Manual for this board is here: http://www.mikroe.com/pdf/uni_ds3_manual.pdf
Wiring diagram is here: http://www.scribd.com/doc/23980337/jpg-to-pdf
1. page is PIC18F4520
2. page is MCU slot for my MicroControlUnit card
3. page is ADC and DAC wiring diagram.
Below are
1. HEADER file for 18F4520 (given by CCS compiler installation)
2. original MCP3204 driver (given by CCS compiler installation)
3. my modified MCP3204 driver
(I believe that original would not work because Din bits had some mistake on "startbit", and tsample was not enabled to ADC; see MCP3204 datasheet, section 5.0 Serial Communication)
4. and my little program.
I use original header file that I got with CCS.
1. Header:
Quote: |
Deleted.
Reason: Forum Rule #10
10. Don't post the CCS example code or drivers
-- Forum Moderator
|
2. Original MCP3204 driver (given by CCS compiler installation)
Quote: |
Deleted.
Reason: Forum Rule #10
10. Don't post the CCS example code or drivers
-- Forum Moderator
|
3. my modified MCP3204 driver:
Code: |
////////////////// Driver for MCP3204 A/D Converter ////////////////////////
//// ////
//// adc_init() ////
//// Call after power up ////
//// ////
//// value = read_analog_mcp( channel, mode ) ////
//// Read an analog channel ////
//// 0 through 3 and select ////
//// differential (0) or ////
//// single (1) mode ////
//// ////
//// value = read_analog( channel ) ////
//// Read an analog channel ////
//// 0 through 7 in single mode ////
//// ////
//// convert_to_volts( value, string ) ////
//// Fills in string with ////
//// the true voltage in ////
//// the form 0.000 ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////
//#ifndef MCP3204_CS
#define MCP3204_CLK PIN_C3
#define MCP3204_DOUT PIN_C4
#define MCP3204_DIN PIN_C5
#define MCP3204_CS PIN_A5
//#endif
void adc_init() {
output_high(MCP3204_CS);
}
void write_adc_byte(BYTE data_byte, BYTE number_of_bits) {
BYTE i;
delay_us(2);
for(i=0; i<number_of_bits; ++i) {
output_low(MCP3204_CLK);
if((data_byte & 1)==0)
output_low(MCP3204_DIN);
else
output_high(MCP3204_DIN);
data_byte=data_byte>>1;
delay_us(50);
output_high(MCP3204_CLK);
delay_us(50);
}
}
BYTE read_adc_byte(BYTE number_of_bits) {
BYTE i,data;
data=0;
for(i=0;i<number_of_bits;++i) {
output_low(MCP3204_CLK);
delay_us(50);
shift_left(&data,1,input(MCP3204_DOUT));
output_high(MCP3204_CLK);
delay_us(50);
}
return(data);
}
long int read_analog_mcp(BYTE channel, BYTE mode) {
int l;
long int h;
BYTE ctrl_bits;
delay_us(200);
if(mode!=0)
mode=1;
output_low(MCP3204_CLK);
output_high(MCP3204_DIN);
output_low(MCP3204_CS);
delay_us(50);
output_high(MCP3204_CLK);
if(channel==1) // Change so MSB of channel #
ctrl_bits=4; // is in LSB place
else if(channel==2)
ctrl_bits=2;
else if(channel==3)
ctrl_bits=6;
else if(channel==0)
ctrl_bits=0;
ctrl_bits=ctrl_bits<<1;
if(mode==1) // In single mode
ctrl_bits |= 1;
else // In differential mode
ctrl_bits &= 0xfe;
/* ctrl_bits=ctrl_bits<<1; // Shift so LSB is start bit mistake: start bit is made with CS low and DIN high in line 85,not in write_adc_byte with CLK low and DIN high
ctrl_bits |= 1;
*/
write_adc_byte(ctrl_bits, 4); // Send the control bits
h=read_adc_byte(4);
l=read_adc_byte(8);
output_high(MCP3204_CS);
return((h<<8)|l);
}
long int read_analog( BYTE channel ) // Auto specifies single mode
{
long int temp;
if(channel<4)
temp=read_analog_mcp( channel, 1);
else
temp=0;
return temp;
}
void convert_to_volts( long int data, char volts[6]) {
BYTE i, d, div_h, div_l;
long int temp,div;
div=4095/5;
if(data>=4090)
data=4095;
temp=data/div;
for(i=0;i<=4;i++) {
volts[i]=(BYTE)temp+'0';
if(i==0) {
volts[1]='.';
i++;
}
temp=div*(BYTE)temp;
data=data-temp;
div=div/10;
}
volts[i]='\0';
}
|
4. and my little program:
Code: | #include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP, XT,PUT,NOBROWNOUT
#use delay(clock=4000000)
#include <mcp3204.c>
#include <flex_pic.c>
#include <stdlib.h>
char display_data( long int data ) {
convert_to_volts( data, volt_string );
return volt_string;
}
void main() {
long int value;
char svalue[];
adc_init();
lcd_init();
do {
delay_ms(1000);
lcd_putc("\f");
value = read_analog(0);
svalue = display_data(value);
lcd_putc("Sampling:\n");
printf(lcd_putc, "value = %lu",svalue);
} while (TRUE);
} |
This doesn´t work. It gives me no values for AD conversion.
What to do?Where is a mistake? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 11, 2009 3:03 pm |
|
|
Quote: | char display_data( long int data ) {
convert_to_volts( data, volt_string );
return volt_string;
} |
Your program doesn't compile. It gives this compiler error:
Quote: | Undefined identifier: volt_string |
You have not declared the variable 'volt_string'.
It also gives a compiler error on this line:
Quote: | printf(lcd_putc, "value = %lu",svalue); |
Here's the error message. You're giving it a pointer (svalue) and
using %lu as the format string, which is not correct:
Quote: | Printf format type is invalid :: |
So I doubt that you have really even tested this program.
Quote: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP, XT,PUT,NOBROWNOUT
#use delay(clock=4000000)
|
Here you are using HS and XT. For a 4 MHz crystal, you should use XT.
Don't use two oscillator fuses.
I think you have several problems in your code with pointers.
You have a complicated program that converts an analog value to volts.
Instead, look at this simple program, which converts an ADC value
from 0 to 1023 into volt, and displays it on an LCD:
http://www.ccsinfo.com/forum/viewtopic.php?t=32168&start=1
Try to re-write your program so it's very simple, as shown in the link
above.
In fact, looking further into it, I can see that you have modified the
code in the CCS example file, ex_ad12.c. The original CCS code
looks like this:
Code: | void display_data( long int data ) {
char volt_string[6];
convert_to_volts( data, volt_string );
printf(volt_string);
printf(" (%4lX)",data);
} |
Notice how volt_string is declared as an array. You don't do that in your
code. You have heavily changed the CCS code, and not for the better.
Either use my suggested code in the link, or use the CCS code.
Don't make all these changes to it.
changed the CC |
|
|
djole_nisam_ja
Joined: 10 Dec 2009 Posts: 18
|
|
Posted: Fri Dec 11, 2009 3:37 pm |
|
|
PCM programmer wrote: | Quote: | char display_data( long int data ) {
convert_to_volts( data, volt_string );
return volt_string;
} |
Your program doesn't compile. It gives this compiler error:
Quote: | Undefined identifier: volt_string |
You have not declared the variable 'volt_string'.
It also gives a compiler error on this line:
Quote: | printf(lcd_putc, "value = %lu",svalue); |
Here's the error message. You're giving it a pointer (svalue) and
using %lu as the format string, which is not correct:
Quote: | Printf format type is invalid :: |
So I doubt that you have really even tested this program.
Quote: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP, XT,PUT,NOBROWNOUT
#use delay(clock=4000000)
|
Here you are using HS and XT. For a 4 MHz crystal, you should use XT.
Don't use two oscillator fuses.
I think you have several problems in your code with pointers.
You have a complicated program that converts an analog value to volts.
Instead, look at this simple program, which converts an ADC value
from 0 to 1023 into volt, and displays it on an LCD:
http://www.ccsinfo.com/forum/viewtopic.php?t=32168&start=1
Try to re-write your program so it's very simple, as shown in the link
above.
In fact, looking further into it, I can see that you have modified the
code in the CCS example file, ex_ad12.c. The original CCS code
looks like this:
Code: | void display_data( long int data ) {
char volt_string[6];
convert_to_volts( data, volt_string );
printf(volt_string);
printf(" (%4lX)",data);
} |
Notice how volt_string is declared as an array. You don't do that in your
code. You have heavily changed the CCS code, and not for the better.
Either use my suggested code in the link, or use the CCS code.
Don't make all these changes to it.
changed the CC |
Yes, I have tried it, I made some changes and I haven´t tested it after that, so that is the reason for those mistakes. I know about char arrays, I just forgot to enter it.
It should be put:
Sorry for that.
As I said, I am not too familiar with PIC, so that´s the reason I didn´t know about oscillator fuses. Also, in the example you gave me, does it use internal PIC AD converter, or external onboard?
Thanks in advance |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 11, 2009 4:04 pm |
|
|
It uses the internal A/D converter, inside the PIC. |
|
|
|
|
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
|