2

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?

William Roy
  • 141
  • 7
  • Can you post the contents of `__delay_ms()`? That is probably the source of the extra time. Is your crystal actually 8 MHz? Are there registers you need to setup for the clock to be properly configured? – rjp Aug 30 '16 at 21:28
  • This is my complete code in my project of MPLAB X. I don't have a crystal I just use the bare IC. – William Roy Aug 30 '16 at 21:32
  • I would consult the documentation for the library providing `__delay_ms()` and make sure that the isn't some configuration that isn't properly set at compile time. You are attempting to delay 100 ms between iterations of the loop, but you're seeing ~2 seconds, so there is probably a difference between how the `__delay_ms()` function is determining how many loop iterations to burn through, and how quickly the micro is actually executing them. – rjp Aug 30 '16 at 21:39
  • __delay_ms() is in the standard pic.h: #define __delay_ms(x) _delay((unsigned long) ((x)*(_XTAL_FREQ/4000.0))) How will this affect the delay if I don't have an external crystal? – William Roy Aug 30 '16 at 21:42
  • I'm not enough of a PIC user to be able to tell you. – rjp Aug 30 '16 at 22:00
  • You have to define the crystal frequency in your code for the delay to work correctly. I believe tris is in the users guide. – Cobusve Aug 31 '16 at 04:54
  • Just make one example code that blinks LED at specified time and to define that time use __delay_ms() function and if your LED blinking is not following delay_ms function value then you should have a look at your clock configuration. – HallMark Aug 31 '16 at 13:07

1 Answers1

3

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.

Mick
  • 4,987
  • 1
  • 19
  • 23