void main_form::remoteDataIncoming() //QSocketNotifier监测到出口有数据读就自动调用该函数(一般不会丢数据)
{
u_char a;
read(m_fd,read_buf,33);
for(a=0;a<33;a++)
qDebug("%u",read_buf[a]);
}
if((event->timerId()==m_timerId)&&(RADIO_STAR==0))//条件判断(如果是定时器1时间到 且 没有进行广播,就正常采样)
{ //定时器1
i++;if(i>=6)i=1;
w_length=MONITOR_LENGTH;w_cid=MONITOR_CID;w_chksum=w_length+w_cid+addr[i];
u_char w_data_buf[3]={w_length,w_cid,w_chksum};
bzero(read_buf,sizeof(read_buf));
sendAddr(addr[i]);
//usleep(1000); //bukequede
sendData(w_data_buf);
usleep(2000);
remoteDataIncoming(0x02);
qDebug("i:%d",i);
}
这样好一点,主要是在sendData后延时一下……让单片机反应一下,应该是单片机的事,以前都是单片机的发送的灯都不亮,只要亮就能收到数的,这个应该是单片机的问题,不过也不能这么说,因为用小程序时就没有问题,到这就有问题了,是不是发的有问题呢,这个很难说了……
还是用Qt的事件结构吧,这样也可以,如果确定这样不行的话再改吧……又想起来了,小程序测试时没有进行清零,清零一下看看:
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h> /*系统类型定义*/
#include <sys/stat.h> /*系统状态定义*/
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <string.h>
struct termios serialAttr;
const char data[]={0x02,0x01,0x05};
int spaceSerialPort(int m_fd) //空校验
{
int fd=m_fd;
serialAttr.c_cflag |= PARENB | PARODD | CMSPAR;//ou
if(tcsetattr(fd, TCSANOW, &serialAttr) !=0) //配置立刻起作用
{
perror("serial error");
return -1;
}
return 0;
}
int markSerialPort(int m_fd) //
{
int fd=m_fd;
serialAttr.c_cflag |= PARENB | CMSPAR;//ou
serialAttr.c_cflag &= ~PARODD;
if(tcsetattr(fd, TCSANOW, &serialAttr) !=0) //配置立刻起作用
{
perror("serial error");
return -1;
}
return 0;
}
int main(void)
{
int fd = -1;
const char *devName = "/dev/ttySAC1";
char read_buf[33];
fd = open(devName, O_RDWR|O_NONBLOCK);
if (fd < 0) {
return -1;
}
memset(&serialAttr, 0, sizeof serialAttr);
serialAttr.c_iflag = IGNPAR;
serialAttr.c_cflag = B9600 | HUPCL | CS8 | CREAD | CLOCAL ;
serialAttr.c_cflag |= PARODD; //JI
serialAttr.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSANOW, &serialAttr) != 0) {
return -1;
}
while(1)
{
printf("hw\n");
char addr = 0x02;
char i = 0;
bzero(read_buf,sizeof read_buf);
markSerialPort(fd);
write(fd, &addr, 1);
usleep(1000);
spaceSerialPort(fd);
write(fd, data, 3);
usleep(90000);
read(fd,read_buf,sizeof read_buf);
for(i=0;i<33;i++)
{
printf("%x",read_buf[i]);
}
printf("\n");
}
}
添加62行所示……
================================================================================================================
2012年10月23日20:23:03:终于露出马脚了,看读到的信息:
[root@FriendlyARM mark]# ./a
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
233014694194567891921718192021222324253233342003738394041130
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
233014694194567891921718192021222324253233342003738394041130
hw
233014694194567891921718192021222324253233342003738394041130
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
233014694194567891921718192021222324253233342003738394041130
hw
000000000000000000000000000000000
hw
000000000000000000000000000000000
hw
233014694194567891921718192021222324253233342003738394041130
hw
233014694194567891921718192021222324253233342003738394041130
hw
233014694194567891921718192021222324253233342003738394041130
hw
233014694194567891921718192021222324253233342003738394041130
总结:原来也会丢数据呀,看来我得把小程序调好了先!
========================================================================================================================
2012年10月23日21:43:42:很无奈呀,怎么调都会丢包,就暂且归为 串口丢包 吧,搜搜前辈们是怎么解决的!
2.http://topic.csdn.net/u/20120820/12/7011b84f-1fc6-42c6-82a3-5b027ba90eca.html?10181
3.http://zhidao.baidu.com/question/265254259
4.http://zhidao.baidu.com/question/147480744
======================================================================================================================
2012年11月4日15:27:05:我想到单片机没有在串口中断之后关闭中断造成的:
输出结果:
[root@FriendlyARM mark]# ./c
hw
2210929299456789c0111213141516171819202122c8252627282982
hw
2210929299456789c0111213141516171819202122c8252627282982
hw
2210929299456789c0111213141516171819202122c8252627282982
hw
2210929299456789c0111213141516171819202122c8252627282982
hw
2210929299456789c0111213141516171819202122c8252627282982
hw
2210929299456789c0111213141516171819202122c8252627282982
尼玛,还真是没有关中断引起的错误,害死人。。。。。。。。。。。。。。。。。。。。。。。。
MCU程序:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define slaveaddr 0x02 //从机地址
#define radioaddr 0xff //广播地址
uchar buf[10];
uchar tab2[]={0x02,0x21,0x00,0x92,0x09,0x29,0x09,0x04,0x05,0x06,0x07,0x08,0x09,0xc0,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0xc8,0x25,0x26,0x27,0x28,0x29,130};
uchar request_flag = 0;
uchar radio_flag = 0;
sbit LED=P3^7;
/延时函数///
void Delayus(int t)
{
while(t--);
}
//发送一个字节函数///
void send_byte(unsigned char dat) //send one byte
{
//RDE = 1;//485为发送
SBUF = dat;
while(!TI);//等待发送结束
TI=0;//发送完毕后标志位清零
//RDE = 0;//485为接收
}
//串口初始化
void UartInit()
{
//RDE=0;/*保持为接收状态*/
TMOD=0X21; //定时器T1设为方式2
TH1= 0xfd; //波特率设为9600
TL1= 0xfd; //
SCON=0xd0; //方式3允许接收
SM2 = 1;
TR1=1;
EA=1;
ES=1;
}
/主函数///
void main()
{
uchar i=0,k = 0;
UartInit();
while(1)
{
if(radio_flag == 1)
{
SM2=0;//转为一对一通信
for(i=0;i<5;i++)
{
//send_byte(i);
while(!RI);
if(RB8==1)
return;
buf[i] = SBUF;
RI = 0;
}
if((buf[2]==0x00)&&(buf[3]==0x01)&&(buf[4]==0x0a))
{
LED=0;
}
else if((buf[2]==0x01)&&(buf[3]==0x01)&&(buf[4]==0x0b))
{
LED=1;
}
ES = 1;
SM2=1;
radio_flag = 0;
}
else if(request_flag == 1)
{
SM2=0;//转为一对一通信
for(i=0;i<3;i++)
{
//send_byte(i);
while(!RI);
if(RB8==1)
return;
buf[i] = SBUF;
RI = 0;
}
if((buf[0]==0x02)&&(buf[1]==0x01)&&(buf[2]==0x05))
{
for(k=0; k<33; k++)
{
send_byte(tab2[k]);//发送一数据
//Delayus(30);
}
}
ES = 1;
SM2=1;
request_flag = 0;
}
}
}
串口中断服务子程序
void uart() interrupt 4
{
uchar rc;
if(RI==1)//接到数据置标志位
{
RI=0;//接收完毕标志位置0
rc=SBUF;//保存缓存数据
if(radioaddr == rc)
{
ES = 0;
//request_flag = 1;
radio_flag = 1;
}
else if(slaveaddr == rc)
{
ES = 0;
request_flag = 1;
}
}
}
/end/
重点在:ES = 0;OR ES = 1;