协议通信格式是:9600bpsd、8位数据位、无校验位的异步通讯方式.通过RS232连接串口.
我发送命令后程序读不出数据,read后显示读的数据字节数为0.调试了两天,还是读不出数据,郁闷.高手帮我看看问题在那,先谢谢了.
int SpeedArr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300,};
int NameArr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300,};
int OpenSerial(char *pDev)
{
int fd;
// fd = open(pDev, O_RDWR | O_NDELAY);
fd = open(pDev, O_RDWR);
if (-1 == fd)
{
perror("open()");
return -1;
} else {
return fd;
}
}
int SetSerialSpeed(int fd, int nSpeed)
{
int i;
int Status;
struct termios Opt;
tcgetattr(fd, &Opt);
for (i = 0; i < sizeof(SpeedArr) / sizeof(int); i++)
{
if (nSpeed == NameArr)
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, SpeedArr);
cfsetospeed(&Opt, SpeedArr);
Status = tcsetattr(fd, TCSANOW, &Opt);
if (Status != 0)
{
perror("(tcsetattr)");
return -1;
}
tcflush(fd, TCIOFLUSH);
}
}
return 0;
}
int SetSerialParity(int fd, int nDatabits, int nStopbits, int nParity)
{
int Status;
struct termios Opt;
if (tcgetattr(fd, &Opt) != 0)
{
perror("SetupSerial Fail");
return -1;
}
// Opt.c_cflag &= ~CSIZE;
// Opt.c_cflag &= ~CRTSCTS;
// Opt.c_cflag |= CLOCAL;
// Opt.c_cflag |= CREAD;
// Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Set Serial Raw
// Opt.c_cflag &= ~(ICANON | ECHOE); //Set Serial Raw
// Opt.c_lflag &= ~OPOST;
(怀疑是这里的问题)
Opt.c_iflag&=~(IGNBRK|IGNCR|INLCR|ICRNL|IUCLC|IXANY|IXON|IXOFF|INPCK|ISTRIP);
Opt.c_iflag|=(BRKINT|IGNPAR);
Opt.c_oflag&=~OPOST;
Opt.c_lflag&=~(XCASE|ECHONL|NOFLSH);
Opt.c_lflag&=~(ICANON|ISIG|ECHO);
Opt.c_cflag|=(CLOCAL|CREAD);
switch (nDatabits)
{
case 7:
Opt.c_cflag |= CS7;
break;
case 8:
Opt.c_cflag |= CS8;
break;
default:
fprintf(stderr, "Unsupported data size\n");
return -1;
}
switch (nParity)
{
case 'n':
case 'N':
Opt.c_cflag &= ~PARENB;
Opt.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
Opt.c_cflag |= (PARODD | PARENB);
Opt.c_iflag |= INPCK;
break;
case 'e':
case 'E':
Opt.c_cflag |= PARENB;
Opt.c_cflag &= ~PARODD;
Opt.c_iflag |= INPCK;
break;
case 's':
case 'S':
Opt.c_cflag &= ~PARENB;
Opt.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr, "Unsupported parity\n");
return -1;
}
switch (nStopbits)
{
case 1:
Opt.c_cflag &= ~CSTOPB;
break;
case 2:
Opt.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr, "Unsupported stop bits\n");
return -1;
}
if (nParity != 'n')
{
Opt.c_iflag |= INPCK;
}
tcflush(fd, TCIFLUSH);
Opt.c_cc[VTIME] = 150;
Opt.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSANOW, &Opt) != 0)
{
perror("SetupSerial 3");
return -1;
}
return 0;
}
int GetAlarmInfoCmd(void)
{
int ret;
BYTE sbuff[14];
sbuff[0] = 0x48;
sbuff[1] = 0x4E;
sbuff[2] = 0x54;
sbuff[3] = 0x09;
sbuff[4] = 0x1F;
sbuff[5] = 0x07;
sbuff[6] = 0xFF;
sbuff[7] = 0xFF;
sbuff[8] = 0xFF;
sbuff[9] = 0xFF;
sbuff[10] = 0xFF;
sbuff[11] = 0x15;
sbuff[12] = 0x44;
sbuff[13] = 0x7A;//后面加一个字节0x0D也不行
ret = write(HDSerialFd,&sbuff,14);
if(ret < 0)
{
PrintMsg("Send get alarm cmd failed!\n");
return -1;
}
return ret;
}
int main(void)
{
//........
fd = OpenSerial(SERIAL_PATH);
if (fd > 0) {
SetSerialSpeed(fd, 9600);
SetSerialParity(fd, 8, 1, 'N');
}
//.....
while(1)
{
GetAlarmInfoCmd();
sleep(1);
ret = read(fd,buff,len);//一直读不到数据.ret =0;
}
}
用串口调试助手发送命令48 4e 54 09 1f 07 ff ff ff ff ff 15 44 7a可以收到数据,程序却收不到.
先设置断点看看,如果程序没问题(主要是波特率)那就要查查是不是硬件电路的问题了,我前段时间也遇到这个问题,是多接了个232导致的
你先在网上下个虚拟串口配合proteus仿真下看看就知道了。想深入学习,推荐网站www.pubembed.com,咨询QQ:104262585
你带的是linux系统啊?你下载一个能直接用的调试工具,看看那个系统上的串口驱动是否可用。
周工开发网-淘宝店开张!
三款周立功99元开发板,非常适合初学者,资料丰富价格便宜。
EasyARM1138 (内嵌USB仿真器的Cortex-M3开发板)
EasyARM2103 (arm7内核开发板)
EasyFPGA030 (FPGA开发板)
详情如下:
www.01zg.com
open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
要加一个 NONBLOCK 上去,要不然,你的程序一直等到一整块数据到
UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
你应该在Windows下用串口测试软件测试先一下,如果你用的是STC的51,还可以直接用
STC的烧写软件进行串口测试,里面有个“串口调试助手”,先保证下位机程序和电路没问
题了再去看你的上位机程序是不是有问题。
在linux下收发数据,打开串口 是成功的,就是向写命令后没有数据返回,读不到数据。
按照仪器厂家提供的通信协议,我用串口调试助手向串口发送命令48 4e 54 09 1f 07 ff ff ff ff ff 15 44 7a后有数据返回,但代码读不到数据。,我想请教下串口设置中termios结构一般怎么设置,和具体硬件相关么?
楼上
如果是32位机,那么一个int是4个字节 sizeof(int) = 4;
有没有超限要看他用的是什么系统,不过,上Linux多半是32位的CPU
int SpeedArr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300,};
int NameArr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300,
38400, 19200, 9600, 4800, 2400, 1200, 300,};
数组超出范围了!
115200=0x1c200
大于定义的INT 的0xffff。