Yoji KURODA / Mbed OS mbed-os-control-ex1

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //  mbed-os-io-control
00002 //  I/O制御プログラム(機械工学実験1)
00003 //
00004 //  20161027 ... v1.0 ... originally written by Y.Kuroda for Mechatronics
00005 //  20180917 ... v2.0 ... customised for Jikken1(mbed LPC1768専用)
00006 //  20181004 ... v3.0 ... uses EventQueue
00007 //
00008 #include "mbed.h"
00009 
00010 const int DELTA_T = 1;    // mainスレッドの時間間隔の設定[ms](デフォルトは1ms)
00011 int delta_t = DELTA_T;
00012 int qbits = 6;            // 量子化シフト値
00013 DigitalOut led1(LED1);
00014 DigitalOut led2(LED2);
00015 DigitalOut led4(LED4);
00016 
00017 // p11,12 サンプリング周期設定ピン(デフォルトは0)
00018 // p11上位ビット,p12下位ビット.0:1kHz, 1: 100Hz, 2: 10Hz, 3: 1Hz
00019 InterruptIn samplingtime_MSB(p11);
00020 InterruptIn samplingtime_LSB(p12);
00021 
00022 // p13,14 量子化粒度設定ピン(デフォルトは0)
00023 // p13上位ビット,p14下位ビット.0:10bit, 1:8bit, 2:6bit, 3:4bit
00024 InterruptIn quantization_MSB(p13);
00025 InterruptIn quantization_LSB(p14);
00026 
00027 // アナログ入出力ピン(入出力共に0 - 3.3V)
00028 AnalogOut aout(p18);
00029 AnalogIn  ain(p20);
00030 
00031 // デジタル入力ピン(割り込みにより実現)
00032 InterruptIn din1(p21);
00033 InterruptIn din2(p22);
00034 
00035 // 方形波,パルス波出力ピン
00036 PwmOut squarewave(p23);
00037 PwmOut pulsewave(p24);
00038 
00039 const int SIG_ST = 0x1;    // signal番号
00040 Thread* sthread;
00041 EventQueue queue;
00042 int id = 0;
00043 
00044 // サンプリング処理をするスレッド(時間管理された処理)
00045 void sampling_job(void* v)
00046 {
00047     unsigned short a_data  = ain.read_u16(); // AD入力(ADは12ビット)
00048     aout.write_u16((a_data>>qbits)<<qbits);// DA出力(量子化粒度はピンにより設定)
00049     led4 = !led4;
00050 }
00051 
00052 void setup_thread(void const* arg)     // 設定処理をするスレッド
00053 {
00054     while(true) {
00055         Thread::signal_wait(SIG_ST);   // シグナルを待つ
00056 
00057         // ピンの状態を読み取り,2ビット値に変換
00058         int s_msb = 10, s_lsb = 10;
00059         int q_msb = 10, q_lsb = 10;
00060         const int RETRY = 100;  // 100回調べて9割以上1なら1,それ以下なら0とする.
00061         for(int i=0; i<RETRY; i++) {
00062             s_msb += samplingtime_MSB;
00063             s_lsb += samplingtime_LSB;
00064             q_msb += quantization_MSB;
00065             q_lsb += quantization_LSB;
00066         }
00067         s_msb /= RETRY; s_lsb /= RETRY;
00068         q_msb /= RETRY; q_lsb /= RETRY;
00069 
00070         int samplingtime = (s_msb<<1)&0x2 | s_lsb&0x1;
00071 
00072         // 制御周期を10^nとする(n=0:1s, n=1:0.1s, n=2:0.01s, n=3:0.001s)
00073         delta_t = (int)pow(10.0,(double)samplingtime);
00074 
00075 
00076         squarewave.period_ms(delta_t);  // 方形波の周期の設定
00077         pulsewave.period_ms(delta_t);   // パルス波の周期の設定
00078         squarewave.write(0.5F);         // duty比
00079         pulsewave.write(0.1F);          // duty比
00080 
00081         // 量子化設定ピン(p13,14)の設定を読んで量子化粒度を決定する
00082         // 設定ピンの状態を読み取り,2ビット値に変換
00083         int quantization = (q_msb<<1)&0x2 | q_lsb&0x1;
00084         qbits = 6+quantization*4;   // 量子化サイズの決定
00085         // (デジタル出力時の量子化サイズは 0:1024, 1:256, 2:64, 3:16 steps)
00086 
00087         queue.cancel(id);   // 前回のプロセスキューをキャンセル
00088         printf("delta_t = %d, qbits = %d\n", delta_t, qbits);
00089         id = queue.call_every(delta_t, sampling_job, (void*)0);
00090     }
00091 }
00092 
00093 // 量子化粒度設定ハンドラ
00094 void qsize_handler(void)
00095 {
00096     sthread->signal_set(SIG_ST);  // スレッドへ再開シグナルを送る
00097 }
00098 
00099 //  サンプリングタイム設定割り込みハンドラ...時間設定ピンの状態が変化した時に呼び出される
00100 void pinstate_handler(void)
00101 {
00102     sthread->signal_set(SIG_ST);  // スレッドへ再開シグナルを送る
00103 }
00104 
00105 //  デジタル入力割り込みハンドラ...デジタル入力信号の状態が変化した時に呼び出される
00106 void din_handler(void)
00107 {
00108     led1 = din1;    // ピンの状態をそのままLEDの点灯状態にする
00109     led2 = din2;
00110 }
00111 
00112 int main()
00113 {
00114     sthread = new Thread(setup_thread);   // 設定用スレッドを起動
00115 
00116 
00117     squarewave.period_ms(delta_t);  // 初期周期の設定
00118     pulsewave.period_ms(delta_t);   // 初期周期の設定
00119     squarewave.write(0.5F);         // 初期duty比(方形波=50%)
00120     pulsewave.write(0.1F);          // 初期duty比(パルス波=10%)
00121 
00122     samplingtime_MSB.disable_irq();
00123     samplingtime_MSB.mode(PullDown);
00124     samplingtime_MSB.rise(pinstate_handler);// 周期設定ハンドラの設定.
00125     samplingtime_MSB.fall(pinstate_handler);// 設定ピンの状態変化で
00126     samplingtime_MSB.enable_irq();
00127 
00128     samplingtime_LSB.disable_irq();
00129     samplingtime_LSB.mode(PullDown);
00130     samplingtime_LSB.rise(pinstate_handler);// ハンドラが呼び出される
00131     samplingtime_LSB.fall(pinstate_handler);// ようにする
00132     samplingtime_LSB.enable_irq();
00133 
00134     quantization_MSB.disable_irq();
00135     quantization_MSB.mode(PullDown);
00136     quantization_MSB.rise(qsize_handler);   // 量子化粒度設定ハンドラの設定
00137     quantization_MSB.fall(qsize_handler);
00138     quantization_MSB.enable_irq();
00139 
00140     quantization_LSB.disable_irq();
00141     quantization_LSB.mode(PullDown);
00142     quantization_LSB.rise(qsize_handler);
00143     quantization_LSB.fall(qsize_handler);
00144     quantization_LSB.enable_irq();
00145 
00146     din1.disable_irq();
00147     din1.mode(PullDown);
00148     din1.rise(&din_handler);            // デジタル入力ハンドラの設定
00149     din1.fall(&din_handler);            // din1,2の状態変化でハンドラ
00150     din1.enable_irq();
00151 
00152     din2.disable_irq();
00153     din2.mode(PullDown);
00154     din2.rise(&din_handler);            // が呼ばれる
00155     din2.fall(&din_handler);
00156     din2.enable_irq();
00157 
00158     id = queue.call_every(delta_t, sampling_job, (void*)0);
00159     queue.dispatch();
00160 }