NXPサポートチームの皆様、こんにちは。
現在、S32K314、RTD 7.0.0、およびFreeRTOSを使用したプロジェクトに取り組んでいます。MCALのADCモジュールを使用して、MCUに接続された外部デバイスの電圧、MCUの内部温度(TEMPSENSE)、MCUの内部電圧(ANAMUX)、およびバンドギャップ電圧の測定を実装しようとしています。測定結果を見ると、外部デバイスの電圧とバンドギャップ電圧は正しく測定されているようですが、MCUの内部温度と内部電圧の値は予想と異なっています。
期待値:
MCU内部電圧(VDD_HV_A):
8192(2.5V、14ビット分解能)
実測値:
約6800~7100(2.07~2.13V、14ビット分解能)
MCUの電源電圧は5.0Vです。ADCハードウェアユニットはADC0に設定され、ADC測定対象は以下のように構成されます。
ADC初期化コード:
void AdcAdapter_Init ( void )
{
Adc_Calibrate ( ADC0 , & calStatus ) ;
Adc_SetupResultBuffer ( ADC0 , Group0Result ) ;
IP_DCM_GPR -> DCMRWF1 = ( IP_DCM_GPR -> DCMRWF1
| DCM_GPR_DCMRWF1_SUPPLY_MON_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_HV_A_VLT_DVDR_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_HV_B_VLT_DVDR_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_1_5_VLT_DVDR_EN ( 1 )
) ;
IP_DCM_GPR -> DCMRWF1 = ( IP_DCM_GPR -> DCMRWF1 & ~ DCM_GPR_DCMRWF1_SUPPLY_MON_SEL_MASK ) | DCM_GPR_DCMRWF1_SUPPLY_MON_SEL ( 0U ) ; // VDD_HV_A_DIV
Adc_StartGroupConversion ( ADC0 ) ; // AdcConversionStart
}ADCデータ取得(すべての周期的なタスク)
void AdcAdapter_RunCyclic ( void )
{
Adc_StatusType ret = ADC_IDLE ;
Std_ReturnType adcStatus ;
uint16 temperature ;
// 変換完了チェック
ret = Adc_GetGroupStatus ( ADC0 ) ;
if ( ( ret == ADC_COMPLETED ) || ( ret == ADC_STREAM_COMPLETED ) ) {
// 結果を取得
Adc_ReadGroup ( ADC0 , Group0Result ) ;
// 次の変換を開始
Adc_StartGroupConversion ( ADC0 ) ;
} else {
// エラーログ
}
/* Adc_TempSenseGetTemp Singed Q11.4 */
adcStatus = Adc_TempSenseGetTemp ( ADC0 , mcuTemperature ) ;
if ( E_OK == adcStatus ) {
temperature = Adc_TempSenseCalculateTemp ( ADC0 , mcuTemperature ) ;
} else {
// エラーログ
}
}ADC0グループのADC値は`Adc_ReadGroup`を使用して更新できると思いますが、MCUの内部温度については`Adc_TempSenseGetTemp`と`Adc_TempSenseCalculateTemp`を使用する必要があると思います。もし私が見落としている設定があれば教えてください。
こんにちは、センレントさん。
迅速なご対応ありがとうございます。
ご提供いただいたサンプルコードは既に確認済みで、私のコードに組み込んだと考えています。
ご提供いただいた表は、ADCブロックに供給される各クロックに対するレジスタ設定の表であると解釈しました。しかし、それらがMCALのどのADC設定に対応しているのかを特定することはできませんでした。
ソースコードを提供できないため、ADC設定の画像を添付します。どの設定を変更すればよいか教えてください。
他に何か必要な設定画面があれば、お知らせください。
こんにちは@輝彦
提供された情報にはADCの完全な構成が見当たらなかったので、ADCクロックがデータシートの要件に合っているか再確認してください。
可能であれば、テストプロジェクトを共有していただければ、私が確認します。
ちなみに、下記のリンクからデモをご覧ください。
こんにちは、センレントさん。
アドバイスありがとうございます。
ご助言に従い、TEMPSENSEのサンプリング時間を1.2マイクロ秒に設定するように、以下のように設定を変更しました。
160MHz = 0.00625マイクロ秒
1.2マイクロ秒/0.00625マイクロ秒= 192
FreeRTOSで1秒サイクルのタスクを作成し、MCU電圧(VDD_HV_A)とMCU温度(TEMPSENSE)のADC値を毎秒取得しました(30秒分のデータ収集)。
MCU電圧についてはバンドギャップ電圧を使い、以下の補償式でmVに変換しました。
(バンドギャップ電圧はほとんど変動せず、約3975(約1.2V)の値が得られた。)
Adc補正 = (1200(mV) * Adc_VCC_HV_A) / Adc_バンドギャップ
Mcu電圧 = アドコレーション × 2(2は電圧分割比VDD_HV_A)
さらに、 McuTempデータは `Adc_TempSenseGetTemp(ADC0, &mcuTemperature)` から取得されます。
ADC変換誤差が±5.0%であることを考慮しても、このばらつきは大きすぎると思います。何か解決策の提案はありますか?
こんにちは@輝彦
ご提供いただいた設定画面のスクリーンショットとコードを見る限り、明らかなエラーは見当たりません。ただし、温度センサのサンプリング時間は1.2μsを超えなければならないことに注意が必要です。そうでなければ、サンプリングの精度に影響します。したがって、テストを行う前にサンプリング時間を再度確認することをお勧めします。
ADC_Config>AdcHwUnitの画像が圧縮されて解像度が低下したため、再アップロードします。
<#1>
<#2>
<#3>
こんにちは@輝彦
温度チャネルから生データを直接読み取って、変動があるかどうかを観察できます。変動が大きい場合は、サンプリング時間を延ばし続けるCAN。
こんにちは、センレントさん。
ご返信ありがとうございます。
下図に示すように、サンプリング期間1/期間2の値を増加させた後、値は安定しました。デフォルト設定はサンプリング持続時間0だと思っていましたが、サンプリング持続時間0、1、2の切り替えはどうすればいいのでしょうか?
(プリスケール設定に基づくと、ADCクロックは80MHzなので、1.2μsに相当する期間は96となる。)
こんにちは、センレントさん。
ドキュメントを添付してくださりありがとうございます。現在チャネル32から63を測定しているので、これはサンプリング持続時間1に対応していると理解しています。
迅速なご対応ありがとうございます。問題は解決しました。
こんにちは、センレントさん。
私は表317の情報を以下のように解釈しました。
fmc = 160 MHz の場合:
・キャリブレーション用のプリスケーラを4に設定する
・通常のADC変換のプリスケーラを2に設定する
・「ADC高速」を無効に設定する
これらの設定を適用して得られたデータは、以下の表に示されています。
平均化することでばらつきは減りましたが、MCU内部温度の変動は依然としてかなり大きいと感じます。
以下の表は、ADC値から°Cに変換したMCU温度データを示しています。
(ADC値を摂氏に変換するために、ADC値を16で割りました。)
16点平均で2.55度の変動は極めて大きい。MCUの温度はプロセッシング負荷によって変動することは理解していますが、これほど瞬時に大きく変わるのは普通のことですか?
MCUの内部温度を測定する際に、平均を取るのが正しいアプローチでしょうか?