2012年9月2日日曜日

PIC32MX220F032B-03 UARTを使う(受信割り込み)(printf出力)


秋月にてPIC32MX220F032Bが220円と大変安価かつDIPにて32bitマイコンが手に入るようになりました.
折角なので,PIC16FシリーズだけでなくPIC32MXも遊んでみようと試みようと
後閑さんの『高速・多機能を実現する pic32mx活用ガイドブック
を購入させていただきました.
大変良くまとまっています.PIC32MXをC32コンパイラで使うなら手元に置いておきたい.購入するべきです.
しかしながらPIC32MX340F256H用に書かれたものであり,PIC16Fシリーズで扱っていたCCS-Cなどと異なり,単純なコピー&ペーストを行っただけではコンパイルエラーになったり正しい動作が行われなかったりしまてしまいました.
ここではPIC32MX220F032B用に書き直して紹介していきたいと思います.

注意:私の提供する情報を元に何らかのトラブルが生じても責任を負いません.


<今回行うこと>
PIC32MX220F032Bにてシリアル通信,UARTの基本機能を扱えるようにします.
Peripheral Pin Select (PPS) Peripheralと呼ばれる機能があり,これによってある程度UARTを使用するピンを指定することができます.
UART1で送信と受信を行います.送信はprintf出力を行えるようにし,受信では割り込み処理が行えるようにします.
シリアル通信が正常かどうか確認するため「Tera Term」を利用します.
  • UART1(RX):RB13で使用(受信割り込み)
    • "["の受信でカウントアップ,"]"でカウントダウンを行う
  • UART1(TX):RB15で使用(printf出力)
    • 50msec待機ごとに(50msec周期ではない)カウント数を送信


<対象者>
PIC32MX220F032BでLEDチカチカ(+入力)をするを理解した方


<用意するもの>
  • PIC32MX220F032BでLEDチカチカ(+入力)をするの環境
    • パソコン(「MPLAB X IDE v1.30」と「C32 Cコンパイラv2.02」の環境で行いました)
    • PIC32MX220F032B(言うまでもないけど)
    • PICkit3(PICkit2でも書き込む方法があるらしい)
    • ブレッドボード(EIC-102が好きなのですが,単品で買える店が少ない)
    • ジャンパ線( EIC-102J付属品で良いと思う)
    • 抵抗 1k Ω(LED用),10k Ω(プルアップ用) 各1こ
    • コンデンサ 10uF 最低1こ (0.1uでも動作したが,「なし」では動作しなかった)
    • LED 1こ
  • Tera Term などといった通信ソフト
  • 3.3VレベルのUSBシリアル変換ケーブル 

<資料>
最新版を探してきたつもりですが,検索かけ直して入手する方が良いと思います.

<配線>
  • 変換ケーブルの黒(GND)をブレッドボードのマイナス(GND)へ接続
  • 変換ケーブルの橙(TXD)をブレッドボードのRX(RB13,24ピン)へ接続
  • 変換ケーブルの黄(RXD)をブレッドボードのTX(RB15,26ピン)へ接続
TTL-232R-3V3を使用する場合には,図1に示すような配線になっていれば配線完了です.
図1 シリアル変換ケーブルの接続

<プログラム>
以下からソースコードをダウンロードできます.(リンク先にてCtrl+SでZIP保存)
https://docs.google.com/open?id=0B25yKH5pEApFc0g2TS1vOEFmVjQ
まずはPPSの設定を行いましょう.
PIC32MX220F032Bデータシートのp145,「11.3 Pripheral Pin Select」を開きましょう.
TABLE11-1および11-2に具体的なピンの対応表が載っています.
以下のように宣言すれば使用できます.他のペリフェラルについても同様に設定を行えます.
     mPORTBSetPinsDigitalIn( BIT_13 );
     U1RXR = 0b0011;    //PIN RPB13 = RX
     mPORTBClearBits( BIT_15 );
     mPORTBSetPinsDigitalOut( BIT_15 );
     RPB15R = 0b0001;   //PIN RPB15 = TX

次にUARTの初期設定(割り込みに関する宣言を含む)を行います.
ボーレートが9600bpsと大変低速の設定にしています.お好みで変更してください.
     UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY);
     UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
     UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
     UARTSetDataRate(UART1, SYSCLK, 9600);
     UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
     
     INTEnable(INT_U1RX, INT_ENABLED);//INT_SOURCE_UART_RX(UART1)
     INTSetVectorPriority(INT_VECTOR_UART(UART1), INT_PRIORITY_LEVEL_2);
     INTSetVectorSubPriority(INT_VECTOR_UART(UART1), INT_SUB_PRIORITY_LEVEL_0);

以下の関数を宣言することによってUARTの送信をprintf関数で扱えるようになります.
ただし,printf関数はプログラムサイズが大変大きいので注意が必要です.
 void _mon_putc (char c)
 {
   while (U1STAbits.UTXBF);
   U1TXREG = c;
 }

受信割り込みの冒頭だけ補足をします.
後閑さんの『高速・多機能を実現する pic32mx活用ガイドブック』と同様にmU1RXClearIntFlag();を入力するとコンパイルエラーとなります.何故かMX220Fでは未定義扱いになります.そのため,レジスタを直接いじる必要があります.IFS1bits.U1RXIF = 0;と入力すると無事に動作しました.
void __ISR(32, ipl2) U1RX_interrupt(void){
 char RcvData;

        IFS1bits.U1RXIF = 0;        //mU1RXClearIntFlag();  
 RcvData = getcUART1();

後閑さんのサンプルプログラムでは,動作停止や再開,カウントアップダウンが多少異なります.
そのあたりについては『高速・多機能を実現する pic32mx活用ガイドブック』を参考にしてみてください.


ブログランキング・にほんブログ村へ

0 件のコメント:

コメントを投稿