// PIC18F14K50 in C - Versione 0.7a - Febbraio 2012 // Copyright (c) 2010-2012 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/elettronica-di-base/PIC18F14K50 // Using internal ADC - Interrupt #include #pragma config FOSC = HS // External crystal oscillator (12 MHz) #pragma config PLLEN = ON // Oscillator multiplied by 4 (48 MHz) #pragma config WDTEN = OFF // Watchdog disabled #pragma config LVP = OFF // Disable Low Voltage Programming #pragma config MCLRE = ON // Master clear enabled void High_Int (void); // ISR function prototype unsigned char volatile AD_high; // AD data buffer 2 MSB bits + data ready (1xxx xxx) unsigned char volatile AD_low; // AD data buffer 8 LSB bits unsigned char volatile AD_done_flag; // AD data in buffer #pragma code high_vector = 0x08 // Setup interrupt vector void interrupt (void) { _asm GOTO High_Int _endasm } // Jump to ISR function (in-line assembler) #pragma code // Back to normal code #pragma interrupt High_Int void High_Int (void) { //PORTCbits.RC4 = 1; // RC4 up: start of interrupt time - Debug and timing if (PIR1bits.ADIF ) // Interrupt from ADC? {AD_high = ADRESH; // Get high 2 bits and save in buffer AD_low = ADRESL; // Get low 8 bits and save in buffer AD_done_flag = 1; // Data in buffer ADCON0bits.GO = 1; // Start new conversion PIR1bits.ADIF = 0; // Clear interrupt status } //PORTCbits.RC4 = 0; // RC4 up: stop of interrupt time - Debug and timing } void main(void) { unsigned int voltage; TRISC = 0x00; // Set PORTC as Output ANSEL = 0; // Set as Digital I/O ANSELH = 0; // Set as Digital I/O TRISBbits.TRISB4 = 1; // Set RB4 (pin 13, aka AN10) to input ANSELHbits.ANS10 = 1; // Set AN10 (pin 13, aka RB4) to analog ADCON0=0b00101001; // Channel AN10 (xx10 10xx), Enable ADC (xxxx xxx1) ADCON1=0b00000000; // VDD and VSS as voltage reference (xxxx 0000) ADCON2=0b10001110; // Right justify result (1xxx xxx), 2 TAD delay (xx00 1xxx), TAD = 1.33 us (Fck/64 = 0.75 Mhz) (xxxx x110) RCONbits.IPEN = 1; // Enable priority levels on interrupts PIE1bits.ADIE = 1; // Enable interrupt from ADC IPR1bits.ADIP = 1; // Set high priority interrupt PIR1bits.ADIF = 0; // Clear interrupt status to avoid automatic interrupt ad "boot time" INTCONbits.GIEH = 1; // Enables high priority interrupts ADCON0bits.GO = 1; // Start first conversion while (1) { //PORTCbits.RC5 = 0; // RC5 down: idle time - Debug and timing while (!AD_done_flag); // Wait new data from ADC //PORTCbits.RC5 = 1; // RC5 up: running time - Debug and timing voltage = ( (unsigned int)AD_high << 8) + AD_low; // Convert data from ADC to 0-1023 integer AD_done_flag=0; // Clear semaphore PORTC = (voltage >> 6) & 0x0F; // Display 4 MSB } }