ch376字节写多余30字节出错

串口方式操作CH376,用字节写的方式,调用标准库,当大于30字节时,写入失败.第一次写入返回0XIE,用继续写命令后就等不来中断,返回FA. 即使小于30字节时,能写入成功,但隔几百个字节就出错,出错一行后又正确.可大家帮助

在CH376产生中断的时候,串口会自动的发送一个中断标志给单片机。所以在查询中断的函数中要清除单片机的串口接收标志。


我是这样做的. 等中断状态,如果收到低电平,通过串口读取中断状态码.然后返回状态码.如果等不到低电平,过大约十多秒返回FA


UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) /* 以字节为单位从当前位置读取数据块 */ { UINT8 s; xWriteCH376Cmd( CMD2H_BYTE_READ ); mDelayS( 30 ); xWriteCH376Data( (UINT8)ReqCount ); mDelayS( 30 ); xWriteCH376Data( (UINT8)(ReqCount>>8) ); mDelayS( 30 ); // xEndCH376Cmd( ); if ( RealCount ) *RealCount = 0; while ( 1 ) { s = Wait376Interrupt( ); if ( s == USB_INT_DISK_READ ) { mDelayS( 30 ); s = CH376ReadBlock( buf ); /* 从当前主机端点的接收缓冲区读取数据块,返回长度 */ mDelayS( 30 ); xWriteCH376Cmd( CMD0H_BYTE_RD_GO ); mDelayS( 30 ); // xEndCH376Cmd( ); buf += s; if ( RealCount ) *RealCount += s; } /* else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */ else return( s ); /* 错误 */ } } 调用这个函数,如果第一次调用 s = CH376ReadBlock( buf ); 返回的字节数与请求字节数相同,写就成功.如果不相同,调用xWriteCH376Cmd( CMD0H_BYTE_RD_GO ); 后应该等中断状态,结果总是等到超时返回FA


看一下你的查询中断函数和读数据函数


UINT8 CH376GetIntStatus( void ) /* 获取中断状态并取消中断请求 */ { UINT8 s; xWriteCH376Cmd( CMD01_GET_STATUS ); // mDelayS(100); s = xReadCH376Data( ); // xEndCH376Cmd( ); return( s ); } UINT8 Wait376Interrupt( void ) //等待中断 { UINT32 i; for(i=0;i<1200000;i++) { if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); } return( ERR_USB_UNKNOWN ); } UINT8 xReadCH376Data( void ) //读数据 { UINT32 i; UINT8 dat; for ( i = 0; i < 500000; i ++ ) { if ( U2STAbits.URXDA ==1 ) { while(U2STAbits.URXDA) //接收缓冲器中是否有数据位 { dat =U2RXREG; //? if (U2STAbits.OERR==1) //串口错误 { U2STAbits.OERR=0; return 0; } // return( dat ); /* 串口输入 */ } return( dat ); /* 串口输入 */ } } return( 0 ); } /* 查询CH376中断(INT#低电平) */ UINT8 Query376Interrupt( void ) { if (CH376_INT_STAT ==1) return FALSE; else return TRUE; }


用下面的查询中断函数测试一下

/* 查询CH376中断(INT#低电平) */ UINT8 Query376Interrupt( void ) {

if ( U2STAbits.URXDA ==1 ) { while(U2STAbits.URXDA) //接收缓冲器中是否有数据位 { dat =U2RXREG; //? }

if (CH376_INT_STAT ==1) return FALSE; else return TRUE; }


大于30字节还是不行,这个问题可以先不解决。下面这个问题比较急 usb Connect Success usb start save can1 data DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,1 ? ^ DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11, ? ^DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11 ? DATA 11,11,11,11,11,11,11,11 DATA 11,11,11,11,11,11,11,11 usb end save can1 data usb Remove Success 正常应该每行一样,但出现有错行现象。


字节写函数 UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) { UINT8 s; xWriteCH376Cmd( CMD2H_BYTE_WRITE ); mDelayS( 30 ); xWriteCH376Data( (UINT8)ReqCount ); // mDelayS( 30 ); xWriteCH376Data( (UINT8)(ReqCount>>8) ); // mDelayS( 30 );

if ( RealCount ) *RealCount = 0; while ( 1 ) { s = Wait376Interrupt( ); if ( s == USB_INT_DISK_WRITE ) { // mDelayS( 100 ); s = CH376WriteReqBlock( buf ); if (s < ReqCount) { Nop() ; 此处设置断点,不存在s < ReqCount 的时候 ???????????????????? 实际请求的数据如上显示,每行为一次字节写操作 } // mDelayS( 100 ); xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); // xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); //mDelayS( 10 ); buf += s; if ( RealCount ) *RealCount += s; } else if ( s == USB_INT_SUCCESS ) return( s ); /* 结束 */ else return( s ); /* 错误 */ } } ========================================================= 请求字节写函数,请求写入的频率为1S LED_LOG=~LED_LOG; s = show_save_var_can1(tmp); s = CH376ByteWrite( tmp, s, NULL );

s1=CH376ByteWrite( tmp, 0, NULL ); if ((s !=USB_INT_SUCCESS )||(s1 !=USB_INT_SUCCESS )) { Nop() ; ??????????????此处理设置断点查看,不存在返回不成功的时候,但实际写入到 记录本中的数据如下,存在乱行现象 } =============================================================


这个问题是你快扇区造成的 我也遇到过 你用的是字节写入吧 其实你出现错误的位置有一部分数据写在了前一个扇区,一个写在后一个扇区 后一扇区写入的时候缺少了CMD0H_BYTE_WR_GO这条命令 补上就不会出现问题了 你先试着弄 弄不好我可以略微的帮你一下


这个问题是你跨扇区造成的 我也遇到过 你用的是字节写入吧 其实你出现错误的位置是因为你有一次操作写入的数据有一部分数据写在了前一个扇区,一部分写在后一个扇区 后一扇区写入的时候缺少了CMD0H_BYTE_WR_GO这条命令 补上就不会出现问题了 你先试着弄 弄不好我可以略微的帮你一下


aa


还是不好用啊,麻烦再指点下啊


我的程序里有再次写入啊,就是这个命令xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); 请求字节写函数,请求写入的频率为1S LED_LOG=~LED_LOG; s = show_save_var_can1(tmp); s = CH376ByteWrite( tmp, s, NULL );

s1=CH376ByteWrite( tmp, 0, NULL ); if ((s !=USB_INT_SUCCESS )||(s1 !=USB_INT_SUCCESS )) { Nop() ??????????????此处理设置断点查看,不存在返回不成功的时候,但实际写入到 记录本中的数据如下,存在乱行现象 }

从这个问号处看没有写入失败的情况啊. if ( RealCount ) *RealCount = 0; while ( 1 ) { s = Wait376Interrupt( ); if ( s == USB_INT_DISK_WRITE ) { // mDelayS( 100 ); s = CH376WriteReqBlock( buf ); if (s < ReqCount) { Nop() 此处设置断点,不存在s < ReqCount 的时候 ???????????????????? 实际请求的数据如上显示,每行为一次字节写操作 } // mDelayS( 100 ); xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); // xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); //mDelayS( 10 ); buf += s; if ( RealCount ) *RealCount += s; } else if ( s == USB_INT_SUCCESS ) return( s ); /* 结束 */ else return( s ); /* 错误 */ 从这个问号处看写入的字节数和请求的字节完都是一样的啊


[Emot]6[/Emot]


不知道你们的问题解决没有,我感觉我的问题和你的类似: 问题是: 写的时候一次只能写30个字节以下的数据,一次 写30个字节以上就会超时返回FA

如果 i值28,29,30,31的时候 能读出来28个字符,且不报错顺利通过 如果i值不为这几个数,则要么等待时间特别长(8s左右),要么返回FA超时 一般情况下,小于27的数等待时间特别长,但能读出来,大于32的数,返回FA超时,屏蔽掉报错程序mStopIfError( s );后,同样只可以读出来28个字节的数据

用51单片机(W79E227)的异步串口方式(串口1)


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