32MMのADCを使ってみる
MCCで自動生成されたソースをそのまま使ってみたのですが、うまく動かなかったので単純に任意のADCユニットを選択して変換するだけのプログラムを作ってみました。
コンフィグビットやクロックの設定、ポートの設定が完了しているものとして、以下の簡単なプログラムでAD変換することができます。
ADCTrig(delay) のdelayは適当です、24Mhz動作 で20に設定したら動きました。
単純変換の場合、どのADCチャンネルでも変換後の値が入るのはADCxBUF0になります。
あと単発メモにもありますが、SCCP1の出力をPORTBに割り当てるとRB4が制御不能になるので特に不自由が無いのであればRAに割り当てたほうが吉です。
//ADCユニットの初期化
void ADCInit( void ) {
AD1CON1 = 0x0000;
AD1CON1bits.MODE12 = 1; // 0=10bit 1=12bit
AD1CON2 = 0x0000;
AD1CON3 = 0x000F; // Sample Clock 1:16
AD1CON1bits.ON = 1; // モジュールスタート
}
// 変換が終了したか?
int ADCIsDone( void ) {
return AD1CON1bits.DONE; //Wait for conversion to complete
}
// 変換チャンネルを指定
void ADCSetCh( int ch ) {
AD1CHSbits.CH0SA = ch;
}
// 手動トリガ
void ADCTrig( int delay ) {
AD1CON1bits.SAMP = 1;
while( delay --) {
__asm__ volatile ("nop");
}
AD1CON1bits.SAMP = 0;
}
void RunAdc( void ) {
unsigned short ad0,ad1;
ADCInit();
for ( ;; ) {
ADCSetCh( 0 ); // チャンネル0選択
ADCTrig( 20 ); // アクイジション
while ( !ADCIsDone() ); // 変換終了を待つ
ad0 = ADC1BUF0;
ADCSetCh( 1 ); // チャンネル1選択
ADCTrig( 20 ); // アクイジション
while ( !ADCIsDone() ); // 変換終了を待つ
ad1 = ADC1BUF0;
}
}