单片机串口调试丢包验证过程记录_已解决

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:很无奈呀,怎么调都会丢包,就暂且归为 串口丢包 吧,搜搜前辈们是怎么解决的!

1.ARM串口通讯丢包问题

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

5.传送数据之后,校验。丢失就重发。

6.降低发送速度2边协同!

7.适当 降低 波特率 试试看  通信 双方的 配合 很重要

8.一般 电脑可以设置的 最高 128000

======================================================================================================================

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;

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值