0

ADC を自分のデバイスで動作させるのに苦労しています。私は dsPIC33FJ128GP802 を使用しており、手動のサンプリングと変換でゆっくりと開始しようとしました。

私のコードは以下に掲載されています.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 間の 33uF コンデンサ (ピン 20 と 19) に電力を供給されます。ハードウェア的に他に何かする必要がありますか? AD1CHS0bits.CH0NA レジスタと少し混乱しています。グランドを VREFL に接続する必要があるかどうか、またはその場合に何をすべきかがわからないためです。

この問題を修正するために何をすべきかについての助けをいただければ幸いです。また、正しく受け取った値を変換する方法についてのヘルプは非常に役立ちます。

4

1 に答える 1

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
于 2013-08-25T21:17:09.970 に答える