2386135_ja-JP

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2386135_ja-JP

2386135_ja-JP

How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

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測定対象は以下のように構成されます。

  •  Ch8:MCU内部温度(TEMPSENSE)
  •  Ch9:MCU内部電圧(ANAMUX)
  •  第10章:バンドギャップ

ADC Setting00.png

ADC Setting01.png

ADC Setting02.png

  •  MCU入力電圧 = 5.0V

ADC Setting03.png

ADC Setting04.png

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`を使用する必要があると思います。もし私が見落としている設定があれば教えてください。



Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは、センレントさん。

迅速なご対応ありがとうございます。


ご提供いただいたサンプルコードは既に確認済みで、私のコードに組み込んだと考えています。

ご提供いただいた表は、ADCブロックに供給される各クロックに対するレジスタ設定の表であると解釈しました。しかし、それらがMCALのどのADC設定に対応しているのかを特定することはできませんでした。

ソースコードを提供できないため、ADC設定の画像を添付します。どの設定を変更すればよいか教えてください。

他に何か必要な設定画面があれば、お知らせください。


1_ADC_ConfigTimeSupport.png

AdcHwUnit>

2_ADC Config_AdcHwUnit.png

3_ADC General.png

4_ADC0 HwConfiguration.png

6_ADC AutosarExt.png





Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは@輝彦

提供された情報にはADCの完全な構成が見当たらなかったので、ADCクロックがデータシートの要件に合っているか再確認してください。

可能であれば、テストプロジェクトを共有していただければ、私が確認します。

Senlent_0-1782458295032.png

ちなみに、下記のリンクからデモをご覧ください。

https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K344-TempSenser-S32DS36-RTD600-500-400-p...


Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは、センレントさん。

アドバイスありがとうございます。
ご助言に従い、TEMPSENSEのサンプリング時間を1.2マイクロ秒に設定するように、以下のように設定を変更しました。

ADC Setting10.png

160MHz = 0.00625マイクロ秒

1.2マイクロ秒/0.00625マイクロ秒= 192

ADC Setting11.png

FreeRTOSで1秒サイクルのタスクを作成し、MCU電圧(VDD_HV_A)とMCU温度(TEMPSENSE)のADC値を毎秒取得しました(30秒分のデータ収集)。

ADC Setting13.png

MCU電圧についてはバンドギャップ電圧を使い、以下の補償式でmVに変換しました。
(バンドギャップ電圧はほとんど変動せず、約3975(約1.2V)の値が得られた。)


Adc補正 = (1200(mV) * Adc_VCC_HV_A) / Adc_バンドギャップ

Mcu電圧 = アドコレーション × 2(2は電圧分割比VDD_HV_A)

ADC Setting12.png

さらに、 McuTempデータは `Adc_TempSenseGetTemp(ADC0, &mcuTemperature)` から取得されます。

ADC変換誤差が±5.0%であることを考慮しても、このばらつきは大きすぎると思います。何か解決策の提案はありますか?


 



Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは@輝彦

ご提供いただいた設定画面のスクリーンショットとコードを見る限り、明らかなエラーは見当たりません。ただし、温度センサのサンプリング時間は1.2μsを超えなければならないことに注意が必要です。そうでなければ、サンプリングの精度に影響します。したがって、テストを行う前にサンプリング時間を再度確認することをお勧めします。

Senlent_0-1782377529947.png


Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

ADC_Config>AdcHwUnitの画像が圧縮されて解像度が低下したため、再アップロードします。

<#1>

2_ADC Config_AdcHwUnit_1.png

<#2>

2_ADC Config_AdcHwUnit_2.png

<#3>

2_ADC Config_AdcHwUnit_3.png

Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは@輝彦

温度チャネルから生データを直接読み取って、変動があるかどうかを観察できます。変動が大きい場合は、サンプリング時間を延ばし続けるCAN。

Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは、センレントさん。

ご返信ありがとうございます。

下図に示すように、サンプリング期間1/期間2の値を増加させた後、値は安定しました。デフォルト設定はサンプリング持続時間0だと思っていましたが、サンプリング持続時間0、1、2の切り替えはどうすればいいのでしょうか?

10_ADCConfig_AdcHwUnit.png

(プリスケール設定に基づくと、ADCクロックは80MHzなので、1.2μsに相当する期間は96となる。)

Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは、センレントさん。

ドキュメントを添付してくださりありがとうございます。現在チャネル32から63を測定しているので、これはサンプリング持続時間1に対応していると理解しています。

迅速なご対応ありがとうございます。問題は解決しました。

Re: How to Measure the Internal Temperature and Voltage of an MCU Using the ADC0

こんにちは、センレントさん。

私は表317の情報を以下のように解釈しました。
fmc = 160 MHz の場合:
・キャリブレーション用のプリスケーラを4に設定する
・通常のADC変換のプリスケーラを2に設定する
・「ADC高速」を無効に設定する
7_ADCConfig_AdcHwUnit.png

これらの設定を適用して得られたデータは、以下の表に示されています。

平均化することでばらつきは減りましたが、MCU内部温度の変動は依然としてかなり大きいと感じます。

8_ADCConfig_AdcHwUnit.png

以下の表は、ADC値から°Cに変換したMCU温度データを示しています。

(ADC値を摂氏に変換するために、ADC値を16で割りました。)

9_ADCConfig_AdcHwUnit.png

16点平均で2.55度の変動は極めて大きい。MCUの温度はプロセッシング負荷によって変動することは理解していますが、これほど瞬時に大きく変わるのは普通のことですか?

MCUの内部温度を測定する際に、平均を取るのが正しいアプローチでしょうか?

Tags (1)
No ratings
Version history
Last update:
9 hours ago
Updated by: