ベリーパイc言語シリアル通信プログラム

7701 ワード

ネットではベリーパイのシリアル通信の例をたくさん探しましたが、pythonで書かれていて、pythonは有名ですが、最近もこの言語を勉強しています.
しかし、やはりc言語で実現したいです.システム全体に使う必要があるので、他の内容はc言語で書かれています.しかし、ネット上では既成品を探していません.
幸いなことに、以前天嵌2440開発ボードのシリアルポートプログラム(天嵌エンジニアが提供したコードを参照)をしたことがありますが、シリアルポートプログラムは実際には共通していることがわかりました.
駆動層はハードウェアの詳細を遮断し、個人的な推測では、ほとんどの移植されたシステムのシリアルポートは、少なくとも2440とベリーパイが共通している同じコードで操作することができる.
共有コードは次のとおりです.
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include"pthread.h"
#include "serial.h"


struct serial_config serialread;

static int serial_fd;

int speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,
		   B38400, B19200, B9600, B4800, B2400, B1200, B300};

int name_arr[] = {230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,
		  38400, 19200, 9600, 4800, 2400, 1200, 300};

//-----------------------------------------------
//      serial.cfg   
//-----------------------------------------------
void print_serialread()
{
	printf("serialread.dev is %s
",serialread.serial_dev); printf("serialread.speed is %d
",serialread.serial_speed); printf("serialread.databits is %d
",serialread.databits); printf("serialread.stopbits is %d
",serialread.stopbits); printf("serialread.parity is %c
",serialread.parity); } //----------------------------------------------- // serial.cfg //----------------------------------------------- void readserialcfg() { FILE *serial_fp; char j[10]; printf("readserailcfg
"); serial_fp = fopen("./serial.cfg","r"); if(NULL == serial_fp) { printf("can't open serial.cfg"); } else { fscanf(serial_fp, "DEV=%s
", serialread.serial_dev); fscanf(serial_fp, "SPEED=%s
", j); serialread.serial_speed = atoi(j); fscanf(serial_fp, "DATABITS=%s
", j); serialread.databits = atoi(j); fscanf(serial_fp, "STOPBITS=%s
", j); serialread.stopbits = atoi(j); fscanf(serial_fp, "PARITY=%s
", j); serialread.parity = j[0]; } fclose(serial_fp); } //----------------------------------------------- // //----------------------------------------------- void set_speed(int fd) { int i; int status; struct termios Opt; struct termios oldOpt; tcgetattr(fd, &oldOpt); // printf("serialread.speed is %d
",serialread.serial_speed); for( i = 0; i < sizeof(speed_arr)/sizeof(int); i++) { if(serialread.serial_speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if(status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd, TCIOFLUSH); } } } //----------------------------------------------- // //----------------------------------------------- int (int fd) { struct termios options; struct termios oldoptions; if(tcgetattr(fd, &oldoptions) != 0) { perror("SetupSerial 1"); return(FALSE); } options.c_cflag |= (CLOCAL|CREAD); options.c_cflag &=~CSIZE; // printf("serialread.databits is %d
",serialread.databits); switch(serialread.databits) { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: options.c_cflag |= CS8; fprintf(stderr, "Unsupported data size
"); return(FALSE); } // printf("serialread.parity is %c
",serialread.parity); switch(serialread.parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); options.c_iflag |= INPCK; break; case 'e': case 'E': options.c_cflag |= PARENB; options.c_cflag &= ~PARODD; options.c_iflag |= INPCK; break; default: options.c_cflag &= ~PARENB; options.c_iflag &= ~INPCK; fprintf(stderr, "Unsupported parity
"); return(FALSE); } // printf("serialread.stopbits is %d
",serialread.stopbits); switch(serialread.stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: options.c_cflag &= ~CSTOPB; fprintf(stderr, "Unsupported stop bits
"); return(FALSE); } if(serialread.parity != 'n') options.c_iflag |= INPCK; options.c_cc[VTIME] = 0; //150; //15 seconds options.c_cc[VMIN] = 0; #if 1 options.c_iflag |= IGNPAR|ICRNL; options.c_oflag |= OPOST; options.c_iflag &= ~(IXON|IXOFF|IXANY); #endif tcflush(fd, TCIFLUSH); if(tcsetattr(fd, TCSANOW, &options) != 0) { perror("SetupSerial 3"); return(FALSE); } return(TRUE); } //----------------------------------------------- // //----------------------------------------------- int OpenDev(char *Dev) { int fd = open(Dev, O_RDWR, 0); if(-1 == fd) { perror("Can't Open Serial Port"); return -1; } else return fd; } //-------------------------------------------------- // //-------------------------------------------------- void serial_init() { char *Dev; int i; readserialcfg(); //print_serialread(); printf("init serial
"); Dev = serialread.serial_dev; // serial_fd = OpenDev(Dev); if(serial_fd > 0) set_speed(serial_fd); // else { printf("Can't Open Serial Port!
"); exit(0); } // if (fcntl(serial_fd, F_SETFL, O_NONBLOCK) < 0) { printf("fcntl failed!
"); exit(0); } // #if 0 // , , 。 if(isatty(STDIN_FILENO)==0) { printf("standard input is not a terminal device
"); } else printf("isatty success!
"); #endif // if(set_Parity(serial_fd) == FALSE) { printf("Set parity Error
"); exit(1); } } int serial_write(char* cmd, int count) { printf("serial write for %d bytes
",count); return write(serial_fd,cmd,count); } void serial_close() { printf("close serial
"); close(serial_fd); } /* void serial_rw() { int i; char buff[512]; int nread,nwrite; char buff2[] = "hello!
"; nwrite = write(serial_fd,buff2,sizeof(buff2)); printf("nwrite=%d
",nwrite); while(1) { if((nread = read(serial_fd,buff,512))>0) { buff[nread] = '\0'; #if 1 // , , 。 write(serial_fd,buff,nread); #endif printf("recv:%d
",nread); #if 1 for(i=0;i

もちろん、対応するヘッダファイルも必要です.
#define FALSE		0
#define TRUE		1

#define WORDLEN 32

struct serial_config
{
	unsigned char serial_dev[WORDLEN];
	unsigned int serial_speed;
	unsigned char databits;
	unsigned char stopbits;
	unsigned char parity;
};

void serial_init();
int serial_write(char* cmd, int count);
void serial_close();

分離されたプロファイル:
DEV=/dev/ttyAMA0
SPEED=9600
DATABITS=8
STOPBITS=1
PARITY=N

cファイルを見ると、main関数が注釈されていることがわかります.コンパイルされたシステム全体なので、このファイルはインタフェースしか提供していないので、main関数はありません.必要であれば、注釈を削除することができます.
内容がざらざらしているので,再修繕の時間がある