完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
串口通信电路板接收电脑的数据都是正常的,发送不正常,代码如下
配置相关的#include #include #include #include #include #include #include #include #include #include #include "uart.h" static int fd; /******************************************************************* * 名称: UART0_Open * 功能: 打开串口并返回串口设备文件描述 * 入口参数: fd :文件描述符 port :串口号(ttyS0,ttyS1,ttyS2) * 出口参数: 正确返回为1,错误返回为0 *******************************************************************/ int uart_open(int fd,const char *pathname) { assert(pathname); fd = open(pathname,O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY); if(fd == -1) { perror("Open UART failed!"); return FALSE; } /*恢复串口为阻塞状态,阻塞状态即在读写串口的过程中, * 如果没有读取到足够的数据,则会一直等待,直到出现对应的数据为止,可以使用select绕过阻塞 *非阻塞:fcntl(fd,F_SETFL,FNDELAY) */ if(fcntl(fd, F_SETFL, 0) < 0) { printf("fcntl failed!\n"); return FALSE; } else { printf("fcntl=%d\n",fcntl(fd, F_SETFL,0)); } //测试是否为终端设备 if(0 == isatty(STDIN_FILENO)) { printf("standard input is not a terminal device\n"); return FALSE; } else { printf("isatty success!\n"); } printf("fd->open=%d\n",fd); return fd; } /******************************************************************* * 名称: uart_close * 功能: 关闭串口并返回串口设备文件描述 * 入口参数: fd :文件描述符 port :串口号(ttyS0,ttyS1,ttyS2) * 出口参数: void *******************************************************************/ void uart_close(int fd) { close(fd); } /******************************************************************* * 名称: uart_set * 功能: 设置串口数据位,停止位和效验位 * 入口参数: fd 串口文件描述符 * speed 串口速度 * flow_ctrl 数据流控制 * databits 数据位 取值为 7 或者8 * stopbits 停止位 取值为 1 或者2 * parity 效验类型 取值为N,E,O,,S *出口参数: 正确返回为1,错误返回为0 *******************************************************************/ int uart_set(int fd,int baude,int c_flow,int bits,char parity,int stop) { struct termios options; /*tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将它们保存于options, *该函数还可以测试配置是否正确,该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为1. */ if(tcgetattr(fd,&options) < 0) { perror("tcgetattr error"); return -1; } //设置串口输入波特率和输出波特率 switch(baude) { case 115200: cfsetispeed(&options, B115200); cfsetospeed(&options, B115200); printf("enter bande 115200\n"); break; case 9600: cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); printf("enter bande 9600\n"); break; default: printf("enter bande Error \n"); break; } /*设置控制模式*/ options.c_cflag |= CLOCAL;//保证程序不占用串口 options.c_cflag |= CREAD;//保证程序可以从串口中读取数据 /*设置数据流控制*/ switch(c_flow) { case 0://不进行流控制 options.c_cflag &= ~CRTSCTS; printf("no c_flow \n"); break; case 1://进行硬件流控制 options.c_cflag |= CRTSCTS; break; case 2://进行软件流控制 options.c_cflag |= IXON|IXOFF|IXANY; break; default: fprintf(stderr,"Unkown c_flow!\n"); return -1; } /*设置数据位*/ switch(bits) { case 5: options.c_cflag &= ~CSIZE;//屏蔽其它标志位 options.c_cflag |= CS5; break; case 6: options.c_cflag &= ~CSIZE;//屏蔽其它标志位 options.c_cflag |= CS6; break; case 7: options.c_cflag &= ~CSIZE;//屏蔽其它标志位 options.c_cflag |= CS7; break; case 8: options.c_cflag &= ~CSIZE;//屏蔽其它标志位 options.c_cflag |= CS8; printf("CS8 \n"); break; default: fprintf(stderr,"Unkown bits!\n"); return -1; } /*设置校验位*/ switch(parity) { /*无奇偶校验位*/ case 'n': case 'N': options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验 options.c_cflag &= ~INPCK;//INPCK:使奇偶校验起作用 fprintf(stderr,"parity n \n"); break; /*设为空格,即停止位为2位*/ case 's': case 'S': options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验 options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位 break; /*设置奇校验*/ case 'o': case 'O': options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验 options.c_cflag |= PARODD;//PARODD:若设置则为奇校验,否则为偶校验 options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用 options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位 break; /*设置偶校验*/ case 'e': case 'E': options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验 options.c_cflag &= ~PARODD;//PARODD:若设置则为奇校验,否则为偶校验 options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用 options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位 break; default: fprintf(stderr,"Unkown parity!\n"); return -1; } /*设置停止位*/ switch(stop) { case 1: options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位 fprintf(stderr,"stop 1 \n"); break; case 2: options.c_cflag |= CSTOPB;//CSTOPB:使用两位停止位 break; default: fprintf(stderr,"Unkown stop!\n"); return -1; } /*设置输出模式为原始输出*/ options.c_oflag &= ~OPOST;//OPOST:若设置则按定义的输出处理,否则所有c_oflag失效 options.c_oflag &= ~(ONLCR|OCRNL); /*设置本地模式为原始模式*/ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // options.c_lflag &= ~(ISIG | ICANON); options.c_iflag &=~(ICRNL|INLCR|BRKINT|IXON|IXOFF|IXANY); /* *ICANON:允许规范模式进行输入处理 *ECHO:允许输入字符的本地回显 *ECHOE:在接收EPASE时执行Backspace,Space,Backspace组合 *ISIG:允许信号 */ /*使用二进制,删除不必要的控制符号*/ // options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IGNCR); /*设置等待时间和最小接受字符*/ options.c_cc[VTIME] = 0;//可以在select中设置 options.c_cc[VMIN] = 1;//最少读取一个字符 /*如果发生数据溢出,只接受数据,但是不进行读操作*/ tcflush(fd,TCIFLUSH); /*激活配置*/ if(tcsetattr(fd,TCSANOW,&options) < 0) { perror("tcsetattr failed"); return -1; } return TRUE; } /******************************************************************* * 名称: uart_init() * 功能: 串口初始化 * 入口参数: fd : 文件描述符 * speed : 串口速度 * flow_ctrl 数据流控制 * databits 数据位 取值为 7 或者8 * stopbits 停止位 取值为 1 或者2 * parity 效验类型 取值为N,E,O,,S * * 出口参数: 正确返回为1,错误返回为0 *******************************************************************/ int uart_init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity) { int err; //设置串口数据帧格式 if (uart_set(fd,115200,0,8,'N',1) == FALSE) { return FALSE; } else { return TRUE; } } /******************************************************************* * 名称: uart_recv * 功能: 接收串口数据 * 入口参数: fd :文件描述符 * rcv_buf :接收串口中数据存入rcv_buf缓冲区中 * data_len :一帧数据的长度 * 出口参数: 正确返回为1,错误返回为0 *******************************************************************/ int uart_recv(int fd, char *rcv_buf,int data_len) { int len,fs_sel; fd_set fs_read; /*fd_set是一组文件描述字(fd)的集合, * 它用一位来表示一个fd,定义在头文件中定义常量FD_SETSIZE,一般可表示1024个ID */ struct timeval time; FD_ZERO(&fs_read); /*初始化读取的集合*/ FD_SET(fd,&fs_read); /*用于在文件描述符集合中增加一个新的文件描述符*/ time.tv_sec = 1; /*等待1秒,超时则会退出*/ time.tv_usec = 0; //使用select实现串口的多路通信 fs_sel = select(fd+1,&fs_read,NULL,NULL,&time); printf("fs_sel = %d\n",fs_sel); if(fs_sel) { len = read(fd,rcv_buf,data_len); printf("I am right!(version1.2) len = %d fs_sel = %d\n",len,fs_sel); return len; } else { printf("Sorry,I am wrong!"); return FALSE; } } /******************************************************************** * 名称: uart_send * 功能: 发送数据 * 入口参数: fd :文件描述符 * send_buf :存放串口发送数据 * data_len :一帧数据的个数 * 出口参数: 正确返回为1,错误返回为0 *******************************************************************/ int uart_send(int fd, char *send_buf,int data_len) { int len = 0; len = write(fd,send_buf,data_len); if (len == data_len ) { printf("send data is %s\n",send_buf); return len; } else { tcflush(fd,TCOFLUSH); return FALSE; } } 主程序如下: #include #include #include #include #include #include #include #include #include #include #include "uart.h" /* *主程序,循环读取数据 *参数,./usar <参数数量> <路径> <参数cmd> *cmd <0> 发送数据 * <1> 其他则循环读取数据 */ int main(int argc, char **argv) { int fd; //文件描述符 int err; //返回调用函数的状态 int len; int i; char rcv_buf[100]; char send_buf[20]="123456789"; if(argc != 3) { printf("Usage: %s /dev/ttySn 0(send data)/1 (receive data) \n",argv[0]); return FALSE; } fd = uart_open(fd,argv[1]); //打开串口,返回文件描述符,需要提供相应的路径 do { err = uart_init(fd,115200,0,8,1,'N'); printf("Set Port Exactly!\n"); sleep(1); }while(FALSE == err || FALSE == fd); if(0 == strcmp(argv[2],"0")) { for(i = 0;i < 10;i++) { len = uart_send(fd,send_buf,7); if(len > 0) printf(" %d time send %d data successful\n",i,len); else printf("send data failed!\n"); sleep(2); } uart_close(fd); } else { while (1) //循环读取数据 { len = uart_recv(fd, rcv_buf,99); if(len > 0) { rcv_buf[len] = '\0'; printf("receive data is %s\n",rcv_buf); printf("len = %d\n",len); } else { printf("cannot receive data\n"); } sleep(2); } uart_close(fd); } } 发送的数据到电脑,都不正确,但是数据是正确的,比如发送7个a接收到的为E1 E1 B8 B8 5C 5C FE,非常奇怪的现象,难道新唐的单片机有问题吗? |
|
相关推荐
1个回答
|
|
|
可能的原因包括:
1. 发送的数据格式不正确,导致接收端无法解析。需要确认发送的数据格式是否与接收端协议一致。 2. 发送的数据长度不正确,导致接收端无法接收完整的数据。需要确认发送的数据长度是否与接收端的缓冲区大小一致。 3. 发送的数据速率不正确,导致接收端无法正确接收数据。需要确认发送端和接收端的波特率设置是否一致。 4. 串口通信电路板硬件出现问题,导致发送失败。需要检查串口通信电路板本身的连接和配置是否正确。 5. 程序本身出现了bug,导致发送失败。需要仔细检查程序并进行调试。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
1559 浏览 0 评论
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
4732 浏览 0 评论
4223 浏览 9 评论
3816 浏览 16 评论
4393 浏览 1 评论
4206浏览 3评论
2378浏览 0评论
3392浏览 0评论
1157浏览 0评论
2841浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 10:50 , Processed in 0.467294 second(s), Total 44, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1304