- 論壇徽章:
- 0
|
//stty.c
#include <stdio.h>
#include<string.h>
#include <sys/ioctl.h>
#include "stty.h"
///////////////////////////////////////////////////////////////////////////////
//初始化串口設(shè)備并進(jìn)行原有設(shè)置的保存
TTY_INFO *readyTTY(int id)
{
TTY_INFO *ptty;
ptty = (TTY_INFO *)malloc(sizeof(TTY_INFO));
if(ptty == NULL)
return NULL;
memset(ptty,0,sizeof(TTY_INFO));
pthread_mutex_init(&ptty->mt,NULL);
sprintf(ptty->name,"/dev/ttyS%d",id);
//
// 打開并且設(shè)置串口
ptty->fd = open(ptty->name, O_RDWR | O_NOCTTY |O_NDELAY);
if (ptty->fd <0)
{
free(ptty);
return NULL;
}
//
// 取得并且保存原來的設(shè)置
tcgetattr(ptty->fd,&ptty->otm);
return ptty;
}
///////////////////////////////////////////////////////////////////////////////
// 清理串口設(shè)備資源
int cleanTTY(TTY_INFO *ptty)
{
//
// 關(guān)閉打開的串口設(shè)備
if(ptty->fd>0)
{
tcsetattr(ptty->fd,TCSANOW,&ptty->otm);
close(ptty->fd);
ptty->fd = -1;
free(ptty);
ptty = NULL;
}
return 0;
}
// 設(shè)置串口通信速率
// ptty 參數(shù)類型(TTY_INFO *),已經(jīng)初始化的串口設(shè)備信息結(jié)構(gòu)指針
// speed 參數(shù)類型(int),用來設(shè)置串口的波特率
// return 返回值類型(int),函數(shù)執(zhí)行成功返回零值,否則返回大于零的值
int setTTYSpeed(TTY_INFO *ptty, int speed)
{
int i;
//
// 進(jìn)行新的串口設(shè)置,數(shù)據(jù)位為8位
bzero(&ptty->ntm, sizeof(ptty->ntm));
tcgetattr(ptty->fd,&ptty->ntm);
ptty->ntm.c_cflag = /*CS8 |*/ CLOCAL | CREAD;
switch(speed)
{
case 300:
ptty->ntm.c_cflag |= B300;
break;
case 1200:
ptty->ntm.c_cflag |= B1200;
break;
case 2400:
ptty->ntm.c_cflag |= B2400;
break;
case 4800:
ptty->ntm.c_cflag |= B4800;
break;
case 9600:
ptty->ntm.c_cflag |= B9600;
break;
case 19200:
ptty->ntm.c_cflag |= B19200;
break;
case 38400:
ptty->ntm.c_cflag |= B38400;
break;
case 115200:
ptty->ntm.c_cflag |= B115200;
break;
}
ptty->ntm.c_iflag = IGNPAR;
ptty->ntm.c_oflag = 0;
//
//
tcflush(ptty->fd, TCIFLUSH);
tcsetattr(ptty->fd,TCSANOW,&ptty->ntm);
//
//
return 0;
}
// 設(shè)置串口數(shù)據(jù)位,停止位和效驗(yàn)位
// ptty 參數(shù)類型(TTY_INFO *),已經(jīng)初始化的串口設(shè)備信息結(jié)構(gòu)指針
// databits 參數(shù)類型(int), 數(shù)據(jù)位,取值為7或者8
// stopbits 參數(shù)類型(int),停止位,取值為1或者2
// parity 參數(shù)類型(int),效驗(yàn)類型 取值為N,E,O,,S
// return 返回值類型(int),函數(shù)執(zhí)行成功返回零值,否則返回大于零的值
int setTTYParity(TTY_INFO *ptty,int databits,char parity,int stopbits)
{
//
// 取得串口設(shè)置
if( tcgetattr(ptty->fd,&ptty->ntm) != 0)
{
printf("SetupSerial [%s]\n",ptty->name);
return 1;
}
bzero(&ptty->ntm, sizeof(ptty->ntm));
ptty->ntm.c_cflag = CS8 | CLOCAL | CREAD;
ptty->ntm.c_iflag = IGNPAR;
ptty->ntm.c_oflag = 0;
//
// 設(shè)置串口的各種參數(shù)
ptty->ntm.c_cflag &= ~CSIZE;
switch (databits)
{ // 設(shè)置數(shù)據(jù)位
case 7:
ptty->ntm.c_cflag |= CS7;
break;
case 8:
ptty->ntm.c_cflag |= CS8;
break;
default:
printf("Unsupported data size\n");
return 5;
}
//
switch (parity)
{ // 設(shè)置奇偶校驗(yàn)位數(shù)
case 'n':
case 'N': //無校驗(yàn)
ptty->ntm.c_cflag &= ~PARENB; /* Clear parity enable */
ptty->ntm.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O': //奇校驗(yàn)
ptty->ntm.c_cflag |= (PARODD|PARENB);
ptty->ntm.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E': //偶校驗(yàn)
ptty->ntm.c_cflag |= PARENB; /* Enable parity */
ptty->ntm.c_cflag &= ~PARODD;
ptty->ntm.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 's':
case 'S': /*as no parity*/
ptty->ntm.c_cflag &= ~PARENB;
ptty->ntm.c_cflag &= ~CSTOPB;
break;
default:
printf("Unsupported parity\n");
return 2;
}
// 設(shè)置停止位
switch (stopbits)
{
case 1:
ptty->ntm.c_cflag &= ~CSTOPB;
break;
case 2:
ptty->ntm.c_cflag |= CSTOPB;
break;
default:
printf("Unsupported stop bits\n");
return 3;
}
ptty->ntm.c_lflag = 0;
ptty->ntm.c_cc[VTIME] = 0; // inter-character timer unused
ptty->ntm.c_cc[VMIN] = 1; // blocking read until 1 chars received
tcflush(ptty->fd, TCIFLUSH);
if (tcsetattr(ptty->fd,TCSANOW,&ptty->ntm) != 0)
{
printf("SetupSerial \n");
return 4;
}
return 0;
}
int recvnTTY(TTY_INFO *ptty,char *pbuf,int size)
{
int ret,left,bytes;
left = size;
#if 1
pthread_mutex_lock(&ptty->mt);
ioctl(ptty->fd, FIOASYNC,0);
//printf("bytes:%d\n",bytes);
// if(bytes>0)
{
ret = read(ptty->fd,pbuf,left);
}
pthread_mutex_unlock(&ptty->mt);
#endif
#if 0
while(left>0)
{
ret = 0;
bytes = 0;
pthread_mutex_lock(&ptty->mt);
ioctl(ptty->fd, FIONREAD, &bytes);
if(bytes>0)
{
ret = read(ptty->fd,pbuf,left);
}
pthread_mutex_unlock(&ptty->mt);
if(ret >0)
{
left -= ret;
pbuf += ret;
}
usleep(100);
}
#endif
return ret;
}
int sendnTTY(TTY_INFO *ptty,char *pbuf,int size)
{
int ret,nleft;
char *ptmp;
ret = 0;
nleft = size;
ptmp = pbuf;
pthread_mutex_lock(&ptty->mt);
ret = write(ptty->fd,ptmp,nleft);
write(ptty->fd,"\n",2);
pthread_mutex_unlock(&ptty->mt);
#if 0
while(nleft>0)
{
pthread_mutex_lock(&ptty->mt);
ret = write(ptty->fd,ptmp,nleft);
pthread_mutex_unlock(&ptty->mt);
if(ret >0)
{
nleft -= ret;
ptmp += ret;
}
//usleep(100);
}
#endif
return ret;
}
int lockTTY(TTY_INFO *ptty)
{
if(ptty->fd < 0)
{
return 1;
}
return flock(ptty->fd,LOCK_EX);
}
int unlockTTY(TTY_INFO *ptty)
{
if(ptty->fd < 0)
{
return 1;
}
return flock(ptty->fd,LOCK_UN);
}
// 接口測(cè)試
int main(int argc,char **argv)
{
TTY_INFO *ptty;
int nbyte,idx;
char buff[]="Hello\n";
char buffer1[80];
int j=10;
int nread;
ptty = readyTTY(0);
if(ptty == NULL)
{
printf("readyTTY(0) error\n");
return 1;
}
//
lockTTY(ptty);
if(setTTYSpeed(ptty,9600)>0)
{
printf("setTTYSpeed() error\n");
return -1;
}
if(setTTYParity(ptty,8,'N',1)>0)
{
printf("setTTYParity() error\n");
return -1;
}
//
// char *pack="0x55 0x03 0x80 0x2001 0x00 0x7d 0xaa ";
char pack_serial[]= {0x55,0x55,0x80,0x01,0x40,0x01,0x00,0x00,0xaa,0xaa};
int bb=0x55^0x80^0x03^0x20^0x02^0x00^0xaa;
printf(" pack = 0x%x 0x%x \n",pack_serial[0],bb);
idx = 0;
// while(j)
{
nread = sendnTTY(ptty,pack_serial,10);
printf("write=%d\n",nread);
sleep(3);
memset(buffer1,0,80);
nbyte = recvnTTY(ptty,buffer1,80);
sleep(2);
printf("nread=%d\n",nread);
#if 1
for(j = 0; j < nread;j++)
printf("0x%02x\t",(unsigned char)buffer1[j]);
printf("\n");
j--;
#endif
}
cleanTTY(ptty);
return 0;
向單片機(jī)發(fā)送10個(gè)字節(jié)數(shù)據(jù),單片機(jī)返回80個(gè)字節(jié)數(shù)據(jù),但是接收到的只有10個(gè)字節(jié)數(shù)據(jù),而且都是0,這是為什么呢 |
|