Linux下串口协议控制51单片机

  • 格式:doc
  • 大小:55.00 KB
  • 文档页数:12

linux下串口协议控制51单片机(涉及多线程操作)

/***************************************************************************

writen by jingshui 7-17 2011 12:53

说明:这是一个linux下串口,多线程测试程序

Version 0.26

***************************************************************************/

# include

# include

# include

# include

# include

# include

# include

# include

# include

int fd;

pthread_t thread[2];

pthread_mutex_t mutex;

/****************************************************************************

结构体说明:传送控制单片机的信息

成员1:select 选择功能模块

成员2:control 控制单片机相应的动作

*****************************************************************************/

struct protocal

{

unsigned char select;

unsigned char control;

};

struct protocal ptr[14]={{0xa1,0x01},{0xa1,0x02},{0xa1,0x03},{0xa1,0x04},{0xa1,0x05},

{0xa1,0x06},{0xa1,0x07},{0xa1,0x08},{0xb2,0x00},{0xb2,0x03},

{0xb2,0x06},{0xb2,0x09},{0xb2,0x0e},{0xc3,0xd4}};

/********************************************************************

功能说明:设置linux串口参数

传入参数:

fd nspeed nbit nevent nstop

文件句柄 波特率 数据位 奇偶校验 停止位

返回值: fd 文件句柄

********************************************************************/

int set_port(int fd ,int nspeed ,int nbits ,char nevent ,int nstop) {

struct termios newtio,oldtio;

if (tcgetattr(fd,&oldtio)!= 0)

{

perror("setup serial");

return -1;

}

bzero(&newtio,sizeof(newtio));

newtio.c_cflag |= CLOCAL|CREAD;

newtio.c_cflag &= ~CSIZE;

switch (nbits)

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

switch (nevent)

{

case 'N':

newtio.c_cflag &= ~PARENB;

break;

}

switch (nspeed)

{

case 9600:

cfsetispeed(&newtio,B9600);

cfsetospeed(&newtio,B9600);

break;

}

switch (nstop)

{

case 1:

newtio.c_cflag &= ~CSTOPB;

break;

case 2:

newtio.c_cflag |= CSTOPB;

break;

}

newtio.c_cc[VTIME]= 0;

newtio.c_cc[VMIN]= 14;

tcflush(fd,TCIFLUSH); if ((tcsetattr(fd,TCSANOW,&newtio))!= 0)

{

perror("com set");

return -1;

}

return 0;

}

int open_port(int fd,int comport)

{

if (comport == 1){

fd = open ("/dev/ttyUSB0",O_RDWR);

if ( -1 == fd ){

perror("can't open serial port");

return -1;

}

}

return fd;

}

void write_port(void)

{

int nwrite,i;

for (i=0;i<14;i++)

{

nwrite = write(fd,&ptr[i],2);

usleep(200000);/*每200ms秒发一次数据*/

}

}

void read_port(void)

{

fd_set rd;

int nread,retval;

unsigned char msg[14];

struct timeval timeout;

FD_ZERO(&rd);

FD_SET(fd,&rd);

_sec = 1;

_usec = 0;

retval = select (fd+1,&rd,NULL,NULL,&timeout);/*select 实现i/o复用*/

switch (retval)

{

case 0: printf("no data input within 1 seconds.\n");

break;

case -1:

perror("select");

break;

default:

if((nread=read(fd,msg,14))>0)

{

printf("nread=%d,msg=%s\n",nread,msg);

}

break;

}

}

void *recv_thread(void )

{

pthread_mutex_lock(&mutex);

read_port();

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

}

void *send_thread(void )

{

pthread_mutex_lock(&mutex);

write_port();

pthread_mutex_unlock(&mutex);

pthread_exit(NULL);

}

void create_thread(void )

{

int temp;

memset(thread, 0, sizeof(thread));

if((temp = pthread_create(&thread[0], NULL,(void *)send_thread, NULL)) != 0)

printf("create send_thread failed!\n");

if((temp = pthread_create(&thread[1], NULL,(void *)recv_thread, NULL)) != 0)

printf("create recev_thread failed!\n");

}

void wait_thread(void )

{

if(thread[0] !=0) {

pthread_join(thread[0],NULL);

printf("send_thread end\n");

}

if(thread[1] !=0)

{

pthread_join(thread[1],NULL);

printf("recev_thread end\n");

}

}

int main(void )

{

int i;

if((fd=open_port(fd,1))<0){

perror("open_port error");

}

if((i=set_port(fd,9600,8,'N',1))<0){

perror("set_opt error");

}

/*用默认属性初始化互斥锁*/

pthread_mutex_init(&mutex,NULL);

int num = 100;

while (num)

{

create_thread();

wait_thread();

num--;

}

pthread_mutex_destroy(&mutex);