u盘文件读写模块写32次就停了
我采用的是扇区方式写数据,每次写一个扇区,连续写N次,当N大于32时就不行,小或等于32次一般都成功写入U盘
怎么回事啊 高手指点一下 调了好几天了[Emot]1[/Emot]
您好,您使用的单片机是什么型号的?主频多少?采用什么样的接口方式和模块通信的?如果您用的是高速的单片机,可能是您的速度太快造成的,应该在每一个扇区结束以后延时10US左右的时间再发下一个写扇区的命令.如果是普通的51单片机则可以不延时.
此号封存
我使用的单片机是MSP149的,主频是32768的,用的串口三线制 用发送同步码的方式和模块通信,我的延时肯定够的啊 因为我每次就写一个扇区,循环写N次,如果延时不够那么前面的32次怎么都能成功呢
void USB_WRITE( char sector )
{
unsigned char ii;
strcpy( mCmdParam.Open.mPathName, filename ); /* 原文件名 文件名,该文件在C51子目录下 */
ii = ExecCommand( CMD_FileOpen, MAX_PATH_LEN ); Delay_ms( 100 ); /* 打开文件,输入参数置为最大值,省得再计算参数长度 */
if ( ii == ERR_MISS_DIR || ii == ERR_MISS_FILE )
while(1);
for(int b=0;b {////////
mCmdParam.Locate.mSectorOffset=0xFFFFFFFF;
ii = ExecCommand( CMD_FileLocate, sizeof( mCmdParam.Locate.mSectorOffset));
Delay_ms( 10 ); /* 打开文件,输入参数置为最大值,省得再计算参数长度 */
mCmdParam.Write.mSectorCount = sector; /* 写入一个扇区512字节 */
buffer = DATA_BUF1;
ii = ExecCommand( CMD_FileWrite, 1 ); Delay_ms(3 ); /* 向文件写入数据 */
mStopIfError( ii );
}///////////
mCmdParam.Close.mUpdateLen = 1;
ii = ExecCommand( CMD_FileClose, 1 ); Delay_ms( 100 );
mStopIfError( ii );
}
这人很懒,什么都没留下
程序应该没有问题,程序能监控到32次以后返回的状态码是多少吗?N的值是否程序中已经定义?还有就是不需要每次移动文件指针,可以在打开文件以后移动一次,循环里面就不要在移动了.最好监控一下32次以后程序运行到哪了,返回的状态码是多少.这样有利于分析.
此号封存
返回的状态码还是正确的 是1E
程序好像是运行到发送子函数里面
void mSendByte (unsigned char c)
{

TXBUF1=c;
while((UTCTL1&0x01)==0); //等待一次发送完毕
}
每次打断几乎都是停在
while((UTCTL1&0x01)==0); //等待一次发送完毕
这条语句上

这人很懒,什么都没留下
您好:
程序是没有道理停在发送子函数里面的,除非您没有给它的发送缓冲区送数据,这样才会停在while((UTCTL1&0x01)==0);这里。
为方便我们了解情况及时处理问题,您可以拨打我们技术支持直拨电话:025-52638373,或者留下号码我们联系您。
^-^……
上午有事出去了 是不是模块的问题啊 可我现在手里就一块模块 也不能换了试试 我电话13596172463
我本来是每次写一个扇区的嘛,然后我在单片机开辟了一个512字节的数组DATA_BUF1;然后每次扇区方式写数据的时候 都会用语句 buffer = DATA_BUF1;将数组的首地址给指针buffer 的 ,我观察前面32次指针的变化是正常的(从452——652),然后如果我写的次数一旦大了 ,超过32次,出错然后打断程序发现buffer 指针所指的地址是数组之外的,一般都大于652
这人很懒,什么都没留下
您好,这个和模块没有关系的,因为返回给你的状态码是正确的,表明要接收您的数据,但是您的数据没有送给模块,却停在了发送数据的地方,应该是你外围单片机程序的问题,虽然你给缓冲区地址了,但是我还是建议您重点查一下您的程序,实在找不到问题在哪里,您可以将您的程序发到我们的技术支持信箱,tech@wch.cn
此号封存
哦好的 谢谢啊 我先仔细查找一下
这人很懒,什么都没留下
不行了 我看不出来啊 改了还是这样的啊 我把程序发给你帮我看看吧 万分感谢!!
这人很懒,什么都没留下
好的!那您把您的程序发送到tech@wch.cn,我们会及时给您回复.
此号封存
我发过了 我的邮箱是 penglili190412@163.com
这人很懒,什么都没留下

感谢您的指导!
您说

在程序中:
else if ( status == USB_INT_DISK_WRITE ) /* 正在向U盘写数据块,请求数据写入 */
{
DIR_430_USB ;//打开430发往模块的使能端
for( i = 0;i<64;i++)
{
mSendByte( *buffer ); /* 依次发送64字节的数据 */
buffer ++; /* 发送的数据来自外部缓冲区 */
}
DIR_USB_430 ;//使能模块发往430,因为模块每接收64字节数据就会向单片机发送一个IE
Delay_ms( 25 );// 此处要将延迟去掉,否则会造成程序跳出不去接收要写入的数据
uart1_Rx_flg=1;//进入解析函数的标志
}

//////////////////////////////////////////////////////////////////////////////////////////////////

但那个延时是必须的,因为我采用的是中断接收,如果在发送完64字节然后又马上回到while(1)函数中去判断status 那肯定还没有接收到。 正确的做法应该是要在接收中断函数中去判断什麽时候接收完毕,然后进入while(1)函数,可是接收的时候USB375模块每次发送的数据长度都不一样,结束字节也不一样,我没有办法判断什麽时候接收完毕,所以只好在单片机发送完数据或者命令之后加延时。

您说的程序跳不出去,但是我的接收是中断方式啊,只要有数据到来自动进去中断服务程序的啊 !


这人很懒,什么都没留下
在你的程序中:
uart1_Rx_flg=1;

//================处理数据传输,直到操作完成才退出 =================//
//===============根据模块返回的状态参数进行相应操作================//
while ( 1 ) //处理数据传输,直到操作完成才退出
{
if (uart1_Rx_flg)
{
uart1_Rx_flg= 0 ; //取数标志清0
nRX1_Len=0;
status = UART1_RX_BUF[0]; // 等待模块完成操作并返回操作状态

你是使用uart1_Rx_flg的值来判断程序是否往下执行,但是仔细分析一下,会发现这样做有不妥之处。
程序一上来就是将UART1_RX_BUF[0]的值赋给status,但是你的UART1_RX_BUF[0]的值能确定是从模块内部接收过来的吗?没有可能是你没有接收之前的数组的默认值0吗?这样的话岂不是认为是操作成功了?
而在我们的例程中status = mRecvByte( );可以断定是模块发送过来的状态码。
/* 从CH375模块接收一个字节数据 */
unsigned char mRecvByte( )
{
unsigned char c;
while ( RI == 0 );
c = SBUF;
RI = 0;
return( c );
}

所以,像刚才在电话中我们工程师给你讲到的那样,需要首先在中断中判断模块发送过来的数据存放入你的接收数组UART1_RX_BUF[]中,然后再做相应处理才可。
还有就是:
unsigned char UART1_RX_BUF[20]={0x00}; //接收数据缓冲区
尽量将此缓冲区增大到32,避免可能的不够用的情况。

^-^……
我下午想了一下,因为430中断接收和51单片机不一样,它是自动跳入中断的,本来是单片机发送完命令之后就等待接收,接收完了就处理,但是现在我还没有好的方案去判断什麽时候接受完毕
//=====================================================================================//
//函数:void UART1RX (void)
//参数:无
//功能:接收中断函数,将接受的数据存放在UART1_RX_BUF[]中
//=====================================================================================//

#pragma vector=USART1RX_VECTOR
__interrupt void UART1RX (void)
{
if(RXBUF1==USB_INT_DISK_WRITE )//我主要只想区分出是不是写命令IE到来
uart1_Rx_flg=1;
else
{
UART1_RX_BUF[nRX1_Len]=RXBUF1;
nRX1_Len+=1;
if (nRX1_Len==??)//我不知道长度是多少,而却这个长度看起来好像并不是一个固定的数吧
uart1_Rx_flg=1;
}
}
这人很懒,什么都没留下
或者您这样做,改成查询的方式,每次查询接收标志,类似于我们例子程序中的那样,不用中断的方式,这样程序好写一点,否则用中断也可以,只是稍微麻烦点.
此号封存
只有登录才能回复,可以选择微信账号登录