/***** IrDA通信テスト *****/ // Arduino UNOで // 秋月電子通商の AE-RPM851A IrDAモジュール // マイクロチップ のUART←→IrDA変換IC // PB3 D11 OC2Aでclkを出力 // PB4 D12 でリセット出力 /***** 送信データ *****/ char tx_str[64]; // 送信文字列 /***** シリアル1行入力 *****/ #define RXBF_SIZ 32 // 文字バッファ文字数 char rx_bff[RXBF_SIZ+1]; // 受信文字バッファ (+null) byte f_rxok; // CRで受信データ確定 byte f_rxecho = 1; // 受信時エコーバックの有無 // 1なら受信文字をエコーバック /***** シリアル1行受信 *****/ // CRでターミネート f_rxokを1に // f_rxechoでエコーバックの有無 // エコーバック有なら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(f_rxecho){ // エコーバックあり if(cnt > 0){ // バッファにデータあり cnt--; // 1文字戻す Serial.print(F("\b \b")); // BS,space,BS } } } else{ // 文字 if((cnt < RXBF_SIZ) && // バッファサイズ内 (isprint(c))){ // 表示可能文字0x20~0x7E if(f_rxecho){ // エコーバックあり Serial.write(c); // 受信文字エコーバック } rx_bff[cnt] = c; // バッファに入れる cnt++; // 1文字進める } } } } } /***** SETUP *****/ // 153.6kHzが欲しいけどメインクロックが // 16MHzなので153.85kHzになってしまう。 void setup() { Serial.begin(9600); // 通信 pinMode(11, OUTPUT); // PB3 OC2A clk出力 pinMode(12, OUTPUT); // PB4 /RESET出力 pinMode(13, OUTPUT); // PB5 LED出力 // タイマー2 OC2A clk出力 (153.6kHzが目標) TCCR2A = 0b01000010; // |||| ++---- WGM21,20 CTC OCR2A モード // ||++-------- Port動作 // ++---------- OC2A PB3 トグル出力 TCCR2B = 0b00000001; // || |+++---- クロック 16MHz/1 // || +------- WGM22 // |+---------- FOC2B // +----------- FOC2A OCR2A = 52 - 1; // 16MHz/52=307.7kHz トグルで153.85kHz } /***** LOOP *****/ void loop() { byte j_exc = 0; //実行区分 word tm_1ms = 0; // 1msタイマー word tm_led = 0; // LED点滅用 1msタイマー byte f_rxstart = 0; // 受信開始フラグ uint32_t tn, tm; byte i, n; tm = millis(); // 1ms値 // 実行loop while(1){ // loop tn = millis(); // msタイマー現在値 if(tm != tn){ // 変化あれば1ms経過 tm = tn; // 新値 if(tm_1ms) tm_1ms--; // 1msタイマーダウンカウント if(tm_led) tm_led--; // LED点滅タイマー if(tm_led == 0){ // タイムアップでLED点滅 tm_led = 500; // 0.5秒 PINB |= (1 << PB5); // LED(PB5)点滅1秒周期 } } // 受信処理 if(f_rxstart) rxbff(); // CRまで文字列入力 // 処理区分実行 switch(j_exc){ // 実行区分 case 0: // MCP2122リセット digitalWrite(12, LOW); // PB4 リセット出力Lに tm_1ms = 500; // 0.5秒 j_exc++; break; case 1: // リセットタイマー待ち if(tm_1ms == 0){ digitalWrite(12, HIGH); // PB4 リセット解除 tm_1ms = 100; // 0.1秒 j_exc++; } break; case 2: // タイトル出力 if(tm_1ms == 0){ Serial.println("Test IrDA"); f_rxstart = 1; // 受信処理開始 j_exc++; } break; case 3: // プロンプト Serial.print(">"); j_exc++; break; case 4: // 1行シリアル受信を待ってHEXで送信 if(f_rxok){ f_rxok = 0; Serial.println(); // 改行 n = strlen(rx_bff); if(n){ // 文字あり? Serial.print(" "); // スペース1つ for(i = 0; i < n; i++){ // バッファの文字を出力 Serial.print(" "); // スペース2つ Serial.write(rx_bff[i]); // 1文字 } Serial.println(); // 改行 Serial.print(" "); // スペース1つ for(i = 0; i < n; i++){ // 16進で出力 sprintf(tx_str, " %02X", // 00~FF(文字コード) rx_bff[i]); Serial.print(tx_str); } Serial.println(); // 改行 } j_exc--; // プロンプトへ } break; } } }