openwrt 7688串口通信

在7688上写了个串口接受并把接收的数据发回,在这个过程中一直有回传,就是电脑串口发送给7688一次数据,7688把这些数据接收到,然后再发送回电脑。遇到问题:每次电脑发送一次,然而接收框里接收两次数据。解决是在配置里添加GNBRK;仔细研究可以查看termios 详解。一下是修改后程序。

#include <stdio.h> //标准输入输出定义
#include <stdlib.h> //标准函数库定义
#include <unistd.h> //Unix标准函数定义
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //文件控制定义
#include <termios.h> //POSIX中断控制定义
#include <errno.h> //错误号定义
#include <string.h>
#include <wait.h>
#define serial_device "/dev/ttyS1"
//打开串口
int open_port(void)
{
    int fd; //串口的标识符
    //O_NOCTTY用来告诉Linux这个程序不会成为“控制终端”
    //O_NDELAY用来告诉Linux这个程序不关心DCD信号
    fd=open(serial_device,O_RDWR|O_NOCTTY);
    if(fd == -1)
    {
        //不能打开串口
        perror("open_port: Unable to open /dev/ttyS0 -");
        return(fd);
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("open ttys1 .....\n");
        return(fd);
    }
}
//设置波特率
void set_speed_and_parity(int fd, int speed)
{
    struct termios Opt; //定义termios结构
    if(tcgetattr(fd,&Opt)!=0)
    {
        perror("tcgetattr fd");
        return;
    }
    tcflush(fd, TCIOFLUSH);//清空缓存
    cfsetispeed(&Opt, B115200);//设置波特率
    cfsetospeed(&Opt, B115200);
   
   
    //tcflush(fd, TCIOFLUSH);
    //设置奇偶校验——默认8个数据位、没有校验位
    Opt.c_cflag &= ~PARENB;

    Opt.c_cflag &= ~CSTOPB;
    Opt.c_cflag &= ~CSIZE;
    Opt.c_cflag |= CS8;
    Opt.c_cflag &= ~(CLOCAL);
    Opt.c_cflag |= CREAD;
    Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    //软件流控制无效,因为硬件没有硬件流控制,所以就不需要管了
    Opt.c_iflag &= ~(IXON | IXOFF | IXANY);
    Opt.c_iflag |= IGNBRK;
    //原始输出方式可以通过在c_oflag中重置OPOST选项来选择:
    Opt.c_oflag &= ~OPOST;
    //VMIN可以指定读取的最小字符数。如果它被设置为0,那么VTIME值则会指定每个字符读取的等待时间。
    Opt.c_cc[VTIME] = 0;
    Opt.c_cc[VMIN] = 0;

/*tcsetattr函数标志:
    TCSANOW:立即执行而不等待数据发送或者接受完成。
    TCSADRAIN:等待所有数据传递完成后执行。
    TCSAFLUSH:Flush input and output buffers and make the change
    */

if(tcsetattr(fd, TCSANOW, &Opt) != 0)
    {
        perror("tcsetattr fd");
        return;
    }
    tcflush(fd, TCIOFLUSH);
}
int serial_write(int fd ,char *data, int datalen)
{
    int len=0;
    //获取实际传输数据的长度
    len=write(fd,data,datalen);
    printf("send data OK! datalen=%d\n",len);
    return len; 
}
int serial_read(int fd,char buff[],int datalen)
{
    int nread=0;
    //printf("Ready for receiving data...");
    nread=read(fd,buff,datalen);
    if(nread>0)
    {
    printf("readlength=%d\n",nread);
    buff[nread]='\0';
    //printf("%s\n",buff);
    }
    return nread;
}
int serialport()
{
    int fd;
    //打开串口
    if((fd=open_port())<0)
    {
    perror("open_port error");
    return 0;
    }
    //设置波特率和校验位
    set_speed_and_parity(fd,115200);
    return (fd);
}
int main(void)
{
    int fd;
    int nread,i,n =0,datalen=0, len = 0;
    char test[8]="Hello\r\n";
    char writebuf[100];
    char readbuff[100];
    fd=serialport();
    printf("fd=%d\n",fd);
    //尝试先写内容
   
    //循环读取串口并输出
    printf("enter the while loop\n");
        //这个是重点,当时我就是这个问题出错了,每次读之前必须清空一次。
    bzero(readbuff, sizeof(readbuff));
    bzero(writebuf, sizeof(writebuf));
    //writebuf = "a1a2a3a4";
    serial_write(fd,test,8);
    sleep(1);
    while(1)
        {
           // printf("enter the while loop\n");
            
            //serial_write(fd,test,8);
            bzero(readbuff, sizeof(readbuff));
            sleep(1);
            datalen=serial_read(fd,readbuff,512);
            if(datalen > 0)
            {
                if(readbuff[0]=='O'&&readbuff[1]=='F'&&readbuff[2]=='F')
                {
                     break;
                }
               
                serial_write(fd,readbuff,datalen);
            }
        }
        
    
}

 

 

下面这句

if(tcsetattr(fd, TCSANOW, &Opt) != 0)
    {
        perror("tcsetattr fd");
        return;
    }

把串口设置完参数后,使用这句生效。

在linux中sleep()是挂起1s,用usleep()是挂起微秒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值