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; } }