- 締切済み
PICでUSARTのフレーミングエラーの取得方法について
PIC16F88を使用したUSARTの勉強をしています。MPLAB+CCS-Cの環境で、C言語を多少はやってきましたが、アセンブラーについては全く駄目です。 RS485受信時にフレーミングエラーを検出・取得したいと思っています。 スペシャルファンクションレジスター<RCSTA>(アドレス18h)の<FERR>(2bit)にフレーミングエラーのフラグが立つのですが、C言語でこれを取得する方法がわかりません。 どなたかご教示いただけませんでしょうか。 よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
ちょうど自分もとある理由でまったく同じレジスタを確認するときに使った方法です。 残念ながらCCSではそのレジスタはヘッダで定義されていないので自分でやります。 int* rcsta = 0x18; putc(*rcsta); ポインタ宣言をして中身にアドレス番地を記述すればOKのようです。 自分は中身をUSART経由で確認するためputcを使っていますがアクセスの方法は変わらないと思います。 補足ですがフレーミングエラーが発生している場合は0bitのフラグもたつのでUSART受信割り込みの最初にチェックすると良いと思います。
- kent85
- ベストアンサー率52% (38/73)
> Q3)レジスタをCCS-Cから直接読み出す方法で行き詰っています。 ざっと検索しただけのアドバイスです。 if(RCSTA & 0x04) { /* FERR? */ ; } のようなものでアクセスできそうです。 機種別?のヘッダファイルに、レジスタ定義がされている気がします。 この手のモノのアクセス手法ですが、受信割り込みの場合でたとえると ステータスレジスタをREADして ・正常だったら受信データを読み出せる ・エラーだったらそのエラー要因をクリアしないと、その後もデバイスは動かない だと思います。 --- (1) http://www.ys-labo.com/JJY%20Simulator%20Kit/JJY%20sum.html > interval() エラーステータスクリア (RCSTAのエラー要因をクリアする) > RCSTA = (RCSTA & 0b11111101); //OERR = 0 : オーバーランエラー(データが残っているのに次のデータを受信)クリア) > RCSTA = (RCSTA & 0b11111011); //FERR = 0 : フレーミングエラー(ストップビットがこない)クリア --- (2) USART 受信割り込みハンドラの例 http://www.ccsinfo.com/forum/viewtopic.php?t=17513&highlight=dmx > void Interrupt_USART_Rx(void) > /* Read the data and the Rx status reg */ > rcsta.byte = RCSTA; > data = RCREG; > case WAIT_FOR_DATA: フレーミングエラーを検出 > if (rcsta.bits.FERR) ---- (3) http://amahime.main.jp/sirial/main.php?name=siri#2 > パソコンと通信するには RS-232 プログラム編 MPLAB-C18
- kent85
- ベストアンサー率52% (38/73)
RS232C/422/485 等の経験はありますが、PICはあまりよく知りません。 PIC16F87/88 のデータシート P100 だけを見て書きます。 REGISTER 11-2: RCSDATA : RECEIVE STATUS AND CONTROL REGISTER (18H) > フレーミングエラーのフラグが立つのですが、C言語でこれを取得する方法がわかりません。 おそらくデバッグ中に 「ステータスレジスタを見たらフレーミングエラーが発生していた」 という状態で、PC上からはモニタ出来るけど 「アプリ側から RCSDATA のレジスターを読み出す方法がわかりません」 という質問だととらえました。 Q1) あっていますか? (ミスリードしていますか?) Q2) どのポートでもかまいませんが、ポートアクセスの手法は理解していますか? Q3) どのレジスタでもかまいませんが、レジスタ読み出しの手法は理解していますか? (読み出すのでREAD:STATUSレジスタ属性) Q4) RCSTA は読み出せるけど、BIT2 = FERR の解釈はどうすればいいか不明 であれば、下記の擬似コードのようなものですが、そういう状態ですか? /* 擬似コード的に考える : uint8_t は符号無し8bitの意味 : unsigned charに近い */ const uint8_t BIT1_OERR = 0x02; /* 0000:0010 - #define BIT1_OERR 0x02 */ const uint8_t BIT2_FERR = 0x04; /* 0000:0100 - #define BIT2_FERR 0x04 */ const uint8_t ONERR_BIT12 = ( BIT1_OERR & BIT2_FERR ); /* 0000:0110 - 0x06 */ ; /* 省略 */ const uint8_t rc_sta = RCSTAをどうにかして読み出す; if( (rc_sta & ONERR_BIT12) == 0 ) return 0; /* no error */ if( rc_sta & BIT1_OERR ) puts("(EE) RCSTA BIT1 ON : Overrun Error !"); if( rc_sta & BIT2_FERR ) puts("(EE) RCSTA BIT2 ON : Framing Error !"); ; /* 省略 */ return -1; /* error */ ===== 上記例では、ANDで判断していますが レジスタを定義した共用体変数に入れて ビットフィールド越しにON/OFF判断してもかまいません。 (もちろん、コンパイラが許可しているのであれば…です)
補足
早速のご回答、有難うございます。 Q1)その通りです。 Q2)ポートアクセスは理解しているつもりです。 Q3)レジスタをCCS-Cから直接読み出す方法で行き詰っています。 なるほど、そういたしますと、こんなイメージでよいのでしょうか? /**********************/ 1)USARTからの1バイト受信での割り込み処理 2)割り込みルーティンの中で、 union { int dmxdata; short dm0; short dm1; short dm2; //フレーミングエラー時 1 short dm3; short dm4; short dm5; short dm6; short dm7; } RcvData ; と定義して、 // RCSTAアドレス= 0x18 をRcvDataに1バイト取得 memcpy( &RcvData , 0x18 , 1 ); if( RcvData.dm2 == 1 ){ ------------- } で良いのでしょうか? よろしくお願いいたします。
お礼
ありがとうございます。 早速取り組んでみます。 ccsのフォーラムを調べることに気がつきませんでした。 お手数をおかけいたしましたこと、申し訳ありません。 改めて、ありがとうございました。