//Program to test ADC principles //One ADC input triggering two LEDs to show if voltage is above or below threshhold set in program //Written for PIC12F683 to be compiled with the CC5X compiler //Clock frequency left at 4MHz default //Copyright David Theunissen 2007 www.flyelectric.ukgateway.net //PREPROCESSOR section #include "12F683.H" //PIC chip file #include "delay_ms.h" //Delay function used below #pragma config = 0b.0.1100.0100 //Brown-out Detect disabled (0) //Code Protect off (1) //MCLR set to 'Internal' (1) //Powerup timer enabled (0) //Watchdog timer disabled (0) //Oscillator set to INTRCIO (100) //VARIABLES section #define LED_HIGH GPIO.0 //Define pin7 as voltage 'high' LED #define LED_LOW GPIO.2 //Define pin5 as voltage 'low' LED long ADC_VALUE_1; //Set variable for ADC value of 'pack1' (16bits) long ADC_TEMP; //Temporary variable for extracting high bits of ADRESH register //FUNCTIONS section void main() { //Main port settings TRISIO0 = 0; //Sets GP ports to Output (0) and Input (1) TRISIO2 = 0; //as above TRISIO3 = 1; //ADC input ANS0 = 0; //Sets ADC port to digital (Output=0) or analogue (Input=1) ANS2 = 0; //as above ANS3 = 1; //ADC input CMCON0 = 0b.111; //Switches all 3 comparator ports off //ADC settings ADCON0.6 = 0; //VCFG: Use Vdd for ADC voltage reference ANSEL.4 = 1; //ADCS: Set AD Conversion Clock to Fosc/16 ANSEL.5 = 0; //part of above ANSEL.6 = 1; //part of above ADCON0.7 = 1; //ADFM: Right-justify ADC register //Activate ADC ADCON0.0 = 1; //ADON: Turn AD module ON ADCON0.2 = 1; //CHS0: Select input channel to ANS3 only ADCON0.3 = 1; //part of above ADIE = 0; //ADC interrupts disabled while(1) //Run ADC continuously { //Run ADC delay_ms(1); //Delay for acquisition capacitor to charge ADIF = 0; //Clear the ADC Complete flag ADCON0.1 = 1; //GO: Start ADC acquisition while(!ADIF) continue; //Wait for conversion to complete (ADIF gets set to 1) //Determine complete ADC value ADC_TEMP = ADRESH; //The ADC produces a 10bit value stored in two 8bit registers //ADRESH contains the higher 2 bits of the ADC conversion value //This statement moves that value from an 8bit register to 16bit ADC_TEMP = ADC_TEMP<<8; //<<8 moves all bits 8 places left (hence the need for 16bits) //The upper 2 bits are now in ADC_TEMP in bits 9 and 10 ADC_VALUE_1 = ADC_TEMP|ADRESL; //| is the OR operator to merge lower 8 bits with upper 2 //Indicate result via LEDs if (ADC_VALUE_1 >= 512) //Have 1k pot and 1k resistors either side (3k total) dividing '5v' Vdd //Actual voltages range from 1.652 to 3.226v (Vdd=4.93v) //ADC values range from 335 to 662 { LED_HIGH = 1; //'High' LED on (pin7) LED_LOW = 0; //'Low' LED off } else { LED_HIGH = 0; //'High' LED off LED_LOW = 1; //'Low' LED on (pin5) } //Delay to 'debounce' cross-over delay_ms(50); //Invokes delay function (eg: 50ms = 0.05 second) } //end while } //end main