2013-04-04 98 views
0

我正在努力使ADC與我的設備一起工作。我正在使用dsPIC33FJ128GP802,並嘗試從手動採樣和轉換開始慢。ADC dsPIC33問題

我的代碼張貼在下面,我已經設置了ADC的每個寄存器,然後嘗試僅採樣一次,以獲取來自已連接的傳感器的電壓。我應該看到的價值在0.7V左右,但我得到的是在-17408(10111100 00000000)的區域。這可能會上升到-2000左右,但首先這個值不應該是負值。

#include <p33Fxxxx.h> 

_FOSCSEL(FNOSC_FRCPLL) // select internal 7.37MHz osc with PPL 
_FOSC(OSCIOFNC_OFF & POSCMD_XT) // no clock output, external OSC disabled 
_FWDT(FWDTEN_OFF) // disable the watchdog timer 
_FPOR(FPWRT_PWR1) // Turn off the power-up timers. 

int ADCValue; 

void DELAY(unsigned ms) { 
    unsigned j; 
    unsigned i; 
    for (j = 0; j < ms; j++) { 
     for (i = 0; i < 0x1F40; i++); 
    } 
} 

int main(void) { 

    // set up clock to 80MHz 
    PLLFBD = 41; // sets M = 41+2 = 43 
    CLKDIVbits.PLLPRE = 0; // sets N1 = 2 
    CLKDIVbits.PLLPOST = 0; // sets N2 = 2 
    while (!OSCCONbits.LOCK); // wait for PLL ready 

    AD1CON1 = 0; // set everything to zero to start with. 
    AD1CON1bits.ADON = 0; // turn ADC off. 
    AD1CON1bits.ADSIDL = 0; // continue module operation in idle mode. 
    AD1CON1bits.ADDMABM = 1; // DMA buffers are written in the order of conversion. 
    AD1CON1bits.AD12B = 0; // set to 10bit mode. 
    AD1CON1bits.FORM = 3; // set data output to signed fractional. 
    AD1CON1bits.SSRC = 0; // manual conversion. clearing sample bit manually. 
    AD1CON1bits.SIMSAM = 1; // collect samples from channels 0, 1, 2, 3 simultaneously. 
    AD1CON1bits.ASAM = 0; // manual sample. samples when SAMP bit is set. 
    AD1CON1bits.SAMP = 0; // sample enable bit. 
    AD1CON1bits.DONE = 0; // ADC conversion status bit. 

    AD1CON2 = 0; // set everything to zero to start with. 
    AD1CON2bits.VCFG = 0; // converter voltage ref. set to AVdd and AVss. 
    AD1CON2bits.CSCNA = 0; // input scan select bit. set to do not scan. 
    AD1CON2bits.CHPS = 0; // channel select bits. set to just channel 0; 
    AD1CON2bits.BUFS = 0; // buffer fill status (invalid as BUFM is 0); 
    AD1CON2bits.SMPI = 0; // ADC interrupt is generated after every sample/conversion. 
    AD1CON2bits.BUFM = 0; // buffer fill mode. set to always start filling from start address. 
    AD1CON2bits.ALTS = 0; // Alternate input sample mode. set to always uses channel input from sample A. 

    AD1CON3 = 0; // set everything to zero to start with. 
    AD1CON3bits.ADRC = 0; // ADC conversion clock derived from system clock. 
    AD1CON3bits.SAMC = 0; // auto sample time bits, TAD, set to 0. 
    AD1CON3bits.ADCS = 0; // ADC conversion clock set to 0. 1 * TCY = TAD. 

    AD1CON4 = 0; // set everything to zero to start with. 
    AD1CON4bits.DMABL = 0; // allocates 1 word of buffer to each analogue input. 

    AD1CHS123 = 0; // everything set to zero as not using channels 1, 2, or 3. 

    AD1CHS0 = 0; // set everything to zero to start with. 
    AD1CHS0bits.CH0NB = 0; // channel 0 negative input, set by CH0NA. sample B. 
    AD1CHS0bits.CH0SB = 0; // channel 0 positive input, set by CH0SA. sample B. 
    AD1CHS0bits.CH0NA = 0; // channel 0 negative input, for sample A. set to VREFL. 
    AD1CHS0bits.CH0SA = 0; // channel 0 positive input is AN0. 

    AD1CSSL = 0; // input scan register set to zero as not using it. 

    AD1PCFGL = 0; // port configuration, set to analogue mode, ADC samples voltage. 

    AD1CON1bits.ADON = 1; // turn on ADC 

    AD1CON1bits.SAMP = 1; // Start sampling 
    DELAY(1); // Wait for sampling time (1ms) 
    AD1CON1bits.SAMP = 0; // Start the conversion 
    while (!AD1CON1bits.DONE); // Wait for the conversion to complete 
    ADCValue = ADC1BUF0; // Read the conversion result 

    while (1); 

} 

我有使用PIC是使用相同的導軌供電傳感器,和我有傳感器的輸出,以AN0(引腳2),如在我的代碼設置。 PIC通過標準Vss和Vdd(引腳8和13),模擬電源引腳AVdd和AVss(引腳28和27)以及Vcap和Vss(引腳20和19)上的33uF電容供電。還有什麼我需要硬件明智嗎?我對AD1CHS0bits.CH0NA寄存器有點困惑,因爲我不知道是否必須將地連接到VREFL或在這種情況下做什麼。

任何幫助,我應該做什麼來糾正這個問題將不勝感激!此外,一旦正確接收到值,如何轉換該值的任何幫助都將非常有用。

+0

如果你不覺得值應該是否定的,不要使用'int'。您的位模式解釋爲'unsigned int'爲48128. – unwind 2013-04-04 11:28:20

+1

@unwind:如果代碼中的註釋是準確的,那麼數據的輸出格式是帶符號的定點格式。轉換緩衝器中的輸出值範圍從-1.0到+1.0,代表從參考低電平到參考高電平的電壓範圍。如果OP僅爲參考低電平提供0V,那麼他可能需要使用無符號小數格式以及在C代碼中使用無符號數據類型。就目前而言,-17408可以被32768除以-1.0至1.0,然後將AVS線性縮放到AVdd(我假設3V3)給出的值爲0.77。使用3V給出0.7V。 – tinman 2013-04-04 11:51:04

+0

你運行PIC的電壓是多少? – tinman 2013-04-04 11:51:29

回答

1

如果該值不應該是否定的,開始時,那麼你不應該使用此設置:

AD1CON1bits.FORM = 3; // set data output to signed fractional. 

是你,我希望你的價值是(進行評價使用Python):

int((2**10) *  # 10-bit operation 
    (0.7/3.3)  # 0.7 volts on a 3.3 volt system 
    - (2**9)  # Center at VDD/2 because of signed operation 
    ) << 6   # Fractional output left-shifted the 10-bit up by 6 to fill 16-bits 
= -18816 

這聽起來代表你的代碼輸出。

而是使用:

AD1CON1bits.FORM = 0; // set data output to integer. 

使用此設置,以10位模式一起,我希望你的價值是

int((2**10) *  # 10-bit operation 
    (0.7/3.3))  # 0.7 volts on a 3.3 volt system 
= 217