『高分』如何实现串口发送数据同时处理接收数据(C/C++)

zl198183 2008-01-31 10:09:51
现已完成串口的单工的发送和读取,源代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/io.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <termios.h>
#include <sys/time.h>
#include <errno.h>



unsigned char ch_read(int fd);
int asy_open(char *Port, int Baud);

#define DataTimeout 0
#define UART_DEBUG

/* Main program */

static void useage()
{
printf("uart test for 2410--------------------\n");
printf("brate:115200\n");
printf("example:\n");
printf("uart3 send--------: #uarttest -3 -s \n");
printf("uart3 receive------: #uarttest -3 -r \n");
}







int main(int argc, char **argv)
{
int fd;
char portname[15];
int e;
unsigned char ch;
char buf[20] = "hello world!\n";
char rvbuf[100];
char rv_Pos;
int ret;
int i,n,recvbytes,flag;

struct timeval timeout;

timeout.tv_sec = 0;
timeout.tv_usec = 0;

if(argc!=3)
{
useage();
return -1;
}
sprintf(portname,"/dev/ttyS%d",argv[1][1]-49);
fd = asy_open(portname,B115200);
if(argv[2][1]=='s')
{
while(1)
{
write(fd,buf,strlen(buf));
sleep(1);
}
return 0;
}
printf("read-------------\n");
rv_Pos=0;
/*
while(1){
FD_ZERO (&rset);
if (fd >= 0)FD_SET (fd, &rset);

e = select (fd + 1, &rset, NULL, NULL, &timeout);

if (e > 0){
if (fd >= 0 && FD_ISSET (fd, &rset)){
FD_CLR(fd, &rset);
//ret = ch_read(fd);
read(fd,&ch,1);
//if(ret > 0)
printf("ch = %x\n",ch);
}
}
}
*/
memset(rvbuf,0,100);
while(1)
{
//n=read(fd,&ch,1);
recvbytes=0;
ioctl(fd, FIONREAD, &recvbytes);
//if there are some chars in the input buffer, then receive them.
if(recvbytes>0)
{
flag=1;
while(1)
{
n=read(fd,&ch,1);
if(n<0)
{
//printf("Serial COM receiving data error!\n");
if(errno==EAGAIN)//Resource temporarily unavailable
break;//break from the while loop
else
perror("read com error");
}
else if(n>0)
{

if((rv_Pos+1)>100)
{
printf("1The input buffer is overflowed!\n");
rvbuf[rv_Pos]='\0';
printf(rvbuf);
printf("\n");
rv_Pos=0;
}
else
{
rvbuf[rv_Pos]=ch;
rv_Pos++;
}
}
else
{
//rvbuf[rv_Pos]='\0';
//printf(rvbuf);
//printf("\n");
//rv_Pos=0;
break;
}
}
}
if((recvbytes==0)&&(flag==1))
{
rvbuf[rv_Pos]='\0';
flag=0;
printf(rvbuf);
printf("\n");
rv_Pos=0;
}
}
return 0;
}




/* Char processing */
/*
unsigned char ch_read(int fd)
{
unsigned char ch,temp1,buf[10] = {0};
int ret,i;

ret = read(fd,&ch,1);
if(!ret || ch != 0x55)return 0;
fprintf(stderr,"ch = %x\n",ch);

ret = read(fd,&ch,1);
if(!ret || ch != 0x55)return 0;
fprintf(stderr,"ch = %x\n",ch);

ret = read(fd,&ch,1);
if(!ret)return 0;
fprintf(stderr,"ch = %x\n",ch);

temp1 = ch;
ret = read(fd,&ch,1);
if(!ret)return 0;
fprintf(stderr,"ch = %x\n",ch);
if((temp1 + ch) != 0xff)return 0;

// if((ch == 0x22) || (ch == 0x13) || (ch == 0x43) || (ch == 0x23))
return temp1;


}*/


/* Uart open fuction */

int asy_open(char *Port, int Baud)
{
struct termio SerialParameters;
int i, fd;

//We want to open the port in nodelay mode, so we are informed if the
// port cannot be opened.
if ((fd = open (Port, O_RDWR | O_NDELAY)) == -1) {
#ifdef UART_DEBUG
fprintf (stderr, "asy_open: Cannot open port %s\n", Port);
#endif
return -1;
}

// Now change the rest of the parameters - non-canonical input, etc.
if (ioctl (fd, TCGETA, &SerialParameters) == -1) {
#ifdef UART_DEBUG
fprintf (stderr, "asy_open: Cannot ioctl (get) on port %s. Errno = %d\n", Port, errno);
#endif
return -1;
}

SerialParameters.c_cflag = Baud | CS8 | CLOCAL | CREAD | HUPCL;
SerialParameters.c_lflag &= ~ICANON;

SerialParameters.c_lflag = 0;
SerialParameters.c_oflag = 0;
SerialParameters.c_iflag = IGNBRK | IGNPAR;
for (i = 0; i < NCC; i++)
SerialParameters.c_cc[i] = (unsigned char) 0;
SerialParameters.c_cc[VMIN] = (unsigned char) 0;
SerialParameters.c_cc[VTIME] = (unsigned char) DataTimeout;

if(ioctl (fd, TCSETA, &SerialParameters) == -1) {
#ifdef UART_DEBUG
fprintf (stderr, "asy_open: Cannot ioctl (set) on port %s. Errno = %d\n", Port, errno);
#endif
return -1;
}

return fd;
}

如何实现当串口发送数据时,如果有数据进来先读取串口数据并显示?
...全文
386 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zl198183 2008-02-01
  • 打赏
  • 举报
回复
如果用select应该怎么写?
初学,不明白!
哪位指点一下
kingwoo 2008-01-31
  • 打赏
  • 举报
回复
你这个程序只能写或者只能读啊
要同时读写用select吧
cceczjxy 2008-01-31
  • 打赏
  • 举报
回复
实际上,串口的速率很慢的.1ms最多也不过10来个字节.但你1ms能读写可能上百次.所以,你的读写过程可以同时进行,
即在写前判断一下有没有数据要读.有就读出来处理就行了.

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧