ユーザ用ツール

サイト用ツール


xg_series_devel:use_adc:start

差分

この文書の現在のバージョンと選択したバージョンの差分を表示します。

この比較画面にリンクする

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
xg_series_devel:use_adc:start [2018/03/20 09:24]
admin
xg_series_devel:use_adc:start [2019/01/07 16:16] (現在)
admin
ライン 1: ライン 1:
 +====== AD Converter の利用 ======
 +
 +XG-50 の AD Converter には、外部電源(バッテリー[ch1]、ワイド電源[ch2]) を接続しています。\\
 +加えて、SoC 内部の Vref、温度センサーも有効化しています。
 +
 +^  Channel ​ ^  入力 ​ ^  Note  |
 +|  0|  VREFINT ​ |SoC 内部基準電圧源|
 +|  1|  バッテリー電圧 ​ |アッテネータ経由((10/​11 にしているため、真の値を求めるには 1.1 倍する必要があります))|
 +|  2|  ワイド電源電圧((5〜36V)) ​ |アッテネータ経由((1/​12 にしているため、真の値を求めるには 12倍 する必要があります))|
 +|  17|  温度センサー ​ |SoC 内蔵温度センサー|
 +
 +\\
 +
 +===== 設定 =====
 +
 +==== NuttX Configuration ====
 +
 +AD Converter を有効化するため、**make menuconfig** で NuttX の構成を変更します。
 +
 +  * Device Drivers -> Analog Device(ADC/​DAC) Support 有効化
 +  * Device Drivers -> Analog Device(ADC/​DAC) Support -> Analog-to-Digital Conversion 有効化
 +
 +{{:​xg_series_devel:​use_adc:​adc_menuconfig_01.png?​600|}}
 +
 +  * Application Configuration -> Examples -> ADC example 有効化
 +    * ADC device path -> **"/​dev/​adc0"​**
 +    * Number of Samples per Group -> 4
 +    * Use software trigger 有効化
 +
 +{{:​xg_series_devel:​use_adc:​adc_menuconfig_02.png?​600|}}
 +
 +config を保存し、build します。
 +
 +\\
 +
 +==== ファームウェアの書き込み ====
 +
 +[[xg_series_devel:​boot_firmware:​start]] を参考に、ファームウェアを XG-50 に書き込みます。
 +
 +\\
 +
 +===== 動作テスト =====
 +
 +書き込んだファームウェアを実行すると、下のように **adc** というコマンドが使用できるようになります。
 +
 +<​code>​
 +NuttShell (NSH)
 +nsh> help
 +help usage: ​ help [-v] [<​cmd>​]
 +
 +  [           ​dirname ​    ​false ​      ​mkfatfs ​    ​pwd ​        time
 +  ?           ​date ​       free        mkfifo ​     reboot ​     true
 +  basename ​   dd          help        mkrd        rm          uname
 +  break       ​df ​         hexdump ​    ​mh ​         rmdir       ​umount
 +  cat         ​dmesg ​      ​kill ​       mount       ​set ​        unset
 +  cd          echo        ls          mv          sh          usleep
 +  cp          exec        mb          mw          sleep       xd
 +  cmp         ​exit ​       mkdir       ​ps ​         test
 +
 +Builtin Apps:
 +  adc <-------
 +  cu
 +  i2c
 +  sudoku
 +nsh>
 +</​code>​
 +
 +\\
 +
 +さっそく実行してみます。
 +
 +<​code>​
 +nsh> adc
 +adc_main: g_adcstate.count:​ 1
 +adc_main: Hardware initialized. Opening the ADC device: /dev/adc0
 +Sample:
 +1: channel: 0 value: 1498
 +2: channel: 1 value: 3483
 +3: channel: 2 value: 0
 +4: channel: 17 value: 936
 +nsh>
 +</​code>​
 +
 +Channel 0, 1, 2, 17 の 4 つの値を取ることができました。
 +
 +\\
 +
 +==== 値の(電圧への)変換 ====
 +
 +上記 AD 変換で取得した値は、アナログ電源(VDDA) を基準にした相対値((12bit ADC なので、0〜4095))となっています。\\
 +STM32L4 の Reference Manual にあるとおり、実際の電圧を求めるには計算を行う必要があります。
 +
 +計算式は下記のとおりです。
 +
 +$$ V_{CHANNEL_X} = \frac{V_{DDA}}{FULL\_SCALE} \times ADC_X\_DATA $$
 +
 +(Reference Manual より)
 +
 +ここで、VDDA は 3.3[V]、FULL_SCALE は 4095 なのでそれを当てはめて Channel 1 (バッテリー入力電圧) を計算すると、
 +
 +$$ V_{CHANNEL1} = \frac{3.3}{4095} \times 3483 \times 1.1 = 3.087 [V] $$
 +
 +となります。
 +
 +\\
 +
 +=== VREFINT を利用した計算 ===
 +
 +STM32L4 の VREFINT を利用し、VDDA の電圧に依存しない計算方法です。
 +
 +$$ V_{CHANNEL_X} = \frac{3.0 V \times VREFINT\_CAL \times ADC_X\_DATA}{VREFINT\_DATA \times FULL\_SCALE} $$
 +
 +
 +ここで、各変数は下記の通りです。
 +
 +^  変数 ​ ^  内容 ​ |
 +|  VREFINT_CAL ​ |VREFINT calibration value((メーカーにて出荷時にキャリブレーションした結果を不揮発領域に書き込んであります)) (0x1FFF75AA - 0x1FFF75AB)|
 +|  ADC_DATA ​ |AD 変換結果|
 +|  VREFINT_DATA ​ |Channel 0 AD変換結果|
 +|  FULL_SCALE ​ |4095|
 +
 +\\
 +
 +手元のチップでは、**VREFINT_CAL** の値は 0x0678 でした。
 +
 +<​code>​
 +nsh> mh 0x1fff75aa
 +  1fff75aa = 0x0678
 +nsh>
 +</​code>​
 +
 +\\
 +
 +この値を上記式に当てはめて計算すると、
 +
 +<​code>​
 +In [8]: ((3 * 0x0678 * 3483) / (1498 * 4095)) * 1.1
 +Out[8]: 3.1028589034463536
 +</​code>​
 +
 +となります。
 +
 +試しに電圧計で電源ピンのところで計測してみると 3.094 [V] でした。\\
 +どちらの方法を使用しても 0.3% 程度の誤差((電圧計が正しいかどうかは置いておいて))で計測できるようです。
 +
 +\\
 +
 +==== 値の(温度への)変換 ====
 +
 +CH17 の温度センサーの値から温度への変換式は下記のとおりです。
 +
 +
 +$$ Temperature\ (in \ ℃) = \frac{110\ ℃ - 30\ ℃}{TS\_CAL2 - TS\_CAL1} \times (TS\_DATA - TS\_CAL1) + 30\ ℃ $$
 +
 +ここで、各変数は下記になります。
 +
 +^  変数 ​ ^  内容 ​ ^
 +|  TS_CAL1 ​ |温度センサーキャリブレーション値((VDDA 3.0V)) @30℃ (0x1FFF75A8 - 0x1FFF75A9) |
 +|  TS_CAL2 ​ |温度センサーキャリブレーション値((VDDA 3.0V)) @110℃ (0x1FFF75CA - 0x1FFF75CB) ​ |
 +|  TS_DATA ​ |温度センサー ADC 出力値|
 +
 +**TS_CAL1**,​ **TS_CAL2** ともに VDDA が 3.0V のときの値となっていますが、XG-50 の VDDA は 3.3V のため、\\
 +**『VREFINT を利用した計算』** を用いて換算する必要があります。
 +
 +\begin{align}
 +Temperature\ (in\ ℃) = \frac{110\ ℃ - 30\ ℃}{TS\_CAL2 - TS\_CAL1} \times \left(\frac{VREFINT\_CAL \times TS\_DATA}{VREFINT\_DATA} - TS\_CAL1 \right) + 30\ ℃
 +\end{align}
 +
 +\\
 +
 +手元のチップで **TS_CAL1**,​ **TS_CAL2** を確認してみると、
 +
 +<​code>​
 +nsh> mh 0x1fff75a8
 +  1fff75a8 = 0x0410
 +nsh> mh 0x1fff75ca
 +  1fff75ca = 0x051b
 +</​code>​
 +
 +それぞれ 0x0410, 0x051b となっているため、それを用いて計算すると、
 +
 +<​code>​
 +In [18]: VREFINT_CAL=0x0678
 +
 +In [19]: TS_DATA=936
 +
 +In [20]: TS_CAL1=0x410
 +
 +In [21]: TS_CAL2=0x51b
 +
 +In [22]: VREFINT_DATA=1498
 +
 +In [23]: ((110 - 30) / (TS_CAL2 - TS_CAL1)) * ((VREFINT_CAL * TS_DATA) / VREFINT_DATA - TS_CAL1) + 30
 +Out[23]: 28.419065620577733
 +</​code>​
 +
 +28.4℃ となりました。
 +
 +\\
 +
 +===== プログラミング =====
 +
 +''​apps/​examples/​adc/​adc_main.c''​ を参照してください。
 +
 +
 +\\
 +
  
xg_series_devel/use_adc/start.1521505455.txt.bz2 · 最終更新: 2018/03/20 09:24 by admin