こんにちはショウです。前回に引き続き、動作確認をしていきます。
今回はAD変換の確認をしていきます。
UART設定
AD変換の前にprintfを使って変換値を表示するためにUARTを設定しました。
Part6のプログラムを使って表示を行います。
Part6ではLUART1を使用していましたが、今回はUSART1を使用しています。ピンはPA9、PA10を使用しています。
プログラムはLUARTのところをUSARTに変更して使用しています。
AD変換
バッテリー電圧
まずはバッテリー電圧チェックのプログラムを作成します。
バッテリー電圧の取得にはAD変換を使います。AD変換のタイミングはタイマー割り込みで行います。
Part9ではClock Prescalerをdivided by 2に設定していましたが、AD変換のクロックは60MHzがMAXになっていることがわかったので、余裕をもった値になるようにdivided by 8に変更しています。
バッテリー電圧はセンサの値と違って短時間で大きく変化しないので、今回はTIM6を使って10ms毎に割り込んで取得しています。
バッテリ電圧を取得するPB12はADC4_IN3の機能を使用しました。
壁センサ
次は壁センサのプログラムを用意していきます。
ピンはAD変換にPB1,PA0,PA1,PA2、LEDの点灯にPA3,PA4,PC13,PC14を使用しています。
壁センサは、一つずつタイミングをずらして取得していきます。今回センサのAD変換にはADC1とADC3を使っていることと、LEDの処理待ちが入るため、DMAで連続処理させずに、タイマー割り込みに合わせて次のAD変換をするDiscontinuousモードで取得させています。
タイマーはTIM5を使用し、250us毎に割り込みを行い、割り込み4回で4つのセンサの値を取得し、全体としては1ms毎に取得させています。
フォトトランジスタは赤外線LEDの光だけでなく、周りの外光も拾って値が出力されてしまうため、割り込み毎にLED点灯前と後で2回AD変換を行い、外光の影響を減らしています。
そのため、Number of Conversionsをセンサの2倍用意して、同じセンサを2回ずつ取得するように設定しています。
壁センサ取得の順番は直前の発光の影響を減らすために、隣り合ったセンサが連続して取得を行わないようにしています。今回は左前、右横、左横、右前の順番で取得させています。
受光したフォトトランジスタの電圧の立ち上がりの遅れがあるので、取得までにfor文で空ループを入れてからAD変換を行うようにしています。
void TIM5_IRQHandler(void) { static uint8_t i = 0; if ( LL_TIM_IsActiveFlag_UPDATE(TIM5)==1){ LL_TIM_ClearFlag_UPDATE(TIM5); } switch(i){ case 0: DIST_Pol_FL(); break; case 1: DIST_Pol_SR(); break; case 2: DIST_Pol_SL(); break; case 3: DIST_Pol_FR(); break; } i = (i+1)%4; }
割り込み部分
void DIST_Pol_FL( void ) { st_sen[DIST_SEN_L_FRONT].s_offset = GetSensor_FL(); Set_SenFL(1); for(uint16_t i=0;i<400;i++); st_sen[DIST_SEN_L_FRONT].s_old = st_sen[DIST_SEN_L_FRONT].s_now; st_sen[DIST_SEN_L_FRONT].s_now = GetSensor_FL()- st_sen[DIST_SEN_L_FRONT].s_offset; LL_ADC_ClearFlag_EOS(ADC3); Set_SenFL(0); }
センサ値取得部分
センサ値取得部分にあるLL_ADC_ClearFlag_EOS(ADC3)という関数はADC3のrankに書かれた処理が全部終了した時に設定するフラグです。これを設定しておかないと次の変換が発生しなくなります。
main関数で割り込みをスタートして、センサ値を確認していきます。
手をかざした時にセンサー値が大きく変化していることを確認しました。
今回はここまで