PIC(6)-UARTとRS232C通信

このエントリーをはてなブックマークに追加

本日は、PICを使用した通信機能です。

PIC側はUARTという通信を使用します。
UARTは、Universal Asynchronous Receiver Transmittionの略で、いわゆる汎用のシリアル通信の機能をもった周辺回路モジュールです。
名前の通り、全二重の非同期式通信であり、調歩同期式通信とも呼ばれます。

PC側(外部機器側)はRS232C通信を使用します。
ちなみに、RS232Cは、OSI参照モデルの物理層に位置づけされます。
ネットワークの物理的な接続・伝送方式を定めたものです。

ここで気になるのは、PIC側とPC側で通信方式が違うということです。
ということは、中間に変換するデバイスが必要となります。
中間デバイスとしては、MAX232やFT232などがあります。
今回使用するボードには、FT232が使用されていました。

下記のコードは、RS232C通信規格で、UARTを使用した通信機能のコードになります。
クライアント側から文字列を送信すると、PIC側から同じ文字列を返信する機能になります。


#include <xc.h>

#include <stdio.h>
#include <stdlib.h>

// CONFIG1L
#pragma config WDT = ON
#pragma config STVR = ON
#pragma config XINST = OFF

// CONFIG1H
#pragma config CP0 = ON

// CONFIG2L
#pragma config FOSC = HS
#pragma config FOSC2 = ON
#pragma config FCMEN = ON
#pragma config IESO = ON 

// CONFIG2H
#pragma config WDTPS = 32768

// CONFIG3L
#pragma config EASHFT = ON
#pragma config MODE = MM
#pragma config BW = 16
#pragma config WAIT = OFF

// CONFIG3H
#pragma config CCP2MX = ON
#pragma config ECCPMX = ON
#pragma config ETHLED = ON

#define _XTAL_FREQ 25000000

char buffer[40];

//受信割込み処理
static void interrupt isr( void )
{
    static int i;
    static int j;
    static char data;
    
    // 割込みはUSART通信の受信可能であるか
     if (RC1IF == 1) {
         
         data = RCREG;
         if(data == 0x0a || data == 0x0d){
             if(i >= 1){
                 buffer[i] = data;
                 for(j = 0; j <= i; j++){
                    if (TX1IF == 1)
                    {
                        TXREG = buffer[j];
                        while(TX1IF == 0){ }
                        __delay_ms(10) ;
                    }
                 }
             }
             i = 0;
         }else{
             buffer[i] = data;
             i++;
             if(i == 40){
                 i = 0;
             }
         }
     }
}

//main処理
void main(void) {

    //ポート設定
    TRISC7 = 1;
    TRISC6 = 1;

    T0CS = 0;
    
    // 通信設定
    BRGH1 = 1;
    TXEN1 = 1;
    SYNC1 = 0;

    CREN1 = 1;
    SPEN1 = 1;

    BRG161 = 0;
    ABDEN1 = 0;
    
    SPBRG1  = 162 ;
    
    // 割り込み設定
    RC1IP = 1;

    RC1IE = 1;
    IPEN = 1;
    GIE = 1;
  
    //メインループ
    while(1){ }
}

それでは、プログラムのソースコードについて解説していきます。

関数は2つになります。
main関数と、受信割り込み関数です。

mainのモジュールで、ポートの設定、通信の設定、割り込みの設定をして、後は、while文でループしています。
while文でループしている間に、PC側から文字列が送信してくると、受信割り込みが発生して、割り込み関数へ処理が移行します。

割り込み関数では、送信されてきた文字の処理を行っています。
改行コードか復帰コード以外の文字列が送信されてくると、配列の中に文字列を保存します。
改行コードか復帰コードが送られてくると、配列に保存されている文字列をPC側に送信します。
ただし、40文字PC側から文字列が送信されると、配列に保存されている文字列はクリアされてしまいます。

今回、PC側にTeraTermというフリーソフトウェアを使用して、文字列を送信、受信して、動作を確認しました。