YS電子工作ラボ

PIC - PC(VC#)間
    UART 文字列送受信

(→プロジェクトファイル(Harmony Ver.2.04版 ) ダウンロード


PIC32MZと VC#で作成したPCアプリケーション間での UARTによる文字列の送受信の例を紹介します。


<仕様>
 ・PCとPIC32MZ間でUART接続による文字列の送受信をおこなう。
 ・USBのライブラリはHarmonyのUARTモジュールをつかうこと
 ・PC側から文字列に対して PIC側からそれぞれに対応した文字列を返信すること
  送受信の文字列は 以下とする

      PCからの送信文字列 PICからの返信文字列
Japan\r Tokyo 
America\r Washington
U.K.\r  London
France\r  Paris
How are you?\ Pardon?

 ・PICのキャラくタ液晶はI2Cインターフェースのキャラクタ液晶とし、以下を表示のこと。
   1行目 …… PCからの受信文字列
   2行目 …… PCへの送信文字列

 ・PICは起動後すみやかに PC側に 下記文字列を送信のこと
    Hellow World !!\r\n"

 ・PC側のアプリケーションは マイクロソフトのVC# で作成のこと。  実行ファイルを以下からダウンロードできます。

 ・PC側のアプリケーションは以下のようなダイアログウィンドウとする。(PC側のアプリケーションについは( →URL ) 参照願います。
  すなわち、
   1. コンボボックスから送信文字列を選択して 送信ボタンをクリックするとPIC側に送信をおこなう。
   2. 受信文字列は リッチテキストボックスに順次追加表示する。


<回路図> (→PDFファイル


<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。  





<動作結果> (→ 動画: 080pのHD動画を見ることができます。)

 









<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
      (以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なることがあるかもしれませんので注意してください。)

 ■ USARTに関するMHCは、以下のように設定します。
   ■ Options

項目 ①Config設定
Device & Project Configuration
  > PIC32MZ2048 Device Configuration
②USART設定
Harmony Framework Configuration > Drivers
 > USART
MHC  
備考 デフォルトからの変更要領:
 FPLLIDIV: DIV3
 FPLLICLK: PLL_POSC
 POSCMOD: EC

システムクロック周波数: 200MHz
外部OSC: 24MHz
タイマ用ペリフェラルクロック
     周波数(PBCLK3): 100MHz


#pragma config FNOSC = SPLL
#pragma config POSCMOD = EC
#pragma config FPLLIDIV = DIV_3
#pragma config FPLLICLK = PLL_POSC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2 
デフォルトからの変更要領:
 Use USART Driver? チェックを入れる
 USART Module ID: USART_ID_6


■ キャラクタ液晶表示のライブラリ 1lcd_lib_XC32.h と 1lcd_lib_XC32.cを main.cと同じフォルダにコピーして、プロジェクトに追加します。
     (詳細→ キャラクタ液晶表示方法 参照




■ app.cに、青字部分を追加します。

①インクルードファイルを追加します。stdio.hがないと、sprintf( )がコンパイラのバージョンによってコンパイルで警告となることが
  あります。
  #include <stdio.h>

➁ 所要の変数、及び送受信文字列の判定に係る文字列を定義します。
  int delay_Clock = 200000000; //システムクロック:200MHz
  char Buf[32];
  char buf[32];

  int ix = 0;
  char* str;
  extern char data;
  int Num;

  char Japan[] = "Japan";
  char America[] = "America";
  char UK[] = "U.K.";
  char France[] = "France";
  char Tokyo[] = "Tokyo";
  char Washinton[] = "Washinton";
  char London[] = "London";
  char Paris[] = "Paris";
  char Pardon[] = "Pardon ?";



 ③ 1バイト送信する関数です。 送信バッファに1バイトを書き込み、送信バッファが空になるまで待ちます。
    void Write_Byte(char chr) //1バイト送信関数
    {
      PLIB_USART_TransmitterByteSend(USART_ID_6, chr); //送信バッファーに1バイト書込み・送信
      // U6TXREG = chr; ////送信バッファーに1バイト書込み・送信
      while (!PLIB_USART_TransmitterIsEmpty(USART_ID_6)); //送信バッファーが空になるまで待つ
      //while(!U6STAbits.TRMT); //送信バッファーが空になるまで待つ
    }


 ④ 文字列を送信する関数です。 1バイト送信したら、ポインタを進めます。文字列の終端の\0を検出するまで繰り返し、1バイトづつ
     文字列を送信します。
    void WriteString(const char *str) //文字列送信関数
    {
      while(*str)
      {
        Write_Byte(*str); //データ送信
        str++;
      }
    }



 ⑤受信したデータを判別する関数です。'\r'で文字列の終端を検出しています。
  受信した文字列に対応した文字列を返信しています。 返信対応の文字列がない場合は "Pardon"を返信しています。
  void SendData(void)
  {
    buf[ix] = data;

    if(buf[ix] == '\r') // Enter キーが押された場合
    {
      buf[ix] = '\0';

      if(strcmp(buf,Japan) == 0)str = Tokyo;
      else if(strcmp(buf,America) == 0) str = Washinton;
      else if(strcmp(buf,UK) == 0) str = London;
      else if(strcmp(buf,France) == 0) str = Paris;
      else str = Pardon;

      ix = 0;
      sprintf(Buf,"%s\n",str);
      WriteString(Buf); //文字列送信

      lcd_cmd(0x80); //1目の先頭へ
      sprintf(Buf,"%s ",buf);
      lcd_str(Buf); //液晶表示

      lcd_cmd(0xC0); //2行目の先頭へ
      sprintf(Buf,"%s ",str);
      lcd_str(Buf); // 開始メッセージ1行目表示
    }
    else //Enter キー以外が押された場合
    {
      ix++;
    }


  ⑥キャラクタ液晶を初期化して、"PIC32MZ_PC"、" Strings by UART "を表示しています。
  lcd_init(); // LCD初期化
  lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF

  lcd_clear();  

  delay_ms(1000);

  lcd_cmd(0x80); //1目の先頭へ

  sprintf(Buf,"PIC32MZ_PC ");//

  ……
  ……


  ⑦ 文字列 "Hellow World !!" を送信して、"\r" で Carriage Return (復帰)して "\n" で Line Feed (改行)します。
    //文字列送信
    WriteString("Hellow World !!\r\n");



以下、app.c





■ system_interrupt.cに青字部を追加します。

➀ 所要の変数を定義します。
  char data;

➁ U6_RXに割り込みが発生した場合 U6のバッファレジスタU6RXREGの値を取り込み関数SendData()を呼び出します。
  if (PLIB_USART_ReceiverDataIsAvailable(USART_ID_6)) //受信データ有の場合
  //if(U6STAbits.URXDA == 1) //受信データ有の場合 //Receive buffer has data, at least one more character can be read
  {
    data = PLIB_USART_ReceiverByteReceive(USART_ID_6); //受信データ読み込み
    //data = U6RXREG; //受信バッファ読み込み

    SendData();

  }
  
  /* Clear pending interrupt */
  PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_USART_6_RECEIVE);
  //IFS5bits.U6RXIF = 0; //RX割込みフラグクリア


以下、system_interrupt.c