Transistor Gijutsu, October 2014, Special Features Chapter 8,Software of the thermistor thermometer of 0.001 ° resolution, トランジスタ技術2014年10月号 特集第8章のソフトウェア 0.001℃分解能で気配もキャッチ「超敏感肌温度計」
Information
tg_201410s8_AD7714 トランジスタ技術 2014年 10月号 第8章のソフトウェア
Program for Section 8 in October. 2014 issue of the Transistor Gijutsu
(Japanese electronics magazine)
概要
このプログラムは、サーミスタの抵抗値変化をAD7714(24bitADC)で測定し、抵抗値を温度値に変換することで、0.001℃程度の分解能で温度変化を測定します。
ファイル
このソフトウエアは、次のファイルから構成されています。
- AD7714.cpp - AD7714の内部レジスタを設定
- Thermistor.cpp - サーミスタの抵抗値から温度値に変換
- ExpAvr.cpp - 指数平均によるソフトウエアLPF
- main.cpp - main()関数
詳細については、10月号の記事および上記ファイル中のコメントを参照してください。
AD7714/AD7714.cpp
- Committer:
- Dance
- Date:
- 2014-08-29
- Revision:
- 0:de885a6da962
File content as of revision 0:de885a6da962:
#include "AD7714.h" #define MAINCLKF (48) // main clock 48MHz #define CLKFRQ (1000) // clkout の周波数 kHz /// コンストラクタ /// - PWMおよびSPIポートを初期化 /// - PWMはAD7714のマスタークロック1MHzを生成する AD7714::AD7714(void) { // CLKOUT を1MHzに設定 // set clock divider LPC_SYSCON->CLKOUTDIV = (CLKFRQ * MAINCLKF) / 1000; // main clock -> CLKOUT LPC_SYSCON->CLKOUTSEL = 0x3; LPC_SYSCON->CLKOUTUEN = 0; LPC_SYSCON->CLKOUTUEN = 1; // P0_1 -> CLKOUT LPC_IOCON->PIO0_1 |= 0x01; // SPIポート初期化 spi = new SPI(P0_9, P0_8, P0_10); // SPI信号のアイドルレベルとクロック位相を設定 LPC_SSP0->CR0 |= 0xc0; // ADCのリセットとフィルタ設定 reset(); setFilter(2); // 各チャネルのゼロ点とフルスケールの校正(キャリブレーション) // 内部的に入力を短絡してゼロスケールを校正 // 内部的に入力をVrefに接続してフルスケールを校正 // 他のチャネルを使う場合は、コメントを外す // キャリブレーションには時間がかかるので必要なチャネルだけ初期化 channel = Ch.A1A2; calib(); //channel = Ch.A3A4; //calib(); //channel = Ch.A5A6; //calib(); }; /// キャリブレーション /// チャネル、ゲイン、フィルタ周波数を変更したあと必ず実行せよ void AD7714::calib(void) { write(Reg.Mode, 0x20); while(isBusy()){ } } /// SPI通信ポートの初期化 void AD7714::reset(void) { for(int a = 0; a < 5; a++){ writeByte(0xff); } } /// 変換中なら真を返す bool AD7714::isBusy(void) { writeByte(CRegister::Comun | CmdRead | channel); return (writeByte(CmdRead) & 0x80) != 0; } /// 1バイト送信 /// @param txd 送信データ /// @return 受信データ int AD7714::writeByte(int txd) { return spi->write(txd); }; /// レジスタの内容を読む /// @param reg レジスタを指定する値 Reg構造体のメンバー /// @return レジスタの内容 int AD7714::read(int reg) { int r, cmd; cmd = reg | CmdRead | channel; writeByte(cmd); r = writeByte(cmd); if(reg >= Reg.Data){ r = (r<<8) | writeByte(cmd); r = (r<<8) | writeByte(cmd); } return r; } /// 指定レジスタに書き込む /// 指定レジスタが8bitか24bitがを判別して書き込む /// @param reg レジスタを指定する値 Reg構造体のメンバー /// @param data 書き込むデータ /// @return なし void AD7714::write(int reg, int data) { writeByte(reg | CmdWrite | channel); writeByte(data & 0xff); if(reg >= Reg.Data){ data >>= 8; writeByte(data & 0xff); data >>= 8; writeByte(data & 0xff); } } /// フィルターノッチ周波数の設定(19Hz - 4000Hz) ///-# 周波数を上げると変換時間は短縮されるがノイズが増える ///-# 60に設定すると60Hzの電源ノイズのキャンセルに有効 /// @param freq ノッチ周波数[Hz] /// @return なし void AD7714::setFilter(int freq) { int code = (FclkIn / 128) / freq; if(code < 19){ code = 19; }else if(code > 4000){ code = 4000; } // バイポーラ入力に設定 write(Reg.FltHi, 0x40 | ((code >> 8) & 0x0f)); write(Reg.FltLo, code & 0xff); } /// レシオメトリックADCクラスのコンストラクタ(初期化に数秒を要する) /// @param Rpu プラス入力のVcc側抵抗値、GND側抵抗としてセンサを接続する。 /// @param Rmu マイナス入力のVcc側抵抗値 /// @param Rml マイナス入力のGND側抵抗値 /// @param Rru リファレンス入力のVcc側抵抗値 /// @param Rrl リファレンス入力のGND側抵抗値 RatioMetric7714::RatioMetric7714(double Rpu, double Rmu, double Rml, double Rru, double Rrl) { af = 1 << bits; rpu = Rpu; rmu = Rmu; rml = Rml; rru = Rru; rrl = Rrl; } /// 与えられたADC値をレシオメトリックにより抵抗値に変換する /// @param int adVal AD変換値 /// @return 変換さた抵抗値 double RatioMetric7714::toResistorValue(int adVal) { return -((rpu*(2*adVal*(rml + rmu)*rrl + af*(-(rmu*rrl) + rml*rru))) /(2*adVal*(rml + rmu)*rrl - af*(rml*rrl + rmu*(2*rrl + rru)))); } /// 現在のADC値を抵抗値に変換して返す /// @return 測定された抵抗値 double RatioMetric7714::getResistorValue(void) { return toResistorValue(getValue()); }