连续写sd卡总是会在20多个小时后死机

2019-07-21 01:26发布

我在做将485收到的数据以625k大小的txt文件存到sd卡里面,可是总是死机。

#define  __SHOW_SD_PROCEDURE__

FIL File;
FIL* CreateNewFile(void)   //创建新文件
{
char FileName[16];
static int i = 0;
int mount = 0;     //为了检查哪里出错设置的标志位
    int open  = 0;    //同上
int lseek = 0;    //同上
    u8    res_mount  = 1;   //同上
u8    res_open   = 1;       //同上
u8    res_lseek  = 1;         //同上
char  CntBuf[64];

RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;

RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
    RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct);

sprintf(FileName, "%02d%02d%02d%02d.txt",
       RTC_DateStruct.RTC_Date,
       RTC_TimeStruct.RTC_Hours,
       RTC_TimeStruct.RTC_Minutes,
       RTC_TimeStruct.RTC_Seconds);

loop: exfuns_init(); //为fatfs相关变量申请内存  
 usmart_dev.init(72);

 my_mem_init(SRAMIN); //初始化内部内存池
 SD_InitializeCards();
while(res_mount!=0)

if(mount > 5) 
{
sprintf(CntBuf, "f_mount = %d", res_mount);
            LCD_ShowString(60, 50, 210, 16, 16, CntBuf); 
goto loop;
}
res_mount = f_mount(fs[0], "0:", 1);
}   //注册工作区
while(res_open!=0)
{
if(open > 5) 
{
sprintf(CntBuf, "f_open = %d", res_open);
            LCD_ShowString(60, 80, 210, 16, 16, CntBuf); 
goto loop;
}
   res_open = f_open(&File, FileName, FA_OPEN_ALWAYS | FA_WRITE);
}
while(res_lseek!=0)
{
if( lseek > 5) 
{
sprintf(CntBuf, "f_lseek = %d", res_lseek);
            LCD_ShowString(60, 110, 210, 16, 16, CntBuf); 
goto loop;
}
   res_lseek = f_lseek(&File, 0);


#ifdef __SHOW_SD_PROCEDURE__
LCD_ShowString(60, 140, 210, 16, 16, FileName);
#endif

LCD_ShowString(60, 170, 210, 16, 16, " CreateNewFile = ");    
LCD_ShowNum(200, 170, ++i, 8, 16);  

return &File;
}

#define  FILE_BLOCK_CNT   100

int main(void) 
 {  
char  CntBuf[64];
int   FileBlockCnt = 0;
int   FileCnt      = 0;
FIL  *SDFile       = NULL;
     u8    res_close  = 1;
//-------------------------------
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
//-------------------------------  
delay_init(168);                                    // 初始化延时函数
uart_init(115200);                                // 初始化串口波特率为115200
LED_Init();                        // 初始化LED 
  LCD_Init();                        // LCD初始化  
RS485_Init(115200);                            // 初始化RS485串口2
    RTC_Set_WakeUp(RTC_WakeUpClock_CK_SPRE_16bits, 0);  // 配置WAKE UP中断,1秒钟中断一次
// //-----------------------------
    while(1)  
{
  
  if(QueueFullWithData)    // QueueFullWithData是在485中断里面设置的缓存区,当存够6400的数以后一次性赋值给QueueFullWithData
  {  
if(FileBlockCnt == 0)
   {
   SDFile = CreateNewFile();
   }
   
f_write(SDFile, QueueFullWithData, QUEUE_SIZE, (UINT*)&bw);
delay_ms(10);
  
LCD_ShowString(60, 200, 210, 16, 16, "Saved File Block = ");    
LCD_ShowNum(200, 200, ++FileBlockCnt, 8, 16);  

QueueFullWithData = NULL; 
  
  
   if(FileBlockCnt == FILE_BLOCK_CNT)   //在同一个文件内写100次,写够625k后关闭该文件,然后创建新文件
   {
while(res_close!=0)
{
res_close = f_close(SDFile);
   sprintf(CntBuf, "f_close = %d", res_close);
                     LCD_ShowString(60, 230, 210, 16, 16, CntBuf); 
}

FileBlockCnt = 0;
   LCD_ShowString(60, 260, 210, 16, 16, "Saved File Cnt = ");    
       LCD_ShowNum(200, 260, ++FileCnt, 8, 16);  
   } 
  }
}
}
 
在网上搜了以后说是SD时钟太快了,就把SD时钟改成了1Mhz,原来的是48Mhz,是将SDIO_TRANSFER_CLK_DIV改成0x30,可是还是会出错
if(SDCardInfo.CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1||SDCardInfo.CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)
{
clkdiv=SDIO_TRANSFER_CLK_DIV+2; //V1.1/V2.0卡,设置最高48/4=12Mhz
}else clkdiv=SDIO_TRANSFER_CLK_DIV; //SDHC等其他卡,设置最高48/2=24Mhz
SDIO_Clock_Set(clkdiv); //设置时钟频率,SDIO时钟计算公式:SDIO_CK时钟=SDIOCLK/[clkdiv+2];其中,SDIOCLK固定为48Mhz 
//errorstatus=SD_SetDeviceMode(SD_DMA_MODE); //设置为DMA模式
errorstatus=SD_SetDeviceMode(SD_POLLING_MODE);//设置为查询模式
能帮忙看一下是什么问题造成的吗?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
kekehuhu
1楼-- · 2019-07-21 03:58
测试了三天,一直没有出现问题,在485.c里面添加了一段程序
[mw_shl_code=c,true]f(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR其实就是清除标志 USART_ReceiveData(USART2); //读DR }[/mw_shl_code]

可是如果溢出的话是进不到if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)   ,等于加上上面的这段程序是进不去的 ,可是现在好了,也不知道是为什么
正点原子
2楼-- · 2019-07-21 05:47
局部数组有点大.
试试不处理485数据,直接程序生成一个固定的字符串,模拟485收到的数据,往SD卡写入,持续20小时,看看有无问题.
wgh1990
3楼-- · 2019-07-21 08:00
换张好点的卡试试 看看时间是不是都在20多小时就死机 还有在原来已经死机过的卡上把原来的文件用覆盖方式继续测试20小时 如果卡死时间提前  那么就用好点的卡
kekehuhu
4楼-- · 2019-07-21 13:30
 精彩回答 2  元偷偷看……
kekehuhu
5楼-- · 2019-07-21 19:10
回复【2楼】正点原子:
---------------------------------
原子哥,局部数组64也大吗?我后来把定义的标志位的变量都放到了函数外面成全局变量
kekehuhu
6楼-- · 2019-07-21 20:55
 精彩回答 2  元偷偷看……

一周热门 更多>