关于petitfatfs的移植问题

    Petit FatFs是FatFs的简版,可以移植到8位单片机上,我此次试验是在PIC16F877A上移植了这种文件系统,用于管理SD卡中的txt文件内容的读写。其中SD卡的驱动程序在另一篇博客中有所介绍。

   我在这次试验遇到的问题和想法简述于下,希望对过客有所帮助,也望高手赐教。


   1.文件系统中,最为根本的就是底层驱动程序的编写,一般没有必要去过多研读系统本身,而且也很难读懂,我们只想调用接口函数,将自己的驱动函数程序挂在接口函数内。然后调用接口函数实现目标即可。

   2.要用文件系统给sd卡里的txt文件写东西,必须先给文件写入需要文件大小的空格,因为在官方的说明中给文件写东西,不能扩大文件的大小。不知道我是不是错了,如果我没错的话,我感觉这是小文件系统的缺陷。它不能创建文件,也不能更改文件的大小。所以,我给sd卡里的txt文件预先写好东西,拿单片机在给文件写入东西的时候,会把原有的东西覆盖。如果我在文件里什么都不写,那么单片机也写不进去任何东西。如果我在文件里输入许多空格,那么单片机就会写入东西,文件指针移动的操作也可以实现。这是经过试验的。

   3.在对sd卡的读写需要一定的时序,在没有移植文件系统的时候,我以前的程序可以对sd卡正常操作。但是挂到系统上之后,程序就会卡在某个循环语句处。于是我在程序中用串口发送信息的方式检测程序卡在了那里。

     开始我在检测点发送的东西较少,会频繁的卡在一个地方,最后误打误撞,我将发送的内容增加,却调试成功,我也不知道是什么原因,于是在卡点放了一个延迟函数。程序便好用了起来。

    一下是接口函数的书写:

 /*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for Petit FatFs (C)ChaN, 2009      */
/*-----------------------------------------------------------------------*/
#include <pic.h>/*Platform dependent macros and functions needed to be modified */
#include<string.h>
#include "pff.h"//include "integer.h"
#include "diskio.h"//include "integer.h"
#define CS RC2
#define _XTAL_FREQ 12000000
/*************************************usart*************************************/
void init_pic_usart(void)
{
     TRISC7=1; 
     TRISC6=1;  
     RCSTA=0x90;//1001 0000,SPEN=1,serial port enabled.CREN=1,
     TXSTA=0X24;//0010 0100,TX9=0,select 8 bits transmission.
           //TXEN=1,transmit enabled .
       //SYNC=0,Asynchronous mode.
       //BRGH=1,High speed.
     SPBRG=77;      
}
void usart_send_byte(CHAR data)
{
  TXREG=data;
  while(!TRMT); 
}
void usart_send_str(const UCHAR *buff,UCHAR EnterFlag)//send of string,and then line feed
{
 UINT i;
 UINT len=strlen(buff);//count the string length
 for(i=0;i<len;i++)
    {
  usart_send_byte(buff[i]);
 }
 if(1==EnterFlag)
    {
  usart_send_byte(0x0a);
  usart_send_byte(0x0d);//line feed
 }
}
/************************************SPI***********************************************/
void init_pic_spi()
{
 TRISC2=0;//CS 
 TRISC3=0;//SCK
 TRISC4=1;//SDI
 TRISC5=0;//SDO
 SSPSTAT=0X80;
 //SMP=1,input data sampled at the end of data output time
 //CKE=1;transmit occurs on transition from idle to active clock
 SSPCON=0X30;
 //SSPM3-SSPM0 0000 SPI master mode ,clock=fosc/64
 //CKP=1 idle state for clock high level
 //SPEN=1 enable serial port
 //WCOL=0 no collision
 //falling edge of SCK transmit data
}
void write_command(UCHAR command,DWORD arguement,UCHAR CRC)
{
 UCHAR arg[4],i=0; 
 arguement=arguement<<9;
 arg[0]=(UCHAR)(arguement>>24);
 arg[1]=(UCHAR)(arguement>>16); 
 arg[2]=(UCHAR)(arguement>>8);
 arg[3]=(UCHAR)(arguement);//four 0x00
 SSPBUF=command|0x40;
 while(!BF);
 for(i=0;i<4;i++)
 {
  SSPBUF=arg[i];
  while(!BF);
 }
 SSPBUF=CRC;
 while(!BF);
}
UCHAR receive_response()
{
 UCHAR a=0;
 while(a++<100)
 {
  SSPBUF=0XFF;//if we want to read a data,must send first,we send complete,receive comlete
  while(!BF);//receive flag
  if(0x01==SSPBUF)
  {
   break;
  }
  else if(0x00==SSPBUF)
  {
   break;
  }
  else if(0xfe==SSPBUF)
  {
   break;
  }
  else if(0xff!=SSPBUF)
  {
   break;
  }
 }
 return SSPBUF; 
}
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive                                                 */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (void)
{
 DSTATUS stat;
 // Put your code here
 stat=RES_ERROR;
 int i=0;
 do   
 { 
  CS=1;//disable sd card 
  for(i=0;i<15;i++) //more than 74 clock pules,15*8=120,FOR YU JU CUO LE
  { 
   SSPBUF=0XFF;
   while(!BF);
  }
  CS=0; 
  SSPBUF=0XFF;
  while(!BF);//8 clock
  write_command(0x00,0,0x95);  
 }while(receive_response()!=0x01);
 CS=1; 
 SSPBUF=0XFF;//8 clock pules
 while(!BF);//untile now ,reset completed
 
 do
 {
  CS=0;
  __delay_us(10);
  write_command(0x01,0,0xff);
 }while(receive_response()!=0x00); 
 CS=1;
 __delay_us(10);
 SSPBUF=0XFF;//8 clock pules
 while(!BF);//untile now ,SD card has came into SPI work mode 
 stat=RES_OK;
 return stat;
}
/*-----------------------------------------------------------------------*/
/* Read Partial Sector                                                   */
/*-----------------------------------------------------------------------*/
DRESULT disk_readp(
 BYTE* dest,   /* Pointer to the destination object */
 DWORD sector,  /* Sector number (LBA) */
 WORD sofs,   /* Offset in the sector */
 WORD count   /* Byte count (bit15:destination) */
)
{
 DRESULT res;
 // Put your code here
 res=RES_ERROR;
 UINT i=0;

 do
 { 
  CS=0;
  SSPBUF=0XFF;
  while(!BF);//8 clock
  write_command(0x11,sector,0xff);//CMD17:the command of read data block,address must be integer multiple of 512
 }while(receive_response()!=0x00); __delay_us(100);//usart_send_str("haha,here",1);//must have 

当时便卡在了此处,我的测试发送程序是usart_send_str("haha,here",1)时,程序便畅行无阻,于是我在此次加了延时函数__delay_us(100)。
 while(receive_response()!=0xfe);
 for(i=0;i<sofs;i++)
 {
  SSPBUF=0XFF;
  while(!BF);//skip sofs bytes
 }
 for(i=0;i<count;i++)//read count byte
 { 
  SSPBUF=0XFF;
  while(!BF);//skip sofs bytes
  *(dest+i)=SSPBUF;
 }
 for(i=0;i<512-sofs-count;i++)
 {
  SSPBUF=0XFF;//skip reminder bytes
  while(!BF); //abandon two CRC bytes
 }
 SSPBUF=0XFF;
 while(!BF); //abandon two CRC bytes
 SSPBUF=0XFF;
 while(!BF); 
 CS=1; 
 SSPBUF=0XFF;
 while(!BF);//8 clock
 res=RES_OK;
 return res;
}
/*-----------------------------------------------------------------------*/
/* Write Partial Sector                                                  */
/*-----------------------------------------------------------------------*/
DRESULT disk_writep(
    const BYTE* buff,  /* Pointer to the data to be written, NULL:Initiate/Finalize write operation */
 DWORD sc  /* Sector number (LBA) or Number of bytes to send */
)
{   /*buff=0,sc=0 finish the write function */
   /*buff=0,sc!=0 init write sector */
   /*buff!=0,sc=!0 normal write */
 DRESULT res;
 WORD bc;//typedef unsigned short WORD;
 static WORD wc;//init with 0 and keep the value last time
 res=RES_ERROR;//init res
 if(buff)
 {      /* Send data bytes */
  bc=(WORD)sc;
  while(bc&&wc)
  {     /* Send data bytes to the card */
   SSPBUF=*buff++;
   while(!BF);
   wc--;bc--;
  }
  res=RES_OK;
 }
 else
    {
  if(sc)/* Initiate sector write process */
  { 
   do
   {
    CS=0;
    SSPBUF=0XFF;
    while(!BF);//8 clock pules
    write_command(0x18,sc,0xff);//CMD24
   }while(receive_response()!=0x00);
   SSPBUF=0XFF;
   while(!BF);
   SSPBUF=0XFE;
   while(!BF);//head data
   wc=512;       /* Set byte counter */
   res=RES_OK;
  }
  else
  { /* Finalize sector write process */
   bc=wc+2;
   while(bc--) 
   {
    SSPBUF=0x00; //if the pointer is not on the sector boundary,left bytes should filled with 0
    while(!BF);/* Fill left bytes and CRC with zeros */
   } 
   while(0x05==(receive_response()&0x1F));
   while(receive_response()!=0xFF);
   res = RES_OK;//!= prior to &&,while sdcard is busy ,dataout is low
   CS=1;
   SSPBUF=0xff;
   while(!BF);
  } 
 }
 return res;
}


  

   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值