CQ出版社セミナ "実習・Armマイコン内蔵ペリフェラルを活用するためのC++プログラミング" で使う外付け回路のテスト

Dependencies:   mbed UIT_SetOutputPortType UIT_AQM1602 UIT_ADT7410

main.cpp

Committer:
MikamiUitOpen
Date:
2020-04-02
Revision:
2:3f2be675f975
Parent:
1:0a21041026c7

File content as of revision 2:3f2be675f975:

//----------------------------------------------------------------------
//  セミナ "実習・Armマイコンで学ぶインターフェース回路とプログラミング"
//  で使う外付け回路のテスト
//      RGB LED             D2: 赤, D3: 緑, D4: 青
//      タクトスイッチ        D6
//      温度センサ(ADT7410) D14: SDA, D15: SCL
//      液晶表示器(AQM1602) D14: SDA, D15: SCL
//      ADC                 A0
//      ステッピング・モータ    D10: LSB, D13: MSB
//      ADC                 A1
//      DAC                 A2
//
//  1. タクトスイッチと RGB LED のテスト
//      起動時は1秒ごとに発光状態が切り替わる
//      タクトスイッチを押すごとに,切替が On/Off する
//  2. 温度センサと液晶表示器のテスト
//      起動直後から気温が液晶表示器に表示される
//  3. ADC(A1), DAC
//      ファンクションジェネレータを AIN につなぐと A2 から同じ信号が出力される
//  4. ステッピング・モータ
//      A0 に接続されている VR で回転スピードをコントロールする
//
//  オフィシャル・ライブラリのドキュメントは下記の URL
//      https://os.mbed.com/docs/mbed-os/ で APIs => Drivers
//
//  2020/04/02, Copyright (c) 2020 MIKAMI, Naoki
//------------------------------------------------------------

#include "mbed.h"
#include "SetOutputPortType.hpp"
#include "ADT7410.hpp"
#include "AQM1602.hpp"
#include "MyTicker13.hpp"
#include "MyTicker14.hpp"
#include "F446_AdcIntr.hpp"
#include "F446_Dac.hpp"
#include "PushButton.hpp"
using namespace Mikami;
#pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため

MyTicker14 steppingMotor_;  // ステッピング・モータ駆動用
AnalogIn adcA0_(A0);        // 回転速度の制御のための AD 変換器として使用
AdcF446_Intr adc_(100, A1); // 標本化周波数: 100 kHz
DacF446 dac_;               // DA 変換器

__IO bool ledOnOff_ = true; // LED の発光色切換えの ON/OFF で使用

// ステッピング・モータ駆動用タイマ割込み間隔を取得する
int GetMotorController(float adc)
{
    // SPG27-1101 の場合
    static const int INTVL1 = 6000;
    static const int INTVL2 = 3500;

    return INTVL1 - (uint16_t)(adc*INTVL2);
}

//------------------------------------------------------------------------------
// 以下:割込みサービス・ルーチン

// LED の発光色切換えの ON/OFF
void SwIsr()
{
    ledOnOff_ = !ledOnOff_;
    if (ledOnOff_) printf("LED の発光色の切替が有効になりました.\r\n\n");
    else           printf("LED の発光色の切替が無効になりました.\r\n");
}

// ステッピング・モータを駆動するための割込みサービス・ルーチン
void TimerIsr()
{
    static BusOut motor(D10, D11, D12, D13);    // D10: LSB, D13: MSB
    static const uint8_t CW[4] = { 0x03, 0x06, 0x0C, 0x09 };
    static int index = 0;

    motor = CW[index++];    // CW
    index &= 0x03;
}

// モータのスピードをコントロールするための割込みサービス・ルーチン
void MotorSpeedIsr()
{
    float value = adcA0_.read();
    // ステッピング・モータのスピード調整
    steppingMotor_.SetPeriod_us(GetMotorController(value));
}

// AD 変換終了割り込みに対する割り込みサービス・ルーチン
void AdcIsr()
{   
    dac_.Write(adc_.Read());
}

// 割込みサービス・ルーチン:ここまで
//------------------------------------------------------------------------------

int main()
{
    BusOut led(D2, D3, D4); // 赤, 緑, 青
    SetOpenDrain(D2);       // D2 をオープンドレインに設定
    led = 0x07;             // 全消灯
    Aqm1602 lcd;            // LCD 表示器,D14: SDA, D15: SCL
    ADT7410 tempr;          // 温度センサ,D14: SDA, D15: SCL

    // チャタリング防止付き入力
    //      D6: PB_10
    PushButton sw(D6, PullDown, PushButton::RISE, &SwIsr, 0.2);

    printf("\r\n外付け回路のテスト\r\n");

    // LED の準備
    uint8_t ledSw = 0;
  
    // LCD 表示器の準備
    if (lcd.IsConnected()) printf("LCD は接続されています\r\n");
    bool dotOn = true;
    lcd.WriteStringXY("ADT7410", 0, 0);

    // ステッピング・モータの準備
    float value = adcA0_.read();
    steppingMotor_.Attach_us(&TimerIsr, GetMotorController(value));
    MyTicker13 motorSpeed;      // モータのスピードを決める値の読取りで使用
    motorSpeed.Attach_ms(&MotorSpeedIsr, 10);   // 10 ms ごと

    // AD 変換器の準備
    adc_.SetIntrVec(&AdcIsr);   // 割り込みサービス・ルーチンの設定

    // 割込み優先順位設定
    NVIC_SetPriority(ADC_IRQn, 0);                  // AdcF446_Intr, 最優先
    NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 1);   // MyTicker14
    NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 2);        // MyTicker13
    NVIC_SetPriority(EXTI15_10_IRQn, 3);            // PushButton

    while (true)
    {
        // LED の点灯/消灯制御
        if (ledOnOff_)
        {
            led = ~ledSw++;
            ledSw &= 0x07;
        }

        // 温度センサと LCD への表示
        float value = tempr.Read();     // 温度読み取り
        lcd.WriteValueXY("%5.1f \xDF""C", value, 0, 1);
        if (dotOn) lcd.WriteStringXY("#", 15, 1);
        else       lcd.WriteStringXY(" ", 15, 1);
        dotOn = !dotOn;

        wait(1);
    }
}