// PIC18F14K50 in C - Versione 1.0 - Ottobre 2014 // Copyright (c) 2014 VincenzoV.net // Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported. // Creative Commons | Attribution-Share Alike 3.0 Unported // https://www.vincenzov.net/tutorial/PIC18/adc.htm // ADC (8 bit) - Interrupt (debug) #define VREF 3.20 #include "configurationbits.h" // Note: // #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) // #pragma config PLLEN = ON // 4 X PLL Enable bit (Oscillator multiplied by 4) // Define MyDEBUG (uncomment line) for debug e timing #define MyDEBUG #ifdef MyDEBUG #define ISR_RUNNING LATBbits.LB6 // If HIGH -> ISR is running #define MAIN_RUNNING LATBbits.LB4=1; LATBbits.LB4=0; #define START_ADC LATBbits.LB7 #endif #define SAMPLES 16 // Buffer size unsigned char volatile buffer[SAMPLES]; // Data samples from ADC unsigned int volatile samples_in_buffer; // How many samples un buffer? void display(unsigned voltage); void main(void) // Program start here { // Configure digital port TRISC = 0x00; // Port C as output #ifdef MyDEBUG TRISBbits.RB6 = 0; // RB6 as output - Timing e debug TRISBbits.RB4 = 0; // RB4 as output - Timing e debug TRISBbits.RB7 = 0; // RB7 as output - Timing e debug #endif // COnfigure ADC and analog port TRISBbits.RB5 = 1; // Disable digital output buffer on AN11/RB5 ANSELHbits.ANS11 = 1; // Disable digital input buffer for AN11 ADCON2bits.ADFM = 0; // Left justified ADCON2bits.ADCS = 0b110; // A/D Conversion Clock = FOSC/64 (1.33 us @ 48 MHz) ADCON2bits.ACQT = 0b001; // A/D Acquisition time set to 2 TAD ADCON1 = 0; // Set VDD and VSS as voltage reference ADCON0bits.CHS = 0b1011; // Analog Channel Select AN11 // Configure interrupt RCONbits.IPEN = 1; // Enable priority levels on interrupts PIE1bits.ADIE = 1; // Enable interrupt from ADC IPR1bits.ADIP = 1; // Set ADC high priority interrupt PIR1bits.ADIF = 0; // Clear interrupt status to avoid automatic interrupt ad "boot time" INTCONbits.GIEH = 1; // Enables high priority interrupts ADCON0bits.ADON = 1; // Power ON ADC ADCON0bits.GO = 1; // Start first conversion while (1) { #ifdef MyDEBUG MAIN_RUNNING // Timing e debug - Main is running #else display(buffer[samples_in_buffer]); #endif } } void display(unsigned voltage) { voltage = voltage + 16; voltage = (voltage >> 5); PORTC = ~(0xFF << voltage); } void interrupt __high_priority my_isr_high(void) { #ifdef MyDEBUG ISR_RUNNING = 1; // Start of interrupt time - Debug and timing #endif if (PIR1bits.ADIF) // Interrupt from ADC? { buffer[samples_in_buffer] = ADRESH; // Read ADC value - 8 bit #ifdef MyDEBUG START_ADC = 1; // Start ADC #endif ADCON0bits.GO = 1; // Start new conversion #ifdef MyDEBUG START_ADC = 0; // Start ADC #endif samples_in_buffer++; // Point to next buffer if (samples_in_buffer >= SAMPLES) { //PIE1bits.ADIE = 0; // Buffer full - Disable interrupt from ADC samples_in_buffer = 0; // Buffer full - Empty } PIR1bits.ADIF = 0; // Clear interrupt status } #ifdef MyDEBUG ISR_RUNNING = 0; // Stop of interrupt time - Debug and timing #endif }