I have trying to read analog data comes from adc. For this reason, I have write following porgram segments. Can you look at and say "what is wrong with it?" or "am I forget something which should be put ?" or "Should I initialize any I/O?".

tools ;

  • pic 18f4520
  • mplab x ide
  • sdcc

initialization part

ADCON0 = 0b00011101;       
ADCON1 = 0b00000111;       
ADCON2 = 0b10111010;       

read part


you are not following what is suggested in the datasheet, althought your register values seems to be correct. I suggest you to follow precisely the register writing order provided at page 227 of the datasheet:

that will be:

ADCON1 = 0b00000111;

ADCON0 |= 0b00011100;
ADCON0 &= 0b11011111;

ADCON2 = 0b10111010; 

ADCON0bits.ADON = 1;

Then you can poll the GO/DONE bit as you are doing. If this still does not work, try disabling the interrupts, that is:

INTCON &= 0b00111111;

If this still does not work you should give more informations about what exactly is not working.

  • \$\begingroup\$ It works. ALso, last question "How can I ensure that new data is read since the last read ? " In other words, how can I ensure that change is occured in adc ? \$\endgroup\$ – user5140 Dec 16 '12 at 11:38
  • 1
    \$\begingroup\$ Please don’t use signatures or taglines in your posts. electronics.stackexchange.com/faq#signatures \$\endgroup\$ – jippie Dec 16 '12 at 11:49
  • \$\begingroup\$ I am not sure I understand your question. When the converted value is ready, GO/DONE goes low. You should read the data, then set GO/DONE, perform whatever you need with the read data, and when GO/DONE is down again the new value is ready. \$\endgroup\$ – Vladimir Cravero Dec 16 '12 at 13:17

Whenever you are using an port as an analog input, you have to make sure that the port is properly configured using both the TRIS register and the ADCON1 register (or the CONFIG3H register for PortB<4:0>). By default, when the PIC18s reset, all port pins are automatically configured to be analog input (pending on the setting of the CONFIG3H register), but your firmware might have changed this setting prior to using the ADC module.

For instance, to set AN12 to be an analog input, you would need to do the following:

  1. Set the TRISB register, bit0, to 0x1 (AN12 is on port B0).
  2. Set PCFG of ADCON1 to 0x0.

For the lower nibble of PortB (PORTB<4:0>), and PBADEN bit of the CONFIG3H register can be set instead of playing with the TRIS settings:

PBADEN: PORTB A/D Enable bit 
(Affects ADCON1 Reset state. ADCON1 controls PORTB<4:0> pin configuration.)
1 = PORTB<4:0> pins are configured as analog input channels on Reset
0 = PORTB<4:0> pins are configured as digital I/O on Reset

By default, PBADEN is set to 1, but I do not know what SDCC sets this value if left unspecified.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy