[b]文字[/b][b]我用的是这种批量写的方式,每次写到1867的时候就会出一行乱码,然后隔23行再出一行乱码。[/b]

for(i = 0;i < flash_js;i++) { // wdt_reset(); unsigned char Spi_Rx_Buffer[40]; uint8_t j; uint32_t temp = 0; if(i>1866) {LCD_Blight_ON;} temp = i; spiflashRead(temp*256+1,34, Spi_Rx_Buffer); for(j = 0;j < 34;j++) { DF_buffer[j*2] = (Spi_Rx_Buffer[j] & 0xf0)>>4; DF_buffer[j*2+1] = Spi_Rx_Buffer[j] & 0x0f; } total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[0],DF_buffer[1],DF_buffer[2],DF_buffer[3],DF_buffer[4],DF_buffer[5],DF_buffer[6],DF_buffer[7],DF_buffer[8],DF_buffer[9]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[10],DF_buffer[11],DF_buffer[12],DF_buffer[13],DF_buffer[14],DF_buffer[15],DF_buffer[16],DF_buffer[17],DF_buffer[18],DF_buffer[19]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[20],DF_buffer[21],DF_buffer[22],DF_buffer[23],DF_buffer[24],DF_buffer[25],DF_buffer[26],DF_buffer[27],DF_buffer[28],DF_buffer[29]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[30],DF_buffer[31],DF_buffer[32],DF_buffer[33],DF_buffer[34],DF_buffer[35],DF_buffer[36],DF_buffer[37],DF_buffer[38],DF_buffer[39]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[40],DF_buffer[41],DF_buffer[42],DF_buffer[43],DF_buffer[44],DF_buffer[45],DF_buffer[46],DF_buffer[47],DF_buffer[48],DF_buffer[49]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x%x%x",DF_buffer[50],DF_buffer[51],DF_buffer[52],DF_buffer[53],DF_buffer[54],DF_buffer[55],DF_buffer[56],DF_buffer[57],DF_buffer[58],DF_buffer[59]); total += sprintf(FileDataBuf + total,"%x%x%x%x%x%x%x%x\r\n",DF_buffer[60],DF_buffer[61],DF_buffer[62],DF_buffer[63],DF_buffer[64],DF_buffer[65],DF_buffer[66],DF_buffer[67]); /* 将二制制数据格式为一行字符串 */ mFlushBufferToDisk(1); /* 强制刷新缓冲区,因为系统要退出了, 所以必须强制刷新 */ // _delay_ms(20); }

/* 将准备写入U盘的零碎数据进行集中缓冲,组合成大数据块时再通过CH376真正写入U盘 */ /* 这样做的好处是: 提高速度(因为大数据块写入时效率高), 减少U盘损耗(U盘内部的内存寿命有限,不宜频繁擦写) */ void mFlushBufferToDisk(UINT8 force) /* force = 0 则自动刷新(检查缓冲区中的数据长度,满则写盘,不满则暂时放在缓冲区中), force != 0 则强制刷新(不管缓冲区中的数据有多少都写盘,通常在系统关机前应该强制写盘) */ { UINT8 s; if (force) { /* 强制刷新 */ s = (total + DEF_SECTOR_SIZE - 1) / DEF_SECTOR_SIZE; /*将缓冲区中的字节数转换为扇区数(除以DEF_SECTOR_SIZE), 长度加上DEF_SECTOR_SIZE-1用于确保写入最后的零头数据 */ if (s) { /* 有数据 */ s = CH376SecWrite(FileDataBuf, s, NULL); /*以扇区为单位向文件写入数据,写入缓冲区中的所有数据,含最后的零头 */ mStopIfError(s); /* 有些U盘可能会要求在写数据后等待一会才能继续操作,所以,如果在某些U盘中发生数据丢失现象,建议在每次写入数据后稍作延时再继续 */ _delay_ms(1); /* 写后延时,可选的,大多数U盘不需要 */ memcpy(FileDataBuf, &FileDataBuf[total &~(DEF_SECTOR_SIZE - 1)], total &(DEF_SECTOR_SIZE - 1)); /*将刚才已写入U盘的零头数据复制到缓冲区的头部 */ total &= DEF_SECTOR_SIZE - 1; /*缓冲区中只剩下刚才已写入U盘的零头数据, 继续保留在缓冲区中是为了方便以后在其后面追加数据 */ } NewSize = CH376GetFileSize(); /* 读取当前文件长度,如果没有零头数据,那么文件长度是DEF_SECTOR_SIZE的倍数 */ if (total) NewSize -= DEF_SECTOR_SIZE - total; /* 以扇区为单位,有零头数据,计算出真正的文件长度(有效数据的长度) */ CH376WriteVar32(VAR_FILE_SIZE, NewSize); /*将正确的当前文件长度写入CH376内存 */ // printf("Current file size is %ld\n", NewSize); s = CH376SecWrite(FileDataBuf, 0, NULL); /* 写0长度,实际是刷新文件长度,将CH376内存中当前文件长度信息真正写入U盘或者SD卡中 */ mStopIfError(s); s = CH376SecLocate(0xFFFFFFFF); /* 重新回到原文件的尾部,以扇区为单位,所以会忽略文件尾部的零头数据, 下面如果再写入数据将覆盖尾部零头数据,不过该零头数据有一份副本保留在缓冲区中,所以请放心 */ mStopIfError(s); } else if (total >= sizeof(FileDataBuf) - DEF_SECTOR_SIZE) { /* 缓冲区中的数据快要满了,所以应该先将缓冲区中的原有数据写入U盘 */ s = CH376SecWrite(FileDataBuf, (UINT8)(total / DEF_SECTOR_SIZE), NULL); /* 将缓冲区中的字节数转换为扇区数(除以DEF_SECTOR_SIZE) ,最后的零头数据先不管,以扇区为单位向文件写入数据 */ mStopIfError(s); memcpy(FileDataBuf, &FileDataBuf[total &~(DEF_SECTOR_SIZE - 1)], total &(DEF_SECTOR_SIZE - 1)); /* 将刚才未写入U盘的零头数据复制到缓冲区的头部 */ total &= DEF_SECTOR_SIZE - 1; /* 缓冲区中只剩下刚才未写入U盘的零头数据 */ /* 注意,此处U盘或者SD卡中的文件长度仍然是以前的值,即此时突然断电,那么虽然物理上的数据已在U盘/SD卡中,但文件长度没有包括这些数据,导致常归应用程序无法取得数据 */ } }