PICマイコンの使い方

PICマイコンの8bitマイコンから32bitマイコンまで使いこなすぞ! 周辺機能やアセンブラ、C言語を使いこなすぞ。ARMには負けないぞ! 頼みの綱はPIC32MZだ!たのしみだなー

PIC32MX220F032B

【PIC32MX220F032B】UARTを使ってみる。その2:受信

◆PIC32MX220F032BでUARTをつかってみます。今回は受信割り込みにチャレンジです。



1)レジスター設定
データシートDS61168DのPage179~を参照しました。
割り込みの場合は、U1STAレジスタの「URXISEL」bitを下記の中から選定する必要があります。
・0b11:ReServed
・0b10:6byte受信で割り込みフラグが立つ
・0b01:4byte受信で割り込みフラグが立つ
・0b00:1byte受信で割り込みフラグが立つ
1byteだと汎用性が乏しいので「0b01:4byte」にしました。
マスター(PC)からはコマンドとデータが一緒に送れますね。
あとIEC1レジスタの「U1RXIE」bitを1にするのもお忘れなく

2)ポートの設定
データーシートDS61168DのPage146を参照しました。
U1RXは、RA2、RB6、RA4、RB13、RB2、RC6、RC1、RC3が割り当て可能です。
PRA2の場合の記述例は、
U1RXR = 0b0000;//右辺はPRA2を示します。
TRISAbits.TRISA2 = 1;//入力にしなきゃだめでした。

3)受信
データシートDS61107EのPage21に受信方法が記載されています。
「URXDA=1」の時にU1RXREGレジスターをロードすればいいみたいです。

4-1)割り込み設定の有効
データシートの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」ではないでしょうか?

4-2)割り込み関数
DS61168DのPage89にU1RXのベクターアドレスが記載されています。
関数としては一個目はVectorアドレス、2個目はPriorityとなります。
PIC24Fまでの記述方法と異なるので戸惑いました。
また関数のプロトタイプは始めの方に記載しなくてもいいみたい・・・

5)プログラムの例
ハイパーターミナルで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)


間違ってたらゴメンね!

6)回路図はこちら
21f400a2.png

【PIC32MX220F032B】UARTを使ってみる。その1:送信

◆PIC32MX220F032BでUARTをつかってみます。手始めに文字列を送信してみます。



1)レジスター設定
データシートDS61107EのPage26に薄らと記述例があります。
ほとんどPIC24Fと同様です。。。

2)ポートの設定
データーシートのPage148を参照にしました。
PIC24Fと違いU1TXはどのピンでも対応という訳ではなく
RPA0Rは可能だけど、RPA1Rは他の機能という感じです。
こちらは記述例が全くないのでトライアンドエラーで何とかしました。
左辺がBit(pin)で右辺が機能となります。U1TXは「0b0001」となります。

3)送信
データシートDS61107EのPage18に送信方法が記載されています。
U1TXREGレジスターにロードすればいいみたいです。

4)プログラムの例
MPLABではターゲットに【PIC32MX220F032B】が無かったので泣く泣くMPLABXを使いました。
ボーレートは9600bpsです。データシートDS61107EのPage14Table21-2を参照しました。
実行は、文字列’abcdefg’と改行とNewラインをずーっとです。
プログラムの例はこちら↓>

#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 U1string(unsigned char *tex, char count);
//== string ==================================================
unsigned char string_box1[15] = "abcdefg¥r¥n" ;
//== main ====================================================
int main(void) {
//== OSC =================================================
SYSTEMConfigPerformance(40000000); //40MHz
//== PORT ================================================
TRISA = 0x00000000;
TRISB = 0x00000000;
//== UART ================================================
RPA0R = 0B0001; //U1TX_RPA0
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
U1BRG = 259; //U1BRG=(Fcy/(16*9600))-1
//========================================================
while(1)
{
U1string(string_box1,9);
//delay_ms(200);
//delay_us(1);
}//while(1)
}//int main(void)

//== U1string ==============================================================
void U1string(unsigned char *tex, char count)
{
char i;
for(i=0; i<count; i++)
{
while(U1STAbits.UTXBF);
U1TXREG = tex[i];
}//for(i=0; i<count; i++)
}//void U1string(unsigned char *tex, char count)

間違ってたらゴメンね!

5)ハイパーターミナルで確認


5)回路図はこちら
df12f96c.png


ギャラリー
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F08KL200】PIC24F08KL200でsprintfを使う
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
  • 【PIC24F04KA200】PIC24F04KA200ではsprintfが使えない件
メッセージはこちちらからお願いします。

名前
メール
本文
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

ブログパーツ
  • SEOブログパーツ
にほんブログ村 その他趣味ブログ 電子工作へ
にほんブログ村
アクセスカウンタ
アクセスランキング