【PIC32MX220F032B】UARTを使ってみる。その2:受信
◆PIC32MX220F032BでUARTをつかってみます。今回は受信割り込みにチャレンジです。
レジスタ設定
データシートDS61168DのPage179~を参照しました。
割り込みの場合は、U1STAレジスタの「URXISEL」bitを下記の中から選定する必要があります。
・0b11:ReServed
・0b10:6byte受信で割り込みフラグが立つ
・0b01:4byte受信で割り込みフラグが立つ
・0b00:1byte受信で割り込みフラグが立つ
1byteだと汎用性が乏しいので「0b01:4byte」にしました。
マスター(PC)からはコマンドとデータが一緒に送れますね。
あとIEC1レジスタの「U1RXIE」bitを1にするのもお忘れなく
ポート設定
データーシートDS61168DのPage146を参照しました。
U1RXは、RA2、RB6、RA4、RB13、RB2、RC6、RC1、RC3が割り当て可能です。
PRA2の場合の記述例は、
U1RXR = 0b0000;//右辺はPRA2を示します。
TRISAbits.TRISA2 = 1;//入力にしなきゃだめでした。
UART受信方法
データシートDS61107EのPage21に受信方法が記載されています。
「URXDA=1」の時にU1RXREGレジスターをロードすればいいみたいです。
割込みの有効化
データシートのDS61108Epage15のExample8-2を参照に割り込み有効をしました。
・INTCONbits.MVEC = 1;//Multi_Vector
・asm volatile(“ei"); //Enable_Interrup
上記2行を記述する必要があります。
データシートpage15の最後方の行は間違ってるっぽいです。
誤:ie/正:ei これにはクソ時間取られました。
推測するにstatusビットのIEと混同したのでしょうか?
また「STATUSbits.IE = 1;」は記述不可でした。どうして?
「INTCONSET = 0x800;」とありますが
セットするなら「0x1000」ではないでしょうか?
割込みの設定
DS61168DのPage89にU1RXのベクターアドレスが記載されています。
関数としては一個目はVectorアドレス、2個目はPriorityとなります。
PIC24Fまでの記述方法と異なるので戸惑いました。
また関数のプロトタイプは始めの方に記載しなくてもいいみたい・・・
ソース
ハイパーターミナルで4回キーを入力するとエコーバックされる仕様です。
プログラムの例はこちら↓
#include <stdio.h> #include <plib.h> #include <p32xxxx.h> #include <stdlib.h> //== OSC:8MHz SYSCLK:40MHz=(OSC_8*MUL_20)/(PLLI_2*PLLO_2) ==== #pragma config FNOSC=FRCPLL, POSCMOD=OFF, FPLLIDIV=DIV_2 #pragma config FPLLMUL=MUL_20, FPBDIV=DIV_1, FPLLODIV=DIV_2 #pragma config FWDTEN=OFF, ICESEL=ICS_PGx2 //== void ==================================================== void U1TXstring(unsigned char *tex, char count); //UART_TX_String unsigned char U1RXstring(void); //UARTReceiveFunction_return(unsigned char) //== string ================================================== unsigned char string_box1[15] = "abcdefg¥r¥n" ; unsigned char rev_data[] = "----¥r¥n"; //UART_receive_string //== main ==================================================== int main(void) { //== OSC ================================================= SYSTEMConfigPerformance(40000000); //40MHz //== PORT ================================================ TRISA = 0x00000000; TRISB = 0x00000000; ANSELA = 0x00000000; ANSELB = 0x00000000; //== T1CON =============================================== T1CON = 0x00000000; //Clear T1CONbits.TON = 0; //Timer1_OFF T1CONbits.TSIDL = 1; //Idelmode:SleepStop T1CONbits.TGATE = 0; //Gatetime:OFF T1CONbits.TCKPS = 0B00; //PS1:1 T1CONbits.TCS = 0; //ClockSource:INT IEC0bits.T1IE = 0; //Interrupt:None IPC1bits.T1IP = 0; //InterruptLevel:0 //== UART ================================================ //PORT_SELECT RPA0R = 0B0001; //U1TX_RPA0 U1RXR = 0B0000; //U1RX_RPA2 TRISAbits.TRISA2 = 1; //U1RX U1MODE = 0x00000000; //Clear U1MODEbits.UARTEN = 1; //15_UART_Enable U1MODEbits.RTSMD = 1; //11_SimplexMode U1MODEbits.BRGH = 0; //3_StandardSpeed*16 U1STA = 0x00000000; //Clear U1STAbits.UTXEN = 1; //10_TX_enable U1STAbits.URXEN = 1; //12_RX_enable U1STAbits.URXISEL = 0B01; //4ByteReceive_Interrupt IEC1bits.U1RXIE = 1; //U1RX_Interrupt_Enable IPC8bits.U1IP = 0B110; //Priority_6 IPC8bits.U1IS = 0B00; //Sub_0 U1BRG = 259; //U1BRG=(Fcy/(16*9600))-1 //======================================================== //== Interrupt ENABLE =========================================== INTCONbits.MVEC = 1; asm volatile("ei"); //======================================================== while(1) { //delay_ms(200); //delay_us(1); }//while(1) }//int main(void) //== U1RXInterrupt ========================================================= void __ISR(32, ipl6) U1RXInterrupt(void) //UARTReceiveInterrupt { IFS1bits.U1RXIF = 0; //Interrup_Flag_Clear //== UART_REV ============================================================== *rev_data = U1RXstring(); //UARTReceiveFunction U1TXstring(rev_data,6); //EchoBack } //== U1TXstring ============================================================== void U1TXstring(unsigned char *tex, char count) { char i; for(i=0; i<count; i++) { while(U1STAbits.UTXBF); //Buffer_empty U1TXREG = tex[i]; //set_Buffer }//for(i=0; i<count; i++) }//void U1string(unsigned char *tex, char count) //== U1RXstring ============================================================== unsigned char U1RXstring(void) { char i; for(i=0; i<4; i++) //4byteInterrupt { while(!U1STAbits.URXDA); //Buffer_has_data rev_data[i] = U1RXREG; //SET_Buffer }//for(i=0; i<count; i++) return(*rev_data); }//void U1string(unsigned char *tex, char count
回路図

ディスカッション
コメント一覧
0b01:4byte受信で割り込みフラグが立つ
・0b00:1byte受信で割り込みフラグが立つ
1byteだと汎用性が乏しいので「0b01:4byte」にしました。
マスター(PC)からはコマンドとデータが一緒に送れますね。