最初、単にStellaris LM4F120のAIN端子に温度センサを繋げて、「はい終了!」のつもりが。。。
以前 MSP430で温度計を作ったときは、電圧出力型温度センサを使ったのですが、今回はLM4F120のADCが12ビットなので、
せっかくなら、「精度のある温度センサを!」
せっかくなら、「複数の温度センサを!」
といったことで、結構手間取るはめになりました。
1.温度センサについて
今回使用した温度センサはUS Sensor社のUSP11491 です。
2.Rcの選択について
今回使用の温度センサは、計測温度の上昇に伴い、抵抗値が減少します。したがってLM4F120が出力する電圧Vccの分圧回路を組む必要があると考えました。分圧回路を構成する2つの抵抗 1つはこの温度センサ、もう1つは固定抵抗(Rc) つまりRcを決める必要があります。
温度測定回路、温度計算式等 |
①各温度(-55~150℃)での温度センサの抵抗値を計算
※ただし 温度センサの B値は (0~50℃)でこの温度範囲外はBを補正する必要がありそうですが、それこそ、精密な温度計が必要になりそうで今回は目をつぶります。
②Rcを仮に設定して、各温度(-55~150℃)での分圧(V)を計算し、1℃あたりの分圧の変化⊿Vを把握
⊿Vが大きいほど測定温度の分解能が大きくなる。
●Rc 3.3KΩ の場合 35~54℃(45℃がピーク)で⊿Vが大きくなる。
●Rc 5KΩ の場合 20~50℃(34℃がピーク)で⊿Vが大きくなる。
●Rc 10KΩ の場合 0~40℃(19℃がピーク)で⊿Vが大きくなる。
※測定温度域が低い場合 Rcを大きく 高い場合 Rcを小さくすることになります。
3.Stellaris LM4F120のADCの使い方。
StellarisWareのサンプルプログラムを参考に温度測定回路の電圧Vを取り込み温度表示をおこないました。比較的簡単に出来ました。
しかし、複数温度センサー構成を試みたところ、なかなか2ch以降の電圧Vの取り込みが行えませんでした、StellarisのADCのシーケンス、シーケンスステップがなかなか理解できなかったのが要因でした、ドキュメントに関連するブロック図でもあったらと思います。
//////// 3チャネルのADC取り込み設定//////////////////////////////////////////
////////////////端子設定/////////////////////////////////////////////////////////////////////
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
ROM_GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1);
///////////////ADC0の使用宣言///////////////////////////////////////////////////////
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
///////////////シーケンス設定///////////////////////////////////////////////////////////
ROM_ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);
//////////////ステップ設定////////////////////////////////////////////////////////////////
ROM_ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH0 |ADC_CTL_IE );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH1 |ADC_CTL_IE );
ROM_ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH2 |ADC_CTL_IE |ADC_CTL_END);
//////////////シーケンス稼働////////////////////////////////////////////////////////////////
ROM_ADCSequenceEnable(ADC0_BASE, 2);
ROM_ADCIntClear(ADC0_BASE, 2);
ROM_ADCSequenceEnable(ADC0_BASE, 2);
ROM_ADCIntClear(ADC0_BASE, 2);
//////// 3チャネルのADC 取り込み //////////////////////////////////////////
///////////////ADCトリガ////////////////////////////////////////////////////////////////////
ROM_ADCProcessorTrigger(ADC0_BASE, 2);
///////////////ADCコンバージョン完了待ち////////////////////////////////////////////////////////////////////
///////////////ADCコンバージョン完了待ち////////////////////////////////////////////////////////////////////
while(!ROM_ADCIntStatus(ADC0_BASE, 2, false))
{
}
{
}
ROM_ADCIntClear(ADC0_BASE,2);
///////////////ADCデータ取得////////////////////////////////////////////////////////////////////
ROM_ADCSequenceDataGet(ADC0_BASE, 2, ulADC0_Value);
///////////////ADCデータ取得////////////////////////////////////////////////////////////////////
ROM_ADCSequenceDataGet(ADC0_BASE, 2, ulADC0_Value);
ulADC0_Valueは配列 ulADC0_Value[0]がCh0 ulADC0_Value[1]がCh1 ulADC0_Value[2]がCh2 の値を格納