ch375释放缓冲期区有时无效

单片机工作在8MHZ范围,当上位机下传数据后单片机接收到数据后,执行释放缓冲命令有时候无效,要连续执行几次才有效。有时候一次就有效! 更重要的问题是,当上位机发送多个数据包的时候单片机断当无法正常接收获丢包的时候,单片机会停止工作,单片机内中断全部停止!我的程序设计是无论上位机是否有数据传过来无论是否传送的数据正确单片机程序都自动运行! 请给点建议?

还有就是由于ch375释放缓冲有时有校有时无效,弄得我的上位机于单片机通讯时常断开, 通讯程序也不能一一对应,单片机端要定期的多次执行释放375的缓冲,才能通讯! 当单片机端上传数据后,在检查有无数据下次传时居然检查到有数据下传,而下传的数据竟然是我要上传给pc的数据? 请问这是为什么???

能不能做到这样:单片机定时检查有无数据下传,如果有则处理,如果没有则不管继续执行自身的程序,单片机上传数据后,检查数据是否取走如果取走继续发送,如果没有则等待(直到超时)

从你反映的现象来看,你的单片机程序可能有问题。CH375怎么会让你的单片机停止工作呢?CH375做为一个外部器件,所有的动作都是MCU来控制的。不会去影响你的MCU的。 您还是仔细检查一下你的单片机程序吧。 至于丢包的问题,你需要注意,你的MCU中断触法方式是什么?沿触发还是电平触发?CH375有中断,就会产生低电平,直到获取中断状态才取消,如果MCU为沿触发方式,则有可能丢中断,比如在处理其他程序时把中断关闭了。 你怎么来判断释放缓冲区无效的?另外,你怎么去检测有没有数据下传的?你的做法可能是错误的,才认为CH375有问题。 CH375应该不会出现你说的这些问题,你还是按照我的提问,把你的程序所处理的方法列出来,方便我们帮你检查问题。


按照楼主的描述的现象来判断,个人认为可能是你程序的流程上面除了问题,或者中断处理上面有问题,例如在读取CH375数据的时候又来别的中断把读取数据给打断导致出现问题。 还有楼主说的“单片机定时检查有无数据下传,如果有则处理,如果没有则不管继续执行自身的程序,单片机上传数据后,检查数据是否取走如果取走继续发送,如果没有则等待(直到超时)”。前面部分是没问题的,但是后面部分建议你不要使用超时,因为你写到CH372数据之后,这个时候,实际在等待计算机取走,建议计算机尽量快的取走数据。采用一直等待计算机取走数据的方式比较好点。或者超市时间设置长点。


对于375单片机端我没有用任何的外部中断,检查pc有无数据下传是定时轮询检查!因为我的程序设计要求不是非得每次都把数据上传,而是在可以上传的时候就上传mcu忙碌的时候就不上传,上传的数据实际上是没有什么用的!所以就造成了pc端定时向mcu发送要数据的请求,而mcu有可能接受他的要求上传数据,有可能不理他!或直接清除375的缓冲! 现在有时候通讯会断开我到不是很着急!按下复位键就好了!最头疼的就是当mcu与pc通讯中断3秒以上的时候mcu就停止工作!(通讯彻底断开)3秒钟以下就没有问题(通讯会自动重新连接好)。一会我把我的程序发上来请指教一下


MCU停止工作?是程序跑飞了还是停止工作了?你好好查查MCU的程序,看看是不是RAM溢出了。估计这个需要做实验验证。


volatile unsigned char usb_ptr(void)reentrant//中断查询 { volatile unsigned char inter=0; inter=0; choose_138(6); data_control(0); delay_us(); *A0_ml=0x22;//写入0x22命令 delay_us(); inter=*A0_sj; choose_138(4); data_control(0); *A0_sj=0;

if(inter ==0x02) { inter=0; return 3;//批量端点2接收到数据 } else if(inter==0x0A) { inter=0; return 4;//批量端点2发送完数据 } else { inter=0; return 0; } } void write_usb_unlock(void)reentrant//释放当前的缓冲区 { choose_138(6); *A0_ml=0X23; delay_us(); choose_138(4); data_control(0); } void write_usb(unsigned char len, unsigned char xdata * pcdata)reentrant { unsigned char xh0=0; unsigned char fssj; choose_138(6); *A0_ml=0x2B;//启动读写控制端(上传缓冲区2) *A0_sj=len;//写入长度 for(xh0=0;xh0<=len-1;xh0++)//写入数据 { choose_138(4); data_control(0); fssj= *(pcdata+xh0); choose_138(6); *A0_sj=fssj; } choose_138(4); data_control(0); } volatile unsigned char read_usb(unsigned char xdata * cjsj1) { volatile char xh1=1; volatile unsigned char dtcount=0; volatile unsigned char jssj=0; choose_138(6);//ch375 data_control(0); delay_us(); *A0_ml=0x22;//写入0x22命令 delay_us(); if(*A0_sj==0x02)//接收到批量数据 { choose_138(6); *A0_ml=0X28; delay_us(); dtcount=*A0_sj;//usb对读写控制写的操作,数据长度不是从0开始 choose_138(4); data_control(0); for(xh1=1;xh1<=dtcount;xh1++) { choose_138(6); jssj=*A0_sj;//获取数据 choose_138(4); *(cjsj1+xh1)=jssj; *(cjsj1+0)=xh1; } return (unsigned char)(1); } else { *(cjsj1+0)=0x0; return (unsigned char) (2); } } void T1_INT(void) interrupt 3 using 1 { EA=0; TH1=0; TL1=0; if(T_data_bz[0]==1) { T_data[0]=T_data[0]+1; //每个10.17分之一秒 自加1 T_data1[0]=T_data1[0]+1; } EA=1; } void main( void ) { AUXR=0x3; CLK_DIV=0x0; choose_138(6); //设置厂商识别码 *A0_ml=0x12;//命令 *A0_sj=jiami1; *A0_sj=jiami2; *A0_sj=jiami1; *A0_sj=jiami2; delay_us(); //工作模式设定 *A0_ml=0x15 ; *A0_sj=0x02;//内部固件模式 delay_us(); choose_138(4);//选择628128 data_control(0); IE=0x0;//关闭所有中断 TMOD=0X11;//00010001; IP=0X8; TL1=0;TH1=0; delay(1500); choose_138(4); data_control(0); IAP_CONTR|=0X40; //复位 choose_138(4); data_control(0); EA=1; ET1=1; TR1=1; for(pxh0=0;pxh0<=(*tdzs)-1;pxh0++) { write_usb_unlock(); write_usb_unlock(); ............................................ if(read_usb(jsdata)==1 && *jsdata!=0)//电脑传送过来了数据 { //其中没有任何死循环语句 .......... } ELSE { write_usb_unlock(); } } }


volatile unsigned char read_usb(unsigned char xdata * cjsj1) { volatile char xh1=1; volatile unsigned char dtcount=0; volatile unsigned char jssj=0; choose_138(6);//ch375 data_control(0); delay_us(); *A0_ml=0x22;//写入0x22命令 delay_us(); if(*A0_sj==0x02)//接收到批量数据 { choose_138(6); *A0_ml=0X28; delay_us(); dtcount=*A0_sj;//usb对读写控制写的操作,数据长度不是从0开始 choose_138(4); data_control(0); for(xh1=1;xh1<=dtcount;xh1++) { choose_138(6); jssj=*A0_sj;//获取数据 choose_138(4); *(cjsj1+xh1)=jssj; *(cjsj1+0)=xh1; } return (unsigned char)(1); } else { *(cjsj1+0)=0x0; return (unsigned char) (2); } }这是检查pc有无数据下传的程序!这段程序非常的差劲,原因是当初调试的时候,当执行了dtcount=*A0_sj;语句时dtcount确实从375芯片中得到了pc端下传的数据长度,但是当执行了 for(xh1=1;xh1<=dtcount;xh1++) { choose_138(6); jssj=*A0_sj;//获取数据 choose_138(4); *(cjsj1+xh1)=jssj; *(cjsj1+0)=xh1;//添加获取长度的语句 } 这些语句用以获取pc下传的数据内容后,dtcount自动变成了0,数据长度又丢了,找不到原因所以又在循环中加上了 *(cjsj1+0)=xh1;这条语句,重新循环计算数据长度(这个问题的原因我一直没有找到)。 函数的返回值也有问题,有时候明明没有接受到数据,愣是返回了1(接受到数据的标志),而查看数据时确实没有数据。所以我觉得问题是出自这个函数!在我的程序中只有一个内部的定时中断开着,而且是mcu加电后一直都开着,永远不会关,当通讯中断时定时中断都停了。


只有登录才能回复,可以选择微信账号登录