Help with pic18f4550 A/D

Discussion in 'Embedded Systems and Microcontrollers' started by sankaud, Jun 28, 2010.

  1. sankaud

    Thread Starter New Member

    Jun 28, 2010
    Hi all,

    I 'm new to MCU's and I want some advice with the new project that I have started. the purpose of this project is to understand how A/D work in PIC based MCU's. I have already set up a Proteus sim module for this circuit and wrote picBasic Pro code for it, but I couldn't get it to work properly and the readings I'm getting, does not match with the DC multimeter. i have couple of questions if any of you guys can help,

    1: how can I configure any of the Pic18f4550's analog terminals to be a Analog input.

    2: how to configure it properly

    I will really appreciate your help.


    Define LOADER_USED 1
    Define OSC 48 ' Core is running at 48MHz

    DEFINE ADC_BITS 8 ' Set number of bits in result
    DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
    DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds

    adval var word

    ADCON1= %00001000
    TRISA = %00000000
    TRISB = %00001000
    TRISE = %0001

    Pause 500
    lcdout $FE, 1

    ADCIN 5, adval ' Read channel 0 to adval (0-1023)
    adval = (adval */ 500)>>2 ' equates to: (adval * 500)/1024
    LCDOut $FE,$80,"DC Volts= ",DEC (adval/100),".",DEC2 adval ' Display the decimal value

    'lcdout $FE, $C0, "Actual= ", #adval

    Goto mainloop ' Go back to loop and blink LED forever


  2. Vaughanabe13

    Active Member

    May 4, 2009
    OK, here's how to do it, but I don't know PicBasic so I'll just tell you how I do it in C18.

    1. Set up your ADC pins as analog. You do this by configuring the ADCON1 register. See page 262 of the datasheet for help with this. Make sure all of your ADC pins are set as analog.
    2. Now set your tristate registers so your ADC pins are high-impedance inputs. You do this by setting the corresponding TRIS bit for your analog pins. Example: If you want port A to be all inputs, you write TRISA = 0xff;
    3. Now you need to configure the ADC module for your specific test constraints. You need to specify the channel (analog pin that you are testing, where CH0 = AN0, etc.), the acquisition time, the operating frequency/prescaler, the interrupts (enabled or disabled), and the plus/minus voltage references. You do this by configuring the ADCON registers, as it explains in the datasheet. If you are using the C18 compiler you can do this using the OpenADC(/*arguments*/) library function.
    4. Make sure the ADC Enable bit is set to turn the ADC module on. Now start a conversion by setting the Go/Done bit of the ADCON register (I forget which one, check the datasheet) or by calling the ConvertADC() function.
    5. Poll the Go/Done bit until it is cleared, and keep looping while it is set. I use a while loop for this. After it is cleared, your conversion is done and the results can be read.
    6. Read the results into an integer. You can do this by using the ReadADC() function, or by reading the ADRESH and ADRESL registers. Your results will be a 10-bit number, either left-justified or right-justified depending on how you configured it. This means you will have a number from 0 to 1023, where 1023 represents your Vdd voltage, and 0 is obviously 0V.

    Here is sample code from one of my projects that I can verify works correctly. It is using the C18 compiler libraries, so you will need to modify this if you use something different.

    Code ( (Unknown Language)):
    1. //ADC reading with the PIC18F4550
    2. ADCON1 = 0b00001110;               //Set all pins to digital I/O except RA0/AN0. (page 262 of datasheet)
    3. TRISA  = 0b00000001;               // Set I/0 for PORTA
    6. ConvertADC();            //Get ADC reading of charged capacitor on pin RA0
    7. while ( BusyADC() );
    8. resultInt = ReadADC();  //Store result of ADC reading
    sankaud likes this.
  3. sankaud

    Thread Starter New Member

    Jun 28, 2010
    Thanks Vaughanabe for you time and effort, and I really appreciate it. I was trying to get one of the analog pins working on port E, it was unsuccessful and under simulation CUP load was around 90%. then I have changed everything back to port A as you said, and bang it worked. Thanks again.
  4. Vaughanabe13

    Active Member

    May 4, 2009
    That's bizarre, PORTE should function the same as PORTA as long as you have the TRIS bits sit for the pins you want as input, and the ADCON1 register setup to make those pins analog. But I'm glad you have it working.
  5. sankaud

    Thread Starter New Member

    Jun 28, 2010
    I'm slowly starting to realize how MCU's work now, by the way I am a Mechanical Engineer, so my knowledge of Electronics is limited. I also got another question. how do you go about doing decimal operations in PicBasic. it seems like bit hard to do general maths and display it on the LCD. Do you have any suggestions.