realtime process control with RTOS
Fork of mbed-os-example-mbed5-blinky by
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 }
Generated on Sat Jul 23 2022 16:03:29 by
1.7.2
Yoji KURODA
