CQ出版社セミナ "実習・Armマイコン内蔵ペリフェラルを活用するためのC++プログラミング" で使う外付け回路のテスト
Dependencies: mbed UIT_SetOutputPortType UIT_AQM1602 UIT_ADT7410
Diff: main.cpp
- Revision:
- 0:8c850cf6285d
- Child:
- 1:0a21041026c7
diff -r 000000000000 -r 8c850cf6285d main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 03 03:30:50 2020 +0000 @@ -0,0 +1,159 @@ +//---------------------------------------------------------------------- +// セミナ "実習・Armマイコンで学ぶインターフェース回路とプログラミング" +// で使う外付け回路のテスト +// RGB LED D2: 赤, D3: 緑, D4: 青 +// タクトスイッチ D6 +// 温度センサ(ADT7410) D14: SDA, D15: SCL +// 液晶表示器(AQM1602) D14: SDA, D15: SCL +// ADC A0 +// ステッピング・モータ D10: LSB, D13: MSB +// DC モータ D9 +// ADC A1 +// DAC A2 +// +// 1. タクトスイッチと RGB LED のテスト +// 起動時は1秒ごとに発光状態が切り替わる +// タクトスイッチを押すごとに,切替が On/Off する +// 2. 温度センサと液晶表示器のテスト +// 起動直後から気温が液晶表示器に表示される +// 3. ADC(A1), DAC +// ファンクションジェネレータを AIN につなぎ A2 から同じ信号が出力される +// 4. ステッピング・モータ +// A0 に接続されている VR で回転スピードをコントロールする +// +// Mbed オフィシャル・ライブラリのドキュメントは下記の URL +// https://os.mbed.com/docs/mbed-os/ で APIs => Drivers +// +// 2020/03/03, 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 変換器として使用 +PwmOut dcMotor_(D9); // DC モータ駆動用 +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)); + // DC モータのスピード調整 + dcMotor_.write(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 ごと + + // DC モータの準備 + dcMotor_.write(value); + + // 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); + } +} \ No newline at end of file