akira.kei が 2025年03月06日09時51分39秒 に編集
コメント無し
本文の変更
[<前の記事](https://elchika.com/article/3ae3aa85-f066-4119-9658-db1b73c2f87c/) : [次の記事>]()
[<前の記事](https://elchika.com/article/3ae3aa85-f066-4119-9658-db1b73c2f87c/) : [次の記事>](https://elchika.com/article/255eb8fa-f3fd-4546-89e2-786402b65667/)
## シリアルポートで受信したら送信する USBシリアル変換でPCと接続した際に、PCからのコマンドでPICが何らかの処理を行う、というケースを想定してみた。タイトルが「送受信」ではなく「受送信」なのはそういう意味だ。 今回は制御文字以外を受け取ったら、1つだけインクリメントして返す、という感じで作ってみた。例えば「HAL(空白)(改行)」と送ると「IBM(空白)(改行)」と返す。  RA5をTXにしてUSBシリアルRXに、RA4をRXにしてUSBシリアルTXに、LEDをRA2に接続してみた。 ## pragma_config.h いつもと同じなので割愛 ## main.c 冒頭はいつものようにxc.hとpragma_config.hを読んで、LEDを定義し、アナログ無効でディジタルバッファ無効としておく。 ``` #include <xc.h> #include "pragma_config.h" #define LED LATAbits.LATA2 void main(void) { ANSELA=0; TRISA=0xff; ``` LEDはRA2に接続し、念の為点灯させておく。TRISAの設定を忘れがち。 ``` // TRISAbits.TRISA2=0; LED=1; ``` EUSARTの設定は以下の通り。いちいちレジスタをクリアしてから該当ビットを立てているのは可読性のためなので、単純に値を代入しても良い。非同期9600ボー(1MHz)の場合「SYNC=0、BRG16=1、BRGH=1、SP1BRG=25」まで確定で、モジュール有効化(SPEN=1)、連続受信有効(CREN=1)、送信有効(TXEN=1)とすればいいだけだ。ちなみに最後のPPSとTRISAの設定を忘れがちだ。 ``` // BAUD1CON=0; BAUD1CONbits.BRG16=1; RC1STA=0; RC1STAbits.SPEN=1; RC1STAbits.CREN=1; TX1STA=0; TX1STAbits.TXEN=1; TX1STAbits.BRGH=1; SP1BRGL=25; SP1BRGH=0; RXPPSbits.RXPPS=0b00100; //RA4->RX TRISAbits.TRISA5=0; RA5PPSbits.RA5PPS=0b10100; // TX->RA5 ``` ## ループ部 エラー処理もタイムアウトも考えなければ単純にレジスタを読んで書けば良い。受信フラグ(PIRbits.RCIF)と送信可能フラグ(PIR1bits.TXIF)のANDをとり、1文字受信して'0'より小さかったらそのまま、大きかったらインクリメントして送信し、LEDを反転する。LED点滅はどうせ見えないので単なるオマケだが、送信文字数が奇数なら点滅する。 ``` // while(1) { if(PIR1bits.RCIF && PIR1bits.TXIF) { char c; c=RC1REG; if(c<'0') TX1REG=c; else TX1REG=c+1; LED=~LED; } } ```