/***** PWM出力とA/D入力のテスト *****/ // USB(Serial)で通信 // VrefにLM4050-2.5を接続 A0でA/D入力 // PWM周波数は4kHz, 12bit分解能 GP6出力 /***** 送信データ *****/ char tx_str[64]; // 送信文字列 /***** シリアル1行入力 *****/ #define RXBF_SIZ 32 // 文字バッファ文字数 char rx_bff[RXBF_SIZ+1]; // 受信文字バッファ (+null) byte f_rxok; // 受信データありフラグ /***** シリアル1行受信 *****/ // CRでターミネート f_rxokを1に // エコーバックなしに // なし→BSで1文字戻す void rxbff(void) { static byte cnt = 0; // 受信文字数 char c; if(Serial.available()){ // 受信データあり if(f_rxok == 0){ // 前データ受信処理した c = Serial.read(); // 1文字読み出し if(c == '\r'){ // CR? rx_bff[cnt] = '\0'; // nullを最後に // Serial.println(); // 改行 f_rxok = 1; // 受信成功 cnt = 0; // 最初から } // else if(c == '\x08'){ // BS? (処理なしに) // if(cnt > 0){ // cnt--; // 1文字戻す // Serial.print("\b \b"); // BS,space,BS // } // } else{ // 文字 if((cnt < RXBF_SIZ) && // バッファサイズ内 (isprint(c))){ // 表示可能文字0x20~0x7E // Serial.write(c); // エコーバック rx_bff[cnt] = c; // バッファに入れる cnt++; // 1文字進める } } } } } /***** Break処理付のdelay *****/ // シリアル受信あればdelayを中断 void bkdelay(word dly) { word tn, t; tn = (word)millis(); // now while(1){ t = (word)millis(); // 経過 if((word)(t - tn) >= dly) break; if(Serial.available()) break; // 受信データ } } /***** 平均処理付A/D入力 *****/ // avr:平均回数 word adavr(word avr) { word ad; word i; uint32_t add; // 平均加算値 if(avr <= 1){ // avr 0,1 // gpio_put(2, HIGH); // GP2 H ad = analogRead(A0); // 生A/D値 // gpio_put(2, LOW); // GP2 L } else{ // avr 2以上 add = 0; for(i = 0; i < avr; i++){ // gpio_put(2, HIGH); // GP2 H ad = analogRead(A0); // 生A/D値 // gpio_put(2, LOW); // GP2 L add += (uint32_t)ad; // 加算 } ad = (word)(add / avr); // 平均値 } return ad; // 12bit A/D値 } /***** SETUP *****/ void setup() { // Serial.begin(9600); // TX0 …USBだとなしで行ける? pinMode(2, OUTPUT); // GP2 pinMode(3, OUTPUT); // GP2 pinMode(25, OUTPUT); // LED // A/D analogReadResolution(12); // 12bit分解能 // PWMでD/A出力 analogWriteFreq(4000); // PWM周波数4kHz analogWriteResolution(12); // 12bit分解能(0~4095) analogWrite(6, 0); // GP6 0Vに } // 繰り返しデータ word ad; // A/D値 word da; // D/A:PWM設定値 char *s; // 入力文字列 最初の word n; // 文字列番号 5つまで char *s_in[5]; // 文字列5つ word d_in[5]; // 入力 start,end,step,avr,wait byte j_exc; // 実行区分 /***** LOOP *****/ void loop() { byte f_x25 = 0; // LED点滅用 delay(1000); // 1文字待ってから起動メッセージ while(!Serial.available()); // 受信データ待ち Serial.read(); // 1文字読み出し Serial.println("# A/D test out:PWM GP6 in:AD0"); delay(500); while(1){ f_x25 ^= 1; // LED トグル gpio_put(25, f_x25); // LED出力 rxbff(); // 1行受信処理 switch(j_exc){ // 実行区分 case 0: // コマンドプロンプト表示 Serial.print("#Start End Step Avr Wait >"); d_in[2] = 16; // step値を16に d_in[3] = 1; // 平均回数=1で d_in[4] = 200; // wait時間を200msに j_exc = 1; break; case 1: // コマンド入力 if(f_rxok){ f_rxok = 0; Serial.println(); // 改行 n = 0; s = strtok(rx_bff, " ,"); // 最初の文字分離 while(s != NULL){ s_in[n] = s; d_in[n] = atoi(s_in[n]); // 数字に s = strtok(NULL, " ,"); // 次文字分離 n++; if(n >= 5) break; // 5つまで } if(n == 0){ // 数値入力なし j_exc = 0; // プロンプトから } else if(n == 1){ // start一つだけ da = d_in[0]; // D/A値 analogWrite(6, da); // PWM出力して delay(1000); // wait j_exc = 2; // A/D入力繰り返しへ } else{ // end,step,waitで j_exc = 3; // PWM繰り返しへ } } break; case 2: // A/D入力表示続行 ad = analogRead(A0); // A/D値 sprintf(tx_str, "D/A:%4d A/D:%4d", da, ad); Serial.println(tx_str); bkdelay(1000); // 1秒 if(f_rxok){ // break? f_rxok = 0; Serial.println("#Break"); j_exc = 0; } break; case 3: // start,end,step,avr,wait da = d_in[0]; // start値 analogWrite(6, da); // PWM出力 Serial.println("#D/A A/D diff"); bkdelay(1000); // 1秒 j_exc = 4; // A/D入力繰り返しへ break; case 4: // loop analogWrite(6, da); // PWM出力 bkdelay(d_in[4]); // wait ミリ秒 ad = adavr(d_in[3]); // avr A/D平均処理 sprintf(tx_str, "%4d %4d %5d", da, ad, (ad - da)); // 差も出力 Serial.println(tx_str); if(da >= d_in[1]){ // endと比較 おわり? Serial.println(); // 改行x2 Serial.println(); j_exc = 3; // A/D入力繰り返しへ } da += d_in[2]; // +step if(f_rxok){ // break? f_rxok = 0; Serial.println("#Break"); j_exc = 0; } break; } } }