2017年4月25日火曜日

pic24 adcレジスタ


pic24 adc レジスタ


adc manual

registors

funcをマウスでホバーすると、パラメタを表示する
ad1con1

電源 フォーマット スタート

bit name func
15 ADON: A/D Operating Mode bit(1)
14 Unimplemented: Read as ‘0’
13 ADSIDL: A/D Stop in Idle Mode bit
12-10 Unimplemented: Read as ‘0’
9-8 FORM<1:0>: Data Output Format bits
7-5 SSRC<2:0>: Conversion Trigger Source Select bits
4-3 Unimplemented: Read as ‘0’
2 ASAM: A/D Sample Auto-Start bit
1 SAMP: A/D Sample Enable bit
0 DONE: A/D Conversion Status bit

ad1con2

リファレンス バッファ

bit name func
15-13 VCFG<2:0>: Voltage Reference Configuration bits
12-11 Unimplemented: Read as ‘0’
10 CSCNA: Scan Input Selections for CH0+ S/H Input for MUX A Input Multiplexer Setting bit
9-8 Unimplemented: Read as ‘0’
7 BUFS: Buffer Fill Status bit (valid only when BUFM = 1)
6 Unimplemented: Read as ‘0’
5-2 SMPI<3:0>: Sample/Convert Sequences Per Interrupt Selection bits
1 BUFM: Buffer Mode Select bit
0 ALTS: Alternate Input Sample Mode Select bit

ad1con3

タイミング

bit name func
15 ADRC: A/D Conversion Clock Source bit
14-13 Unimplemented: Read as ‘0’
12-8 SAMC<4:0>: Auto-Sample Time bits
7-0 ADCS<7:0>: A/D Conversion Clock Select bits

ad1chs

マルチプレクサ

bit name func
15 CH0NB: Channel 0 Negative Input Select for MUX B Multiplexer Setting bit
11-8 CH0SB<3:0>: Channel 0 Positive Input Select for MUX B Multiplexer Setting bits(1,2)
7 CH0NA: Channel 0 Negative Input Select for MUX A Multiplexer Setting bit
3-0 CH0SA<3:0>: Channel 0 Positive Input Select for MUX A Multiplexer Setting bits(1,2)

ad1pcfg

アナログピン設定

bit name func
15 PCFG15: Analog Input Pin Configuration Control bit
14-13 Unimplemented: Read as ‘0’
12-0 PCFG<12:0>: Analog Input Pin Configuration Control bits(1)

ad1cssl

スキャンピン設定

bit name func
15 CSSL15: Band Gap Reference Input Pin Scan Selection bit
14-13 Unimplemented: Read as ‘0’
12-0 CSSL<12:0>: A/D Input Pin Scan Selection bits(1)

pin selection
ad1pcfgでpin select

input channel selection >>> muxa, muxbのselect

muxa >>>
ch0sa
ch0na

muxb >>>
ch0sb
ch0nb

channelは0のみで、ch0xa, ch0xbをセレクトできる。

negativeにsignalを接続して差動でとれる。
ad1chsで設定できるが、シーケンシャル動作させる場合は?

17.4.4.1 CONFIGURING MUX A AND MUX B INPUTS
bandgap > vbg or vbg/2 >>> s/hのプラス端子に接続できる。これで、測定電圧がマイナスの電圧になる場合があるのか。 mux a,bのマイナス側には、an1を接続可能。

17.4.4.2 ALTERNATING MUX A AND MUX B INPUT SELECTIONS
muxa, muxbを交互に測定できる。alts = 0でmuxa固定になる。

17.4.4.3 SCANNING THROUGH SEVERAL INPUTS
muxaのみscanできる。
CSCNA = 0でscanしない。scanなしでauto測定できるのか?
scanの場合、naは固定でpositiveのみ切り替えられる。
alts = 1でmuxbの切替を有効にした場合、muxa=scanかつ交互にmuxbが測定される。

タイミング
tad = clock source * adcs(ad1con3.7-0, 00111111 = 64max)
tsamp = tad * samc(ad1con3.12-8, 11111=31 max)

sys clockをつかって最長の設定にする。
fcy = 16MHz, tcy = 1/fcy
adcs 111111 >>> tad = tcy * 64
samc 11111  >>> cnt clock = 31 * tad
tad = 1/16M * 64 = 1.984mS ??
tad = tcy(adcs + 1) >>> max 0b1000000 = 64

adc clock >>> tcy * adcs
sys 16MHz時
tcy = 0.0625us
adcs = 64 (max)
0.0625u * 64 = 4us = tad

a/d convert clock
sample clock num = samc + 1 (max 31)
conversion clock num = 12 >>> data outまでいれると13か
one data time
tad * (31 + 13) = 4us + 44 = 176us

16data sample
175us * 16 = 2.816ms >>> だいたい実測値とあっている。

manual start sample

Example 17-3: Converting One Channel, Manual Sample Start, TAD-Based Conversion Start Code

int ADCValue;
AD1PCFG = 0xEFFF; // all PORTB = Digital; RB12 = analog
AD1CON1 = 0x00E0; // SSRC<2:0> = 111 implies internal counter ends sampling
// and starts converting.
AD1CHS = 0x000C; // Connect AN12 as S/H input.
// in this example AN12 is the input
AD1CSSL = 0;
AD1CON3 = 0x1F02; // Sample time = 31Tad, Tad = 3Tcy
AD1CON2 = 0;
AD1CON1bits.ADON = 1; // turn ADC ON
while (1) // repeat continuously
{
AD1CON1bits.SAMP = 1; // start sampling, then after 31Tad go to conversion
while (!AD1CON1bits.DONE){}; // conversion done?
ADCValue = ADC1BUF0; // yes then get ADC value
}

an0 single int per 16samples

Example 17-6: Sampling and Converting a Single Channel Multiple Times

int ADCValue, count;
int *ADC16Ptr;
AD1PCFG = 0xFFFE; // Only AN0 as analog input
AD1CON1 = 0x00E0; // Internal counter triggers conversion
AD1CHS = 0x0000; // Connect AN0 as positive input
AD1CSSL = 0;
AD1CON3 = 0x0F00; // Sample time = 15Tad, Tad = Tcy
AD1CON2 = 0x003C; // Set AD1IF after every 16 samples
AD1CON1bits.ADON = 1; // turn ADC ON
while(1) // repeat continuously
{
ADCValue = 0; // clear value
ADC16Ptr = &ADC1BUF0; // initialize ADC1BUF pointer
IFS0bits.AD1IF = 0; // clear ADC interrupt flag
AD1CON1bits.ASAM = 1; // auto start sampling for 31Tad
// then go to conversion
while (!IFS0bits.AD1IF){}; // conversion done?
AD1CON1bits.ASAM = 0; // yes then stop sample/convert
for (count = 0; count < 16; count++) // average the 16 ADC value
{
ADCValue = ADCValue + *ADC16Ptr++;
}
ADCValue = ADCValue >> 4;
} // repeat

interrupt sample


/*
 * adc1 interrupt
 */
void  __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt(void){
    int ADCValue, count;
    int *ADC16Ptr;
    double dbuf;
    AD1CON1bits.ASAM = 0;    // stop conersion    
    ADCValue = 0; // clear value
    ADC16Ptr = (int*)&ADC1BUF0; // initialize ADC1BUF pointer
    for (count = 0; count < 16; count++) // average the 16 ADC value
    {
        ADCValue = ADCValue + *ADC16Ptr++;
    }
    dbuf = (double)ADCValue;
    dbuf /= 16368;  // 16 * 1023
    measPower = dbuf * 3.3;
    _AD1IF = 0;
    AD1CON1bits.ASAM = 1; // auto start sampling for 31Tad
    oTest1 ^= 1;
}

/*
 * conversion start
 * 
 */
void adcStart(void){
    _AD1IF = 0;
    _AD1IE = 1;
    AD1CON1bits.ADON = 1; // turn ADC ON
    AD1CON1bits.ASAM = 1; // auto start sampling for 31Tad    
}
/*
 * main
 */
void main(void){
    AD1PCFG = 0xFFFE; // Only AN0 as analog input
    AD1CON1 = 0x00E0; // Internal counter triggers conversion
    AD1CHS = 0x0000; // Connect AN0 as positive input
    AD1CSSL = 0;
    AD1CON3 = 0x0F00; // Sample time = 15Tad, Tad = Tcy
    AD1CON2 = 0x003C; // Set AD1IF after every 16 samples
    _AD1IE = 1;
    AD1CON1bits.ADON = 1; // turn ADC ON
    AD1CON1bits.ASAM = 1; // auto start sampling for 31Tad
    while(1);
}

0 件のコメント:

コメントを投稿