William Roy
William Roy

Reputation: 141

PIC 16f1827 ADC Conversion too slow XC8

I followed this Tutorial and changed the code for my Micro-controller 16f1827. I also changed the function of the code. It should turn on a LED if the ADC Value is more than half of max. ADC Value and turn off a LED if less than half.

// CONFIG
#pragma config FOSC = HS      // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF     // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF    // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF    // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF      // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF      // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF      // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF       // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>
#include <pic16f1827.h>

#define _XTAL_FREQ 8000000

void ADC_Init()
{
  ADCON0 = 0x81;               //Turn ON ADC and Clock Selection
  ADCON1 = 0x00;               //All pins as Analog Input and setting Reference Voltages
}

unsigned int ADC_Read(unsigned char channel)
{
  if(channel > 7)              //Channel range is 0 ~ 7
    return 0;

  ADCON0 &= 0xC5;              //Clearing channel selection bits
  ADCON0 |= channel<<3;        //Setting channel selection bits
  __delay_ms(2);               //Acquisition time to charge hold capacitor
  GO_nDONE = 1;                //Initializes A/D conversion
  while(GO_nDONE);             //Waiting for conversion to complete
  return ((ADRESH<<8)+ADRESL); //Return result
}

void main()
{
  unsigned int a;
  TRISA = 0xFF;                 //Analog pins as Input
  TRISB = 0x00;                 //Port B as Output
  //TRISC = 0x00;                 //Port C as Output
  ADC_Init();                   //Initialize ADC

  do
  {
    a = ADC_Read(0);            //Read Analog Channel 0
    //PORTB = a;                  //Write Lower bits to PORTB
    //PORTC = a>>8;               //Write Higher 2 bits to PORTC


if(a > 512){
PORTBbits.RB7 = 1;
}else{
PORTBbits.RB7 = 0;
}


    __delay_ms(100);            //Delay
  }while(1);                    //Infinite Loop
}

The Code compiles without error in XC8. The problem is the PIC detects the ADC changes too slow. If I take the Input pin and connect it to the positive reference Value it turns on the LED with a Delay of maybe 2 Seconds. The same happens when I change the ADC Input to 0v. All changes are detected very slow. Why is the ADC working so slow?

Upvotes: 2

Views: 1153

Answers (1)

Mick
Mick

Reputation: 5197

The tutorial that you link to uses a PIC16F877A with an 8MHz crystal oscillator whereas you appear to be trying to use a PIC16F1827 with its internal oscillator instead of an external oscillator. It is not sufficient to just change the PIC header file as you have done. You must also set the required oscillator mode and take care of any other configuration options that differ between the two parts. I'm not certain, but I think that the default internal oscillator frequency for the 16F1827 is 1MHz, not 8MHz. This may go some way to explaining the problems that you are experiencing.

BTW: Don't be tempted to fudge your code. Make sure that you configure your microcontrollers correctly otherwise they will bite you on the bum sooner or later.

Upvotes: 3

Related Questions