自作マイクロマウス研修(槇原)

STM32でADCで各チャンネルの変換を1つずつ変換する – 自作マイクロマウス研修(槇原)Part7

自作マイクロマウス研修(槇原)

はじめに

こんにちは、槇原です。前回は基板の設計をしてきました。今回からはマイコンのペリフェラルについて書いていきます。今回はタイトルの通りSTM32マイコンでADCをする際に各チャンネルの変換を1つずつ行う方法について説明します。

やりたいこと

今回のマウスの壁センサでは125 µsおきに4つある壁センサのうち1つのセンサの値を取得するという動きをさせます。高速でADCを行うことでマウス全体の制御周期(1 ms)より早くすべてのセンサの値を更新できるようにします。

マイコンのピンアサインは次の通りです。

ピン ADC
PA0 ADC1_IN1
PA1 ADC1_IN2
PA2 ADC1_IN3
PA3 ADC1_IN4

CubeMXでの設定は次のとおりです。設定自体は1ch用の変換の設定をして、プログラム上でどのチャンネルの変換をするか切り替えます。

毎回ソフトウェアをトリガーでADCをするためEnable Regular ConversionsをEnable、External Trigger Conversion SourceをRegular Conversion launched by softwareに指定します。

プログラム

今回は毎周期ごとに、1ch分の通常のADCを行います。さらに毎回必要なチャンネルを切り替える必要があるため。HAL_ADC_ConfigChannel関数によって毎回チャンネルを指定します。
必要な設定項目はADC_ChannelConfTypeDefという構造体に必要な部分を設定します。特に今回はChannelを読みたいポートに合わせて指定します。
ChannelはマイコンのピンのADC_INxに対応します。ここではReadADCという関数を作りました。引数にチャンネルを取り、それに合わせて読み取るチャンネルを指定します。

uint16_t ReadADC(int ch){

    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5; 
    sConfig.SingleDiff = ADC_SINGLE_ENDED;
    sConfig.OffsetNumber = ADC_OFFSET_NONE;
    sConfig.Offset = 0;
    
    switch(ch){
    case 1:
        sConfig.Channel = ADC_CHANNEL_1;
        break;
    case 2:
        sConfig.Channel = ADC_CHANNEL_2;
        break;
    case 3:
        sConfig.Channel = ADC_CHANNEL_3;
        break;
    case 4:
        sConfig.Channel = ADC_CHANNEL_4;
        break;
    }
    if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) !=HAL_OK){
        Error_Handler();
    }
    if(HAL_ADC_Start(&hadc1) == HAL_OK){
        if (HAL_ADC_PollForEvent(&hadc1,ADC_EOSMP_EVENT, 200) == HAL_OK){
            uint16_t data=HAL_ADC_GetValue(&hadc1);
            return data;
        }
    }
    return -1;
}

壁センサの値を取得するためには発光側のLEDを光らせて一定時間待機してからADCを行います。
これを125 µsおきに呼び出すポートを変えてセンサ値を取得します。割り込み中にADCを行うため、for文で一定時間待機させます。

HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
for(int i=0;i<loop_num;i++);
right_adc_value= ReadADC(2);
HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);

 

ここまで書いてしまったのですが、これを作成してからRankを付けておけばひとつずつ呼び出すだけで順番にADCしてくれるらしいという話を聞きました。次からはこちらを使おうと思います…
参考

次回はFlashの書き込みについて書いていきます。

 

タイトルとURLをコピーしました