戻る

Serial通信 USB & GPIO                2012.9.11

PICマイコン等とのI/Fです。PCのUSBともOKです。


raspberry pi側送受信


ttyUSB0のプログラミング

# ls/dev では
  ・serial-USB変換ケーブルをUSBに接続すると「ttyUSB0」が増えて、
   USBメモリーを接続すると「usbdev1.5」が増える
  ・serial-USB変換ケーブルをもう1つUSBに接続すると「ttyUSB1」が増える

# ls -l \dev | grep ttyUSB
ttyUSB0
ttyUSB1

と表示する

ttyUSB0とttyUSB1の見分けは
# ls /dev/serial/by-id
usb-FTDI_FT232R_USB_UART_A400gBYg-if00-port0
usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0
# ls /dev/serial/by-path
platform-bcm2708_usb-usb0:1.2:1.0-port0
platform-bcm2708_usb-usb-0:1.3:1.0-port0

-----------------------------------------------------------
以下の変更のみでUSBorGPIOの切り替えをする

#define DEV_NAME "/dev/ttyAMA0" // デバイスファイル名
//#define DEV_NAME "/dev/ttyUSB0" // デバイスファイル名


GPIOでのserial接続では、
8ビット双方向ロジックレベル変換モジュールIC“FXMA108”を通して
3.3v<-->5v変換を行った。


-----------------------------------------------------------
ソースファイル  ttyUSB0.c
# gcc -o ttyAMA0 ttyUSB0.c

//-----------------------------------------------------------
//-----------------------------------------------------------
//-----------------------------------------------------------

/*
 * ttyUSB0 & ttyAMA0 シリアルポート送受信テストプログラム
 *
 *                              2012/9/11 shell-valley
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <time.h>

//#define DEV_NAME    "/dev/ttyAMA0"        // デバイスファイル名
#define DEV_NAME    "/dev/ttyUSB0"        // デバイスファイル名
#define BAUD_RATE    B9600                // RS232C通信ボーレート
#define BUFF_SIZE    4096                 // 適当

// シリアルポートの初期化
void serial_init(int fd)
{
    struct termios tio;
    memset(&tio,0,sizeof(tio));
    tio.c_cflag = CS8 | CLOCAL | CREAD;
    tio.c_cc[VTIME] = 100;
    // ボーレートの設定
    cfsetispeed(&tio,BAUD_RATE);
    cfsetospeed(&tio,BAUD_RATE);
    // デバイスに設定を行う
    tcsetattr(fd,TCSANOW,&tio);
}
/* --------------------------------------------------------------------- */
/* メイン                                                                */
/* --------------------------------------------------------------------- */
int main(int argc,char *argv[]){
    int fd;
    int i,j;
    int len;                                                               // データ数(バイト)
    unsigned char buffer[BUFF_SIZE],in_data[BUFF_SIZE];    // データバッファ
    fd = open(DEV_NAME,O_RDWR);         // デバイスファイル(シリアルポート)オープン
    if(fd<0){                                   // デバイスの open() に失敗したら
        perror(argv[1]);
         exit(1);
    }
    serial_init(fd);                                    // シリアルポートの初期化
        j = 0;
    // メインの無限ループ
    while(1){
        len=read(fd,buffer,BUFF_SIZE);  // 受信待ち
        if(len==0){
            continue;
        }
                                                                                // read()が0を返したら、end of file
                                                                                // 通常は正常終了するのだが今回は無限ループ
        if(len < 0){                                    // read()が負を返したら何らかのI/Oエラー
            printf("%s: ERROR\n",argv[0]);
            perror("");
            exit(2);
        }
        // read()が正を返したら受信データ数
                for(i=0; i<len; i++){
                        printf("%02X ",buffer[i]);      // 受信したデータを 16進数形式で表示
                        in_data[j++] = buffer[i];
                }
                if((in_data[j - 1] == 0x0a) || (in_data[j - 1] == 0)){
                        in_data[j - 1] = 0x0a;
                        in_data[j] = 0;
                        printf("\n read-data=%s\n",&in_data[0]);
                write(fd,&in_data[0],strlen(&in_data[0]));
                        j = 0;
                }
    }
}


トップに戻る

TEST用 PIC-16F877A プログラム

//-----------------------------------------------------------
//-----------------------------------------------------------
//-----------------------------------------------------------

//*****************************************************************************
//*   自作汎用ボードでの動作確認済み                                          *
//*                                                                           *
//*    while(1)ループで送信し、232c割り込みで受信                             *
//*                                                                           *
//*                                                                           *
//*    v1.0                            2012.09.11   Galley-Shell-Valley       *
//*                                                                           *
//*****************************************************************************

#define USART                                           // USART(RS232C/USB)接続で定義
#define LCD

#include    <16F877A.h>
#include    <stdlib.h>
//#use fast_io(A)            // #use fast_io(Port) Port as A-G
#use fast_io(B)
#use fast_io(C)
#FUSES HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(CLOCK = 20000000)
#define LED_0           PIN_C0                  // LED用
#define LED_1           PIN_C1                  // LED用
#define LED_2           PIN_C2                  // LED用
#define LED_3           PIN_C3                  // LED用

//  液晶表示ライブラリのインクルード
#include    <lcd_lib.c>

#ifdef USART    // *************************************
#use rs232(BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7)

#endif                  // *************************************

static int rda_t = 0;
static int flg = 0;
static char rda_buffer[40];                                     //受信バッファstatic
static int1 Tm1_Int_Sign;                                       // timer1 オーバーフローサイン

#ifdef USART    // *************************************
//============================================================================
//====================LCD=>stdout変換関連function=============================
void DISP_DATA(int asci){putc(asci);}           // LCDでは1文字表示関数
#endif                  // *************************************

#ifdef USART    // *************************************
//============================================================================
//====================USART受信割込処理==(未使用である)======================
#int_rda
void isr_rcv(){
        char data;
        output_high(LED_0);                                                     // LED
        data = getc();                                                          //受信データ取り出し
        if ((data == 0x0a) || (data) == 0x0d || (data == 0)){
                rda_buffer[rda_t] = 0;                                  //文字列END
                lcd_cmd(0x80);                                                  // 1段目表示
                printf(lcd_data,"<%s>",rda_buffer);             //
                rda_t = 0;                                                              //格納インデックス再初期化
        }
        else{
                rda_buffer[rda_t] = data;                               //バッファへ格納
                rda_t++;                                                                //インデックス+1
                if ( rda_t > 38)rda_t = 0;                              //上限チェック
        }
        output_low(LED_0);                                                      // LED
}
#endif                  // *************************************

//====================タイマー1割込処理 =====================================
#int_timer1
void t1_intval(){
        set_timer1(0);                                          // timer1をpreset 0〜0xffff=約160ms
        Tm1_Int_Sign = 1;
}
//============================================================================
void main() {
unsigned int i;

        set_tris_b(0x00);                                       // output
        set_tris_c(0x80);                                       // RC7:input
//      output_B(0);                                                    //全ピンLow
        output_C(0);                                                    //全ピンLow
#ifdef LCD
        lcd_init();                                                             //LCD初期化
        lcd_clear();                                                    //LCD全消去
        printf(lcd_data,"Start!!");                             //初期メッセージ
        delay_ms(500);

        lcd_clear();
        lcd_cmd(0x80);                                                                  // 1段目表示
        printf(lcd_data,"upper");
        lcd_cmd(0x80 | 0x40);                                                   // 2段目表示
        printf(lcd_data,"lower");
        delay_ms(500);
#endif
        output_high(LED_0);                     // LED
        delay_ms(400);
//      output_high(LED_1);                     // LED
//      delay_ms(400);
//      output_high(LED_2);                     // LED
//      delay_ms(400);
//      output_high(LED_3);                     // LED
//      delay_ms(400);

        output_low(LED_0);
        delay_ms(400);
//      output_low(LED_1);
//      delay_ms(400);
//      output_low(LED_2);
//      delay_ms(400);
//      output_low(LED_3);
//      delay_ms(400);
//      lcd_clear();                                                    //LCD全消去

        setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);       // プリスケーラ2
        set_timer1(0);                                          // timer1は「0」からスタートする
        Tm1_Int_Sign = 0;                                       // timer1がoverflowで「1」にする
        enable_interrupts(int_timer1);          // timer1 割り込み許可
        enable_interrupts(int_rda);                     // USART 割り込み許可
        enable_interrupts(GLOBAL);                      // 割込処理全体の許可
        i = 0;
    while(1){
                lcd_cmd(0x80 | 0x40);                                                   // 2段目表示
                printf(lcd_data,"[%d]",i);
                printf(DISP_DATA,"%d\n",i);             // ターゲットの送信
                delay_ms(1000);
                ++i;
        }
}


トップに戻る