本文へ移動
サポートシェアリングソリューション
OKWAVE Plus
「OKWAVE Plus の利用」に関するアンケートご協力のお願い
アンケートに答えると抽選で500名様にAmazonギフト券100円分をプレゼント!
アンケートはこちら

このQ&Aは役に立ちましたか?

ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:c18でのusart受信割り込み)

c18でのusart受信割り込み

2023/09/07 05:48

このQ&Aのポイント
  • usart受信割り込みの実装方法を教えてください
  • c18を使用してpic18f14k50でusart受信割り込みを行いたいです
  • usart受信割り込みが正常に発生しない場合にはどのような設定が必要ですか?
※ 以下は、質問の原文です

c18でのusart受信割り込み

2010/09/26 18:29

いつもお世話になっております。
pic18f14k50を使用して設計を行っています。
コンパイラはc18です。

usartで受信したときに割り込みを発生させ、規定の処理を実行したいのですが、割り込みが発生せずに困っております。
timer0を使用した割り込みの記述を行った場合は、割り込みは問題なく発生しました。

usart受信割り込みを以下のようなコードで行いたいのですが、間違いがわかる方がいらっしゃいましたら、ご指摘をお願い致します。
void main(){

TRISB=0x20;
TRISC=0;

OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,10);
    IPENbits.IPEN=0;
IPR1bits.RCIP=1;
PIE1bits.RCIE=1;
INTCONbits.GIE=1;

while(1){

}
}

#pragma interrupt isr
#pragma code isrcode = 0x08
void jump_isr(void){
_asm
goto isr
_endasm
}

#pragma code
void isr(void){ //割り込み関数
if (PIR1bits.RCIF == 1){
PIR1bits.RCIF =0;
        処理;
}
}

質問者が選んだベストアンサー

ベストアンサー
2010/09/26 19:20
回答No.2

初期化で
INTCONbits.PEIE =1;
を入れる必要があります。

これはデバッガを使って確認しているのでしょうか?
もし、ICD3などを使用している場合はデバッガがHigh priorityを使用しますのでユーザーはLow priorityを使用しなければなりません。
ベクタも異なりますので、やってみてください。

CPUのデータシート(3.0 MEMORY ORGANIZATION)を見ますと
High Priority Interrupt Vector は0008hですが
Low Priority Interrupt Vector は0018hとなっていますので
そうなのかと考えました。
私は違うコンパイラを使ってますのでこんな表現になります。
void low_priority interrupt my_isr_low(void){

それとは別にSPENを1にする必要があります。
詳しくはデータシート16.1.2.9 Asynchronous Reception Set-upにある
手順通りにやってみてください。
順序が違うと動作しない場合があります。
また、CPUのピンもオシロで確認してください。

お礼

2010/09/26 19:53

ご回答ありがとうございます。
上記のアドバイスをもとに初期化に追記しましたが、割り込みが発生しません。下記の用にコードを変更しました。

void main(){

TRISB=0x20;
TRISC=0;

OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,10);

RCONbits.IPEN=0;
IPR1bits.RCIP=1;
PIE1bits.RCIE=1;
INTCONbits.PEIE=1;
INTCONbits.GIE=1;

while(1){
}
}

#pragma interrupt isr
#pragma code isrcode = 0x08
void jump_isr(void){ //割り込み関数へジャンプ
_asm
goto isr
_endasm
}

#pragma code
void isr(void){
if (PIR1bits.RCIF == 1){
PIR1bits.RCIF =0;
printf("受信");
PIR1bits.RCIF =1;
}
}

ご回答ありがとうございます。
デバッガは使用していません。
ベクタが異なるということは#pragma code isrcode = 0x08 の部分を変更する必要があるということなのでしょうか?
知識不足で質問ばかりで申し訳ありませんが、よろしくお願いいたします。

質問者

このQ&Aは役に立ちましたか?

この質問は投稿から一年以上経過しています。
解決しない場合、新しい質問の投稿をおすすめします。

質問する

その他の回答 (2件中 1~2件目)

2010/09/26 19:12
回答No.1

pic18f14k50 は 使ったことないが 


大体の割り込みの失敗をしてるみたい


#pragma code
void isr(void){ //割り込み関数
if (PIR1bits.RCIF == 1){ //2重割り込みチェック
PIR1bits.RCIF =0; // 割り込み禁止
        処理;
}
}



割り込み禁止で抜けてるよ


#pragma code
void isr(void){ //割り込み関数
if (PIR1bits.RCIF == 1){ //2重割り込みチェック
PIR1bits.RCIF = 0; //割り込み禁止

        処理;

        PIR1bits.RCIF = 1; //割り込み許可
}
}




http://www.kumikomi.net/archives/2009/09/_pic2.php?page=6



void main(){

TRISB=0x20;
TRISC=0;

OpenUSART(USART_TX_INT_OFF
& USART_RX_INT_ON
& USART_ASYNCH_MODE
& USART_EIGHT_BIT
& USART_CONT_RX
& USART_BRGH_HIGH,10);


    IPENbits.IPEN=0;
IPR1bits.RCIP=1;

//    PIE1bits.RCIE=1;  //←割り込みフラグの間違いでは?         PIE1bits.RCIF=1;  //←割り込み処理許可


INTCONbits.GIE=1;

while(1){

}
}

//割り込みベクタの設定
pragma interrupt isr
#pragma code isrcode = 0x08
void jump_isr(void){
_asm
goto isr
_endasm
}

main の
INTCONbits.GIE=1; // が全面割り込みの許可らしい





割り込み
二重割り込みの処理

#pragma code
void isr(void){ //割り込み関数
if (PIR1bits.RCIF == 1){ //2重割り込みチェック
PIR1bits.RCIF = 0; //割り込み禁止

        処理;

        PIR1bits.RCIF = 1; //割り込み許可 ← 
                    //これがないと 
//割り込み終了後
//PIR1bits.RCIF = 0;
//になって 
//2重割り込みチェック
//引っかかり
                    //ここに入ってこれないよ   
}
}

誤記が直ってない
main の


PIE1bits.RCIE = 1;
      ↑  



割り込みの
PIR1bits.RCIF == 1
PIR1bits.RCIF = 0;
PIR1bits.RCIF = 1;



多分 PIR1bits.RCIE
         ↑
が正解  

お礼

2010/09/26 19:51

ご回答ありがとうございます。
下記の内容が理解できなかったのですが、割り込み禁止で抜けてる とは
どういったことを表しているのでしょうか?
私の理解不足のため申し訳ありません。

//#pragma code
//void isr(void){ //割り込み関数
// if (PIR1bits.RCIF == 1){ //2重割り込みチェク
// PIR1bits.RCIF =0; // 割り込み禁止
//        処理;
// }
//}
//↑
//割り込み禁止で抜けてるよ

質問者

お礼をおくりました

さらに、この回答をベストアンサーに選びますか?

ベストアンサーを選ぶと質問が締切られます。
なおベストアンサーを選びなおすことはできません。