Chinaunix首页 | 论坛 | 博客
  • 博客访问: 349351
  • 博文数量: 87
  • 博客积分: 1322
  • 博客等级: 少尉
  • 技术积分: 915
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-25 18:04
文章分类

全部博文(87)

文章存档

2013年(10)

2012年(9)

2011年(68)

分类:

2011-11-24 10:29:40

原文地址:串口通信程序 作者:futurepeter

/*====================
程序名:串口通信程序
====================*/

#include /*标准输入输出定义*/
#include /*标准函数库定义*/
#include /*Unix 标准函数定义*/
#include
#include
#include /*文件控制定义*/
#include /*PPSIX 终端控制定义*/
#include /*错误号定义*/
#include

#include
#include

#define FALSE -1
#define TRUE 0

int fd;
pthread_t pid_Send;
pthread_t pid_Recv;
typedef struct
{
    int size;
    char buff[100];
}Cmd_Buf,*LpCmdBuf;
LpCmdBuf pCb;

//struct termio
//{
//    unsigned short c_iflag; /* 输入模式标志 */
//    unsigned short c_oflag; /* 输出模式标志 */
//    unsigned short c_cflag; /* 控制模式标志*/
//    unsigned short c_lflag; /* local mode flags */
//    unsigned char c_line; /* line discipline */
//    unsigned char c_cc[NCC]; /* control characters */
//};

//设置波特率的例子函数:
/**
*@brief 设置串口通信速率
*@param fd 类型 int 打开串口的文件句柄
*@param speed 类型 int 串口速度
*@return void
*/
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300};

void set_speed(int fd, int speed)
{
    int i;
    int status;
    struct termios Opt;
//    tcgetattr(fd, &Opt);
    if ( tcgetattr( fd,&Opt) != 0)
    {
        printf("get serial failed\n");
        return;
    }   
    for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
    {
        if (speed == name_arr[i])
        {
            tcflush(fd, TCIOFLUSH);
            cfsetispeed(&Opt, speed_arr[i]);
            cfsetospeed(&Opt, speed_arr[i]);
            status = tcsetattr(fd, TCSANOW, &Opt);
            if (status != 0)
            {
                perror("tcsetattr fd1");
                return;
            }
            tcflush(fd,TCIOFLUSH);
        }
    }
    printf("speed set ok\n");
}


//设置效验的函数:
/**
*@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)
    {
        perror("SetupSerial 1");
        return(FALSE);
    }
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= (CLOCAL|CREAD);
    switch (databits) /*设置数据位数*/
    {
        case 7:
        options.c_cflag |= CS7;
        break;
        case 8:
        options.c_cflag |= CS8;
        break;
        default:
        fprintf(stderr,"Unsupported data sizen"); return (FALSE);
    }
    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 parityn");
        return (FALSE);
    }
    /* 设置停止位*/
    switch (stopbits)
    {
        case 1:
        options.c_cflag &= ~CSTOPB;
        break;
        case 2:
        options.c_cflag |= CSTOPB;
        break;
        default:
        fprintf(stderr,"Unsupported stop bitsn");
        return (FALSE);
    }
    /* Set input parity option */
    if (parity != 'n')
        options.c_iflag |= INPCK;
    options.c_iflag = IGNPAR|IGNBRK;
    /* raw input */
        options.c_lflag = 0;
         /* raw ouput */
        options.c_oflag = 0;

    tcflush(fd,TCIFLUSH);
    //下面两个参数比较重要 一个设置超时时间 一个设置读取多少字节显示
    //具体视情况而定 但是这两个参数如要用其中一个的特性 另一个需要设置为0
    //例如我读取15个字节显示 则将超时时间设置成0 即不起作用
    options.c_cc[VTIME] = 0; /* 设置超时15 seconds*/
    options.c_cc[VMIN] = 15; /* Update the options and do it NOW */
    if (tcsetattr(fd,TCSANOW,&options) != 0)
    {
        perror("SetupSerial 3");
        return (FALSE);
    }
    printf("parity set ok\n");
    return (TRUE);
}

//下面是一个简单的读取串口数据的例子,使用了上面定义的一些函数和头文件
/**********************************************************************
代码说明:使用串口二测试的,发送的数据是字符,
但是没有发送字符串结束符号,所以接收到后,后面加上了结束符号。
我测试使用的是单片机发送数据到第二个串口,测试通过。
**********************************************************************/
//#define FALSE -1
//#define TRUE 0
/*********************************************************************/
int OpenDev(char *Dev)
{
    int fd = open( Dev, O_RDWR| O_NOCTTY | O_NDELAY);
//    int fd = open( Dev, O_RDWR |O_NDELAY);
    if (-1 == fd)
    {
        perror("Can't Open Serial Port");
        return -1;
    }
    else
    {
        printf("dev open ok\n");
        //fcntl(fd,F_SETFL,FNDELAY);   
        return fd;
    }
}

void Uart_Send(void)
{
    unsigned char cmd1[]={0x02,0x00,0x00,0x04,0x46,0x52,0x9C,0x03}; //寻卡
    unsigned char cmd2[]={0x02,0x00,0x00,0x04,0x47,0x04,0x4F,0x03}; //防冲撞--读卡
    unsigned char cmd3[]={0x02,0x00,0x00,0x04,0x05,0x00,0x09,0x03}; 
    int nbyte;
    while(1)
    {
        nbyte=write(fd,cmd1,sizeof(cmd1));
        if(nbyte!=0)
            usleep(10000);
        nbyte=write(fd,cmd2,sizeof(cmd2));
        if(nbyte!=0)
            usleep(100000);
        //printf("==write success==\n");
    }
}
void Uart_Recv2(void)
{
    struct timeval timeout;
    fd_set readfd;
    int nread,ret;
    char buff[512];
    while (1)
    {
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    FD_ZERO(&readfd);
    FD_SET(fd, &readfd);
    ret = select(fd + 1, &readfd, NULL, NULL, &timeout);
    if (FD_ISSET(fd, &readfd))
    {
        //if((nread = read(fd, buff, 512))>0)
        if((nread = read(fd, buff, 512))>0)
        {
            printf("nLen %d\n",nread);
            buff[nread+1] = ' ';
            //process the data
            printf( "%02X ", buff[0]);
            printf( "%02X ", buff[1]);   
            printf( "%02X ", buff[2]);
            printf( "%02X ", buff[3]);   
            printf( "%02X ", buff[4]);
            printf( "%02X ", buff[5]);   
            printf( "%02X ", buff[5]);   
            printf( "%02X ", buff[6]);   
            printf( "%02X ", buff[7]);   
            printf( "%02X ", buff[8]);   
            printf( "%02X ", buff[9]);   
            printf( "%02X ", buff[10]);   
            printf( "%02X ", buff[11]);   
            printf( "%02X ", buff[12]);   
            printf("\n");
        }
        else
            printf("No data read :%d\n",nread);
    }
    }
}
void Uart_Recv(void)
{
    struct timeval timeout;
    fd_set readfd;
    int nread,ret;
    char buff[512];
    while (1)
    {
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    FD_ZERO(&readfd);
    FD_SET(fd, &readfd);
    ret = select(fd + 1, &readfd, NULL, NULL, &timeout);
    if (FD_ISSET(fd, &readfd))
    {
        //if((nread = read(fd, buff, 512))>0)
        if((nread = read(fd, buff, 512))>0)
        {
            //printf("nLen %dn",nread);
            buff[nread+1] = ' ';
            int i;
            //process the data
            if(buff[0]==0X02&&buff[nread-1]==0X03&&nread==12)
            {
                for(i=0;i                    printf( "%02X ", buff[i]);
            }
            else if(buff[0]==0X02&&buff[nread-1]==0X03&&nread!=12)
            {
                continue;
            }
            else if(buff[0]==0X02&&buff[nread-1]!=0X03)
            {
                //printf( "%02X ", buff[0]);
                memcpy(pCb->buff,buff,nread);
                pCb->size+=nread;
                continue;
            }
            else if(pCb->size!=0&&buff[nread-1]==0X03)
            {
                memcpy(&pCb->buff[pCb->size],buff,nread);
                pCb->size+=nread;
            //    printf("pCb->size:%d \n",pCb->size);
                if(pCb->size==12)
                {    //bingo
                    for(i=0;isize;i++)
                    printf( "%02X ", pCb->buff[i]);
                    printf("\n");
                    system("/usr/dltk/popcliapp -printfb \"get the correct data\"\n");
                }
                memset(pCb,0,sizeof(Cmd_Buf));
            }
            /*printf( "%02X ", buff[15]);
            printf( "%02X ", buff[16]);   
            printf( "%02X ", buff[17]);
            printf( "%02X ", buff[18]);   
            printf( "%02X ", buff[19]);
            printf( "%02X ", buff[20]);   
            */
            //printf("\n");
        }
        else
            printf("No data read :%d\n",nread);
    }
    }
}
int main(int argc, char **argv)
{
   
    int nread;
//    char *dev = "/dev/s3c_serial0"; //串口二
    char *dev = "/dev/ttyS0"; //串口二
    int ret=0;
   
    //open the serial and configure it
    fd = OpenDev(dev);
    set_speed(fd,9600);
    if (set_Parity(fd,8,1,'N') == FALSE)
    {
        printf("Set Parity Errorn");
        exit (0);
    }
    pCb=malloc(sizeof(Cmd_Buf));
    pCb->size=0;
    //start the read and write thread

/*    ret=pthread_create(&pid_Send,NULL,(void *)Uart_Send,NULL);
    if(ret!=0)
    {
        printf("write thread create error\n");
        return -1;
    }
*/
    ret=pthread_create(&pid_Recv,NULL,(void *)Uart_Recv2,NULL);
    if(ret!=0)
        return -1;
   

    //pthread_join(pid_Send,NULL);
    pthread_join(pid_Recv,NULL);
    close(fd);
    return 0;

    /*write cmd to the serial dev*/
    //02 00 00 04 6A 10 03 71 03 点亮黄灯
    //02 00 00 04 6A 00 6E 03
/*
    unsigned char cmd1[]={0x02,0x00,0x00,0x04,0x6A,0x10,0x03,0x71,0x03};
    unsigned char cmd2[]={0x02,0x00,0x00,0x04,0x6A,0x00,0x6E,0x03};
    int nbyte=write(fd,cmd1,sizeof(cmd1));
    while (1) //循环读取数据
    {
        if((nread = read(fd, buff, 512))>0)
        {
            printf("nLen %dn",nread);
            buff[nread+1] = ' ';
            printf( "n%s", buff);
        }
        else
            printf("No data read :%d\n",nread);
        sleep(1);
   
    close(fd);
    exit (0);*/
}



阅读(619) | 评论(0) | 转发(0) |
0

上一篇:framebuffer驱动全篇

下一篇:jpeg+fb 显示图片

给主人留下些什么吧!~~