LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 889|回复: 0

串口编程的问题,请大侠们指教

[复制链接]
发表于 2010-11-21 20:48:17 | 显示全部楼层 |阅读模式
最近弄一个小工具,就是LINUX下与单片机通信,目前单片机程序已经搞定,在WINDWOS下,单片机以9600 8数据位1停止位无奇偶校验可以通信,现在在LINUX下在网上搜了一个源程序如下:

#include <stdio.h>      /*标准输入输出定义*/
#include <stdlib.h>     /*标准函数库定义*/
#include <unistd.h>     /*Unix 标准函数定义*/
#include <sys/types.h>  
#include <sys/stat.h>   
#include <fcntl.h>      /*文件控制定义*/
#include <termios.h>    /*PPSIX 终端控制定义*/
#include <errno.h>      /*错误号定义*/

/**
*@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;
       
        [color="Red"]if(tcgetattr(fd, &Opt)==-1)        {
                //Get current settings failure;
                perror("Get current settings failure!");
                return;
        }
       
        for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
        {
                if  (speed == name_arr)
                {
                        tcflush(fd, TCIOFLUSH);
                        if(cfsetispeed(&Opt, speed_arr)==-1)
                        {
                                perror("in set_speed cfsetispeed error!");
                                return ;
                        }
                        if(cfsetospeed(&Opt, speed_arr)==-1)
                        {
                                perror("in set_speed cfsetospeed error!");
                                return;
                        }
                        status = tcsetattr(fd, TCSANOW, &Opt);  
                        if  (status != 0)
                        {
                                perror("tcsetattr fd");  
                                return;     
                        }   
                        tcflush(fd,TCIOFLUSH);
                        break;
                }  
        }
}

/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄
*@param  databits 类型  int 数据位   取值 为 7 或者8
*@param  stopbits 类型  int 停止位   取值为 1 或者2
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
        struct termios options;
        if(tcgetattr(fd,&options)!=0)
        {
                //Get current settings failure;
                perror("Get current settings failure!");     
                return -1;  
        }
        options.c_cflag &= ~CSIZE;
        switch (databits) /*设置数据位数*/
        {   
        case 7:               
                options.c_cflag |= CS7;
                break;
        case 8:     
                options.c_cflag |= CS8;
                break;   
        default:   
                fprintf(stderr,"Unsupported data size\n");
                return -1;
        }
        switch (parity)
        {   
        case 'n':
        case 'N':   
                options.c_cflag &= ~PARENB;   /* Clear parity enable */
                options.c_iflag &= ~INPCK;     /* Enable parity checking */
                break;  
        case 'o':   
        case 'O':     
                options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/  
                options.c_iflag |= INPCK;             /* Disnable parity checking */
                break;  
        case 'e':  
        case 'E':   
                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*/   
                options.c_cflag &= ~PARENB;
                options.c_cflag &= ~CSTOPB;
                break;  
        default:   
                fprintf(stderr,"Unsupported parity\n");   
                return -1;  
        }  
        /* 设置停止位*/  
        switch (stopbits)
        {   
        case 1:   
                options.c_cflag &= ~CSTOPB;  
                break;  
        case 2:   
                options.c_cflag |= CSTOPB;  
                break;
        default:   
                fprintf(stderr,"Unsupported stop bits\n");  
                return -1;
        }
        /* Set input parity option */
        if (parity != 'n')   
                options.c_iflag |= INPCK;
        tcflush(fd,TCIFLUSH);
        options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/   
        options.c_cc[VMIN] = 0; /* Update the options and do it NOW */

        //以下两句将串口设为原始(RAW)模式
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
        options.c_oflag &= ~OPOST; /*Output*/

        if (tcsetattr(fd,TCSANOW,&options) != 0)   
        {
                perror("Set serial port failure!");   
                return -1;  
        }
        return 0;  
}

int main(int argc, char **argv)
{
        int fd;
        int nread;
        char buff[512];
        char *dev  = "/dev/ttyS1"; //串口一
       
        fd=open(dev,O_RDWR); //| O_NOCTTY | O_NDELAY
        if(-1 == fd)
        {
                perror("Can't Open Serial Port");
                return -1;//Open serial port failure!;
        }       

        set_speed(fd,9600);//set speed as 9600bps

        if (set_Parity(fd,8,1,'N')==-1)
        {
                printf("Set Parity Error\n");
                exit (0);//set parity failure;
        }
        while (1)
        {
                /*
                while((nread = read(fd, buff, 512))>0)
                {
                        printf("\nLen %d\n",nread);
                        buff[nread+1] = '\0';   
                        printf( "\n%s", buff);   
                }*/

                buff[1]=0x05;
                buff[2]=0x1A;
                write(fd,buff,2);
                break;
        }
        close(fd);

        return 0;
}

程序运行到红色代码处,提示  input/output error ,且tcgetattr函数返回-1,即调用失败,是什么问题啊,望大位们指教。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表