View previous topic :: View next topic |
Author |
Message |
Guest
|
A2D Conversion Not working |
Posted: Mon Mar 02, 2009 11:13 am |
|
|
I cant get my analog to digital conversion working for PIC18F4520. Im watching "value" in MPLAB and it stays at zero.
Code: | #include <18F4520.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC //Internal RC Osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <float.h>
#include <math.h>
#include <stdio.h>
int16 value;
void main()
{
setup_adc_ports(AN0_TO_AN1|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32 );
setup_psp(PSP_DISABLED);
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_16);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
While(1)
{
set_adc_channel(0);
delay_us(100);
value=read_adc();
delay_ms(1000);
}
} |
Im trying to read a variable pot attached to A0. |
|
|
andreluizeng
Joined: 04 Apr 2006 Posts: 117 Location: Brasil
|
|
Posted: Mon Mar 02, 2009 11:39 am |
|
|
If you are not external supplying the ADC clock you need to configure the internal clock to work
try changing
Code: |
setup_adc(ADC_CLOCK_DIV_32 );
|
by
Code: |
setup_adc(ADC_CLOCK_INTERNAL);
|
and make sure that your pic is working, try blink some LED, because Im not comfortable with some used fuses like:
Code: |
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
|
it sometimes can cause serious conflicts with another internal peripherals.
regards
André _________________ Andre |
|
|
Guest
|
|
Posted: Mon Mar 02, 2009 11:54 am |
|
|
Replaced origonal with setup_adc(ADC_CLOCK_INTERNAL); Tested blinking LED with success. Still "value is reading zero". Using the watch function in the view menu of MPLAB. |
|
|
andreluizeng
Joined: 04 Apr 2006 Posts: 117 Location: Brasil
|
|
Posted: Mon Mar 02, 2009 12:03 pm |
|
|
are you sure that read_adc makes the desired pin connected to the adc channel as input ??? if not... try setting up your port A pins as input (set_tris function)
regards _________________ Andre |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 02, 2009 12:04 pm |
|
|
Are you running this in the MPLAB simulator, or with an ICD2 debugger ?'
How are you testing this ? What board are you using ? |
|
|
Guest
|
|
Posted: Mon Mar 02, 2009 12:24 pm |
|
|
I have a ICD3 and after reading what u said I outputted my "value" through rs232 to computer and I'm getting different numbers when I change the pot so for now i will assume its working . Also I am just using a standard breadboard for all my hookup including chip. I don't think I was using the "watch" feature in MPLAB correctly. Now that I'm getting values out I want to translate that into a voltage. Here my calcs:
10 bit ADC so resolution is (Vdd/2^10) to get voltage just multiply that by my value stored in value. Correct? |
|
|
andreluizeng
Joined: 04 Apr 2006 Posts: 117 Location: Brasil
|
|
Posted: Mon Mar 02, 2009 12:29 pm |
|
|
yes... it is correct.
regards. _________________ Andre |
|
|
Guest
|
|
Posted: Tue Mar 03, 2009 8:35 am |
|
|
Ok I found that I had a couple things incorrect when I was displaying the value. Here is my modified code:
Code: |
int16 value;
float voltage;
void main()
{
setup_adc_ports(AN0_TO_AN1|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_16);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(OSC_4MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
While(1)
{
set_adc_channel(0);
delay_us(100);
value=read_adc();
delay_ms(1000);
voltage=(value*.00494624); //if i use value*(5/1023); it will display 0 on printout.
//voltage=(value*(5/1023)); //if i use value*(5/1023);
printf("total %lx voltage %lf \r\n",value, voltage);
}
} |
Questions:
1. Why doesn't the second voltage calculations where i divide only display 0's?
2. Does anyone know where to find the information found in the printF statement such as %lx,%lf I search the forums to get them and I am wondering if there is a good place to find them. I check the maunual and didn't see them. |
|
|
andreluizeng
Joined: 04 Apr 2006 Posts: 117 Location: Brasil
|
|
Posted: Tue Mar 03, 2009 8:46 am |
|
|
Code: |
//voltage=(value*(5/1023)); //if i use value*(5/1023);
|
you need to "tell" that you are treating with float numbers, or else you only will take 0'z
try
Code: |
voltage=(value*(5.0/1023));
|
or
Code: |
voltage=(value*( (float)5/ (float)1023));
|
regards. _________________ Andre |
|
|
|