PIC24FV32KA302 C16 ADC Help Needed - Page 1
Forum section: electronics / general

author: kolbep
author_rank: Frequent Contributor
timestamp: April 28, 2015, 05:56:25 pm
content: Hi AllI am trying to read the ADC on a pin, and output that reading over the UART to hyperterminal, but it hangs at the point where it checks if the conversion is done (ie while(!AD1CON1bits.DONE)If I comment out that line, and put a 1000ms Delay in (I read a few places that some of the Silicon for V4 of this chip does not update that flag right), then I just continously get a result of 1019, no matter if the pins are floating, or if I tie them to Vcc.....Any help would be appreciatedOh, and the code isCode:/** File: MAIN.c* Author: Peter** Created on 25 April 2015, 10:53*/#define FCY 4000000 //OSC Frequency for Delay#define FOSC 8000000L#include <stdio.h>#include <stdlib.h>#include "p24FV32KA302.h"#include <libpic30.h>#include <xc.h>#include <uart.h>#define USE_AND_OR /* To enable AND_OR mask setting */// FBS#pragma config BWRP = OFF // Boot Segment Write Protect (Disabled)#pragma config BSS = OFF // Boot segment Protect (No boot program flash segment)// FGS#pragma config GWRP = OFF // General Segment Write Protect (General segment may be written)#pragma config GSS0 = OFF // General Segment Code Protect (No Protection)// FOSCSEL#pragma config FNOSC = FRC // Oscillator Select (Fast RC Oscillator (FRC))#pragma config SOSCSRC = DIG // SOSC Source Type (Digital Mode for use with external source)#pragma config LPRCSEL = HP // LPRC Oscillator Power and Accuracy (High Power, High Accuracy Mode)#pragma config IESO = ON // Internal External Switch Over bit (Internal External Switchover mode enabled (Two-speed Start-up enabled))// FOSC#pragma config POSCMOD = NONE // Primary Oscillator Configuration bits (Primary oscillator disabled)#pragma config OSCIOFNC = OFF // CLKO Enable Configuration bit (CLKO output signal is active on the OSCO pin)#pragma config POSCFREQ = HS // Primary Oscillator Frequency Range Configuration bits (Primary oscillator/external clock input frequency greater than 8MHz)#pragma config SOSCSEL = SOSCHP // SOSC Power Selection Configuration bits (Secondary Oscillator configured for high-power operation)#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Both Clock Switching and Fail-safe Clock Monitor are disabled)// FWDT#pragma config WDTPS = PS32768 // Watchdog Timer Postscale Select bits (1:32768)#pragma config FWPSA = PR128 // WDT Prescaler bit (WDT prescaler ratio of 1:128)#pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT disabled in hardware; SWDTEN bit disabled)#pragma config WINDIS = ON // Windowed Watchdog Timer Disable bit (Standard WDT selected(windowed WDT disabled))// FPOR#pragma config BOREN = BOR3 // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware, SBOREN bit disabled)#pragma config LVRCFG = OFF // (Low Voltage regulator is not available)#pragma config PWRTEN = ON // Power-up Timer Enable bit (PWRT enabled)#pragma config I2C1SEL = PRI // Alternate I2C1 Pin Mapping bit (Use Default SCL1/SDA1 Pins For I2C1)#pragma config BORV = V20 // Brown-out Reset Voltage bits (Brown-out Reset set to lowest voltage (2.0V))#pragma config MCLRE = ON // MCLR Pin Enable bit (RA5 input pin disabled,MCLR pin enabled)// FICD#pragma config ICS = PGx1 // ICD Pin Placement Select bits (EMUC/EMUD share PGC1/PGD1)// FDS#pragma config DSWDTPS = DSWDTPSF // Deep Sleep Watchdog Timer Postscale Select bits (1:2,147,483,648 (25.7 Days))#pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select bit (DSWDT uses Low Power RC Oscillator (LPRC))#pragma config DSBOREN = ON // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR enabled in Deep Sleep)#pragma config DSWDTEN = ON // Deep Sleep Watchdog Timer Enable bit (DSWDT enabled)unsigned char uart_RX;unsigned int i;void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void){uart_RX = U1RXREG; //Move UART RX buffer to a variableasm("NOP"); //NOP for a breakpointIFS0bits.U1RXIF = 0; // Clear UART Interrupt Flag}void Test_ADC1(void){AD1CON1=0;// clear configAD1CHS = 0; // setup ADC channel// AD1PCFGLbits.PCFG1 = 0; //Does not exist on this PICANSA=0xFF; //SET ANALOGUE PORTS ONANSB=0xFF; //DittoAD1CSSL = 0;//No scanned inputsAD1CON1 = 0x0E4;//auto sample start, auto-convertAD1CON2 = 0;//AVdd, AVss, int every conversion, MUXA onlyAD1CON3 = 0x1F05;//31 Tad auto-sample, Tad = 5*TcyAD1CON1bits.ADON=1;// switch ON ADCwhile(!AD1CON1bits.DONE); // Wait for conversion to complete// __delay_ms(1000);int presult=ADC1BUF0;// read ADC valueprintf("%u\n", presult);printf(".\r\n");}int main(int argc, char** argv) {TRISA=0xffff; //ALL INSTRISB=0xffff; //ALL INSConfigIntUART1( UART_RX_INT_EN &UART_RX_INT_PR4 &UART_TX_INT_DIS);OpenUART1( UART_EN &UART_IDLE_CON &UART_DIS_WAKE &UART_DIS_LOOPBACK &UART_DIS_ABAUD &UART_NO_PAR_8BIT &UART_1STOPBIT &UART_IrDA_DISABLE &UART_MODE_SIMPLEX &UART_UEN_00 & //U1TX AND U1RX pins onlyUART_UXRX_IDLE_ONE &UART_BRGH_FOUR,UART_INT_TX_EACH_CHAR &UART_IrDA_POL_INV_ZERO &UART_SYNC_BREAK_DISABLED &UART_TX_ENABLE &UART_INT_RX_CHAR &UART_ADR_DETECT_DIS &UART_RX_OVERRUN_CLEAR,105);__delay_ms(1000);while(i<100){printf("\r\n");i++;};printf("PETER, This is your PIC speaking...\r\n");__delay_ms(2000);printf ("That is fine, I will flash my lights while I wait\r\n");__delay_ms(1000);printf("\r\n");while(1){printf("ADC RESULT ");Test_ADC1();//printf("%s",ADCResult);printf(" OK\r\n");LATAbits.LATA0=0;__delay_ms(1000);LATAbits.LATA0=1;__delay_ms(1000);};return (EXIT_SUCCESS);}

author: mikerj
author_rank: Super Contributor
timestamp: April 28, 2015, 06:53:39 pm
content: The DONE bit never clears because you haven't actually started a conversion. AD1CON1bits.ADON enables the ADC peripheral, but to start a conversion you have to set AD1CON1bits.SAMP = 1

author: kolbep
author_rank: Frequent Contributor
timestamp: April 29, 2015, 07:16:47 pm
content: Thanks for that.Between your advice of the SAMP bit, and also using the Interrupt Flag (yes, this chip indeed suffers from the DONE bit not being set bug), I have made some changes to my code.The result I get out of the ADC is 4095 (when pulling that pin up to the 4.95v rail), so I took 4095/4.95, and that is the value I am dividing the ADC result by, to get a Real-World voltage value.I hooked up a pot between Vcc and GND, and as I adjust the pot, the values I am now getting correspond with my cheap $9.00 multimeter.So I am getting on with this project now.But switching from the 8Bit PIC18f2420 to this 16 Bit monster has been a Big Learning Curve.Next Step is to get an SD Card interface going (Think along the lines of a 3 Phase Voltage, Current and Temperature Logger)...

author: kolbep
author_rank: Frequent Contributor
timestamp: April 29, 2015, 07:27:26 pm
content: Code:/** File: MAIN.c* Author: Peter** Created on 25 April 2015, 10:53*/#define FCY 4000000 //OSC Frequency for Delay#define FOSC 8000000L#include <stdio.h>#include <stdlib.h>#include "p24FV32KA302.h"#include <libpic30.h>#include <xc.h>#include <uart.h>#define USE_AND_OR /* To enable AND_OR mask setting */// FBS#pragma config BWRP = OFF // Boot Segment Write Protect (Disabled)#pragma config BSS = OFF // Boot segment Protect (No boot program flash segment)// FGS#pragma config GWRP = OFF // General Segment Write Protect (General segment may be written)#pragma config GSS0 = OFF // General Segment Code Protect (No Protection)// FOSCSEL#pragma config FNOSC = FRC // Oscillator Select (Fast RC Oscillator (FRC))#pragma config SOSCSRC = DIG // SOSC Source Type (Digital Mode for use with external source)#pragma config LPRCSEL = HP // LPRC Oscillator Power and Accuracy (High Power, High Accuracy Mode)#pragma config IESO = ON // Internal External Switch Over bit (Internal External Switchover mode enabled (Two-speed Start-up enabled))// FOSC#pragma config POSCMOD = NONE // Primary Oscillator Configuration bits (Primary oscillator disabled)#pragma config OSCIOFNC = OFF // CLKO Enable Configuration bit (CLKO output signal is active on the OSCO pin)#pragma config POSCFREQ = HS // Primary Oscillator Frequency Range Configuration bits (Primary oscillator/external clock input frequency greater than 8MHz)#pragma config SOSCSEL = SOSCHP // SOSC Power Selection Configuration bits (Secondary Oscillator configured for high-power operation)#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Both Clock Switching and Fail-safe Clock Monitor are disabled)// FWDT#pragma config WDTPS = PS32768 // Watchdog Timer Postscale Select bits (1:32768)#pragma config FWPSA = PR128 // WDT Prescaler bit (WDT prescaler ratio of 1:128)#pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT disabled in hardware; SWDTEN bit disabled)#pragma config WINDIS = ON // Windowed Watchdog Timer Disable bit (Standard WDT selected(windowed WDT disabled))// FPOR#pragma config BOREN = BOR3 // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware, SBOREN bit disabled)#pragma config LVRCFG = OFF // (Low Voltage regulator is not available)#pragma config PWRTEN = ON // Power-up Timer Enable bit (PWRT enabled)#pragma config I2C1SEL = PRI // Alternate I2C1 Pin Mapping bit (Use Default SCL1/SDA1 Pins For I2C1)#pragma config BORV = V20 // Brown-out Reset Voltage bits (Brown-out Reset set to lowest voltage (2.0V))#pragma config MCLRE = ON // MCLR Pin Enable bit (RA5 input pin disabled,MCLR pin enabled)// FICD#pragma config ICS = PGx1 // ICD Pin Placement Select bits (EMUC/EMUD share PGC1/PGD1)// FDS#pragma config DSWDTPS = DSWDTPSF // Deep Sleep Watchdog Timer Postscale Select bits (1:2,147,483,648 (25.7 Days))#pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select bit (DSWDT uses Low Power RC Oscillator (LPRC))#pragma config DSBOREN = ON // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR enabled in Deep Sleep)#pragma config DSWDTEN = ON // Deep Sleep Watchdog Timer Enable bit (DSWDT enabled)unsigned char uart_RX;unsigned int i;void __attribute__((__interrupt__, no_auto_psv)) _U1RXInterrupt(void){uart_RX = U1RXREG; //Move UART RX buffer to a variableasm("NOP"); //NOP for a breakpointIFS0bits.U1RXIF = 0; // Clear UART Interrupt Flag}void Test_ADC1(void){AD1CON1=0b1010010000000000;AD1CON2=0;AD1CON3=0b0001111100000101;AD1CHS = 1;AD1CON1bits.SAMP=1;if (!IFS0bits.AD1IF); //WAIT FOR ADCfloat presult=ADC1BUF0;// read ADC valuepresult=presult/822.28915662650602409638; //CONVERT 0-4095 to 0-4.97printf("%f\n", presult);// printf(".\r\n");}int main(int argc, char** argv) {TRISA=0x02; //ALL OUT EXCEPT ANA1TRISB=0xffff; //ALL INSConfigIntUART1( UART_RX_INT_EN &UART_RX_INT_PR4 &UART_TX_INT_DIS);OpenUART1( UART_EN &UART_IDLE_CON &UART_DIS_WAKE &UART_DIS_LOOPBACK &UART_DIS_ABAUD &UART_NO_PAR_8BIT &UART_1STOPBIT &UART_IrDA_DISABLE &UART_MODE_SIMPLEX &UART_UEN_00 & //U1TX AND U1RX pins onlyUART_UXRX_IDLE_ONE &UART_BRGH_FOUR,UART_INT_TX_EACH_CHAR &UART_IrDA_POL_INV_ZERO &UART_SYNC_BREAK_DISABLED &UART_TX_ENABLE &UART_INT_RX_CHAR &UART_ADR_DETECT_DIS &UART_RX_OVERRUN_CLEAR,105);__delay_ms(1000);while(i<100){printf("\r\n");i++;};printf("PETER, This is your PIC speaking...\r\n");__delay_ms(100);printf ("That is fine, I will flash my lights while I wait\r\n");__delay_ms(100);printf("\r\n");while(1){printf("ADC RESULT ");Test_ADC1();//printf("%s",ADCResult);// printf(" OK\r\n");// LATAbits.LATA0=0;// __delay_ms(50);// LATAbits.LATA0=1;// __delay_ms(50);};return (EXIT_SUCCESS);}

author: mikerj
author_rank: Super Contributor
timestamp: May 01, 2015, 06:48:34 am
content: Quote from: kolbep on April 29, 2015, 07:27:26 pmI'm surprised that works as it's not waiting for a conversion to complete. The second line above should be:while (!IFS0bits.AD1IF);