当前位置:  技术问答>linux和unix

串口通信的问题

    来源: 互联网  发布时间:2017-03-21

    本文导语:  在网上修改了串口通信的代码,编译正确,打开串口和参数设置都是正确的,但是就是在发送数据的时候出现问题,板子发送的数据PC收不到,PC发送的数据板子也收不到,不知道是什么原因,详情各位大哥看看~~~ 附...

在网上修改了串口通信的代码,编译正确,打开串口和参数设置都是正确的,但是就是在发送数据的时候出现问题,板子发送的数据PC收不到,PC发送的数据板子也收不到,不知道是什么原因,详情各位大哥看看~~~
附上我的主要代码:

/***@brief  设置串口通信速率
*@param  fd     类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void*/

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
    B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300,
    38400,  19200,  9600, 4800, 2400, 1200,  300, };
void set_speed(int fd, int speed)
{
int   i;
int   status;
struct termios   Opt;
tcgetattr(fd, &Opt);
for(i= 0;i0)
{
printf("Open Serial Port Successful!n");
set_speed(fd,19200);
printf("set_speed Successful!n");

else
{
printf("Can't Open Serial Port!n");
exit(0);
}

if (set_Parity(fd,8,1,'N')== FALSE)
{
printf("Set Parity Errorn");
exit(1);
}

printf("Set Parity Successful!n");

#if 1
//while(1)
//{
nRet = write(fd,buff,512);
if(-1 == nRet)
{
printf("Write Error!n");
}
printf("Write Successful!n");
//}
#endif

#if 0
while(1)
{
while((nread = read(fd,buff,512))>0)
{
printf("nLen %dn",nread);
buff[nread+1]='';
printf("n%s",buff);
}
}
#endif
    nRet = close(fd);
if(-1 == nRet)
{
printf("Close Port Error!n");
}
printf("Close Port Successful!n");
}


|
1、判断你的串口线是否正确
2、判断你所用的串口设备是否正确
3、判断你的板子和PC之间的串口设置是否一致
还不行的话,建议用示波器进行判断:
当板子发送数据时,用示波器看看串口线上是否有波形。

|
再给你个建议:
把你这段代码,放到PC上(Linux OS)编译运行,让两台PC进行串口通讯。
如果没有问题那应该是板子的串口驱动程序有问题。
如果在PC上运行也有问题,再仔细查你的代码(稍微浏览了一下,没有发现明显的问题)。

|
给你一个建议:

1,首先用超级终端测试该串口是否是通的。我曾今遇到这种情况,串口线绝对是好的。设备绝对是好的。

但是就是不同。最后找了很久才发现,原来我的开发板串口竟然没有交叉!!!RXD  Txd竟然没有交叉!!

2.先不着急发送别的,先测试发送单个字符。

然后对于串口设置,设置好几就ok了。主要的问题恐怕就是设置阻塞那一段属性需要你自己去式。其他没什么

困难的了

|
在实际中的情况往往是非常多特例,比如,在用write发送数据时没有键入回车,信息就将发送不出去的情况,这主要是因为我们在输出输入时是按照 规范模式接受到回车或换行才发送,而非常多情况我们是不必回车和换行的,这时,应当转换到行方式输入,设置options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);不经处理直接发送。

又比如在我们发送字符0x0d的时候,往往接受端得到的字符是0x0a 这是怎么回事,原因是在串口设置中c_iflag和c_oflag中存在从NL-CR 和CR-NL的映射,也就是说,串口能把回车和换行看成一个字符,所以,此时我们应该屏蔽掉这些,用options.c_oflag &=~(INLCR|IGNCR|ICRNL|);和options.c_oflag &=~(ONLCR|OCRNL); 进行设置。

|
我也用过这段代码,也是无法通信,后来网上查了下,在set_Parity的设置options的设置改成如下就可以了
    options.c_cflag |= CLOCAL | CREAD;
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;
    options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

|
int set_Parity(int ai_com,uchar ai_databits,uchar ai_stopbits,uchar ai_parity)
{
    struct termios options;
    if  ( tcgetattr( ai_com,&options)  !=  0)
    {
        return ERROR_LOAD_COMINFO;
    }
    options.c_cflag |= CLOCAL | CREAD;
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag &= ~OPOST;
    options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    /*options.c_cflag &= ~CSIZE;
    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_oflag  &= ~OPOST;   */

    switch (ai_databits) /*设置数据位数*/
    {
        case 5:
            options.c_cflag |= CS5;
            break;
        case 6:
            options.c_cflag |= CS6;
            break;
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            return ERROR_DATABITS;
    }
    switch (ai_parity)
    {
        /*case 'n':
        case 'N':*/
        case 1:
            options.c_cflag &= ~PARENB;   /* Clear parity enable */
            options.c_iflag &= ~INPCK;     /* Enable parity checking */
            break;
        /*case 'o':
        case 'O':*/
        case 2:
            options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
            options.c_iflag |= INPCK;             /* Disnable parity checking */
            break;
        /*case 'e':
        case 'E':*/
        case 3:
            options.c_cflag |= PARENB;     /* Enable parity */
            options.c_cflag &= ~PARODD;   /* 转换为偶效验*/
            options.c_iflag |= INPCK;       /* Disnable parity checking */
            break;
        /*case 'S':
        case 's':  /*as no parity*/
        case 4:
            options.c_cflag &= ~PARENB;
            options.c_cflag &= ~CSTOPB;
            break;
        default:
            return ERROR_PARITY;
    }
    /* 设置停止位*/
    switch (ai_stopbits)
    {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
         case 2:
            options.c_cflag |= CSTOPB;
            break;
         default:
            return ERROR_STOPBITS;
    }

    /* Set input parity option */
/*    if (ai_parity != 'n')*/
    if (ai_parity != 1)
        options.c_iflag |= INPCK;
    tcflush(ai_com,TCIFLUSH);
    options.c_cc[VTIME] = 0; /* 设置超时15 seconds*/
    options.c_cc[VMIN] = 1; /* define the minimum bytes data to be readed*/
    if (tcsetattr(ai_com,TCSANOW,&options) != 0)
    {
        /*printf("set_Parity errorn");*/
        return (FALSE);
    }
    /*printf("set_Parity successn");*/
    return (TRUE);
}
这是我的set_Parity,用在modem拨号程序上,做了些修改以对应数据库里的参数,大体上和你用的差不多

|
重点查查串口驱动中的初始化部分,看看你要用的串口的配置寄存器是否正确。或者你的驱动中只配置了UART0和UART1,而你却要用到UART3。

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。














站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3