|
最近做项目用到串口通信,碰到问题如下:
无论用串口收数据还是发数据,始终用的都是控制台所用的串口(终端为超级终端和CRT),而不能用其他串口,
既无论我开串口几,都是在当前串口,也就是控制台串口打印。
看懂的可不看例
/***********************************************************************************************************************************************************************************************************
例如:
我现在要用串口发的程序发数据,板子控制台用的是串口0(正常的是ttyS0,我的板子是tq2440_serial0,以此类推),open的是串口1,既发数据用的是串口1;
1,运行程序,串口0发送成功,在控制台打印出发送信息,而串口1的终端没反应;
2,而然后我不连接串口1的串口线,运行程序,串口0依然发送成功,在控制台打印出发送信息。
3,依然不连接串口一的串口线,仍然只连接控制台,也就是串口0的串口线,open依次改为串口2,。。。娱乐一下,改为串口4X,多次验证,结果依然以串口0发送,成功;
4,NOW我们把控制台控制权交给串口1,重复上述实验,结果为无论open的是串口几,都是在控制台串口,既串口1,发送成功,其他串口无反应(串口线插着);拔掉其他串口,只剩控制台串口,发送依然成功;
5,若OPEN错误的设备,则程序无法执行,但只要是个串口,哪怕是ttyS4X,5X,只要设备里有,就会在控制台串口下发收数据,且open的串口无法应;
串口接收程序同上;
************************************************************************************************************************************************************************************************************/
经认识的高人分析,可能是内核串口驱动这块有问题;
我的收发程序如下:
uart.c 串口设置程序uartwf.c发程序 uartrf.c收程序
//uart.c 串口配置
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
struct termios old_cfg;
int speed_arr[]={B115200,B57600,B38400,B19200,B9600,B4800,B2400,B1800};
int name_arr[]={115200,57600,38400,19200,9600,4800,2400,1800};
int set_speed(int fd,int speed){
int i;
int ret;
struct termios Opt;
tcgetattr(fd,&Opt);
for(i=0;i<sizeof(speed_arr)/sizeof(speed_arr[0]);i++){
if(speed=name_arr){
tcflush(fd,TCIOFLUSH);
cfsetispeed(&Opt,speed_arr);
cfsetispeed(&Opt,speed_arr);
#if 1
Opt.c_cflag|=CLOCAL|CREAD;
Opt.c_oflag&=~(OPOST);
// cfmakeraw(&Opt);
Opt.c_lflag&=~(ICANON|ISIG|ECHO|IEXTEN);
// Opt.c_lflag=ICANON;
Opt.c_iflag&=~(INPCK|BRKINT|ICRNL/*|IGNCR|INLCR*/|ISTRIP|IXON);
// Opt.c_iflag=0;
// Opt.c_iflag|=IGNPAR|IGNBRK;
#if 0
/* 初始化所有的控制特性预设值可以在 /usr/include/termios.h 找到,
在注解中也有, 但我们在这不需要看它们 */
Opt.c_cc[VINTR] = 0; /* Ctrl-c */
Opt.c_cc[VQUIT] = 0; /* Ctrl-\ */
Opt.c_cc[VERASE] = 0; /* del */
Opt.c_cc[VKILL] = 0; /* @ */
Opt.c_cc[VEOF] = 0; /* Ctrl-d */
// Opt.c_cc[VTIME] = 5; /* 不使用分割字元组的计时器 */
// Opt.c_cc[VMIN] = 0; /* 在读取到 1 个字元前先停止 */
Opt.c_cc[VSWTC] = 0; /* '\0' */
Opt.c_cc[VSTART] = 0; /* Ctrl-q */
Opt.c_cc[VSTOP] = 0; /* Ctrl-s */
Opt.c_cc[VSUSP] = 0; /* Ctrl-z */
Opt.c_cc[VEOL] = 0; /* '\0' CR */
Opt.c_cc[VREPRINT] = 0; /* Ctrl-r */
Opt.c_cc[VDISCARD] = 0; /* Ctrl-u */
Opt.c_cc[VWERASE] = 0; /* Ctrl-w */
Opt.c_cc[VLNEXT] = 0; /* Ctrl-v */
Opt.c_cc[VEOL2] = 0; /* '\0' */
#endif
#endif
ret=tcsetattr(fd,TCSANOW,&Opt);
if(ret!=0){
perror("tcsetattr fd");
return 0;
}
tcflush(fd,TCIOFLUSH);
return 1;
}
}
}
int set_Parity(int fd,int databits,int stopbits,char parity)
{
struct termios options;
if(tcgetattr(fd,&options)!=0){
perror("tcgetattr options");
return 0;
}
options.c_cflag&=~CSIZE;
switch(databits){
case 7: options.c_cflag|=CS7;
break;
case 8: options.c_cflag|=CS8;
break;
default:
fprintf(stderr,"Unsupported date size\nPlease input 7or8\n");
return 0;
}
switch(stopbits){
case 1: options.c_cflag&=~CSTOPB;
break;
case 2: options.c_cflag|=CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\nPlease input 1or2\n");
return 0;
}
switch(parity){
case 'n':
case 'N': options.c_cflag&=~PARENB;
options.c_iflag&=~INPCK;
break;
case 'o':
case 'O': options.c_cflag|=(PARODD|PARENB);
options.c_iflag|=INPCK;
break;
case 'e':
case 'E': options.c_cflag&=~PARODD;
options.c_cflag|=PARENB;
options.c_iflag|=INPCK;
break;
default:
fprintf(stderr,"Unsupported parity\nPlease input n o or e\n");
return 0;
}
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME]=255;
options.c_cc[VMIN]=0;
if(tcsetattr(fd,TCSANOW,&options)!=0){
perror("tcsetattr options");
return 0;
}
tcflush(fd,TCIFLUSH);
return 1;
}
//串口初始化,包括波特率(115200~1800),数据位(7,8),停止位(1,2),校验位(n,o,e)的的设置
int uart_init(int fd,int speed,int databitss,int stopbits,char party)
{
// struct termios old_cfg; //保存原先串口配置
if(tcgetattr(fd,&old_cfg)!=0){
perror("tcgetattr old_cfg");
return 0;
}
if(set_speed(fd,speed)<0){
printf("set_speed failed");
return 0;
}
if(set_Parity(fd,databitss,stopbits,party)<0){
printf("set_Parity failed");
return 0;
}
return 1;
}
//uartwf.c 发送
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
#include<sys/wait.h>
#include "sys/ioctl.h"
extern struct termios old_cfg;
int main()
{
int len=0;
int fd,fd2,/*fd3,*/loops,rc;
char *buffer;
int size = 128;
buffer = (char *) malloc(size);
char *dev="/dev/tq2440_serial1";
// char *dev="/dev/ttyS0";
if(fd=open(dev,O_RDWR|O_NOCTTY)<0){
perror("Open Serial Port");
return 0;
}
// ioctl(fd, TIOCEXCL, 0);
if(uart_init(fd,115200,8,1,'n')<0){
printf("uart_init err\n");
return 0;
}
/* if((fd2=open("/My_Documents/12345.c",O_RDWR,0777))<0){
perror("open fd2");
} */
fd2=open("/My_Documents/sound.raw",O_RDWR,0777);
if(fd2<0)
perror("open fd2");
/* fd3=open("/My_Documents/s123.raw",O_RDWR,0777);
if(fd2<0)
perror("open fd2"); */
loops=6880;
while (loops > 0) {
loops--;
rc = read(fd2, buffer, size);
if (rc == 0) {
fprintf(stderr, "end of file on input\n");
break;
}
else if (rc != size) {
fprintf(stderr,"short read: read %d bytes\n", rc);
}
/* rc = write(fd3, buffer, size);
if (rc == 0) {
fprintf(stderr, "end of file on output\n");
break;
}
else if (rc != size) {
fprintf(stderr,"short read: write %d bytes\n", rc);
} */
// printf(buffer);
rc=write(fd,buffer,size);
if(rc<0){
perror("uart write faild");
}
if (rc != size){
fprintf(stderr, "short write: wrote %d bytes\n", rc);
}
len+=size;
//printf("Send total: %d\r\n", len);
// usleep(100000);
}
tcflush(fd,TCIFLUSH);
if(tcsetattr(fd,TCSANOW,&old_cfg)!=0){
perror("tcsetattr options");
return 0;
}
close(fd);
close(fd2);
// close(fd3);
free(buffer);
return 1;
} |
|