野人的笔记 https://bbs.21ic.com/?79434 [收藏] [复制] [RSS]

日志

51读写cf卡

已有 1452 次阅读2005-11-26 17:26 |个人分类:单片机设计|系统分类:单片机


    因工程需要存储大量的数据,今天参考参考德国人的一个基于avr的cf控制程序,移植了一个51上面使用的cf驱动程序。


程序如下cf.c文件:







#include <reg52.h>


#include "cf.h"


unsigned char CFReadSector(unsigned long lba, unsigned char *buf)
//######################################################
{
 unsigned int i;
 unsigned char by;
 unsigned char *p;


 if(lba>=maxsect) return 1; //sectornumber too big


 if(CFWaitReady()) return 1;
 
// CFWriteAdr(CF_FEATURES,0); //Brauch ich nicht
 CFWriteAdr(CF_SECCOUNT,1);   //einen Sektor lesen


 by=(unsigned char)lba;
 CFWriteAdr(CF_LBA0,by);            //D7..0
 by=(unsigned char)(lba>>8);
 CFWriteAdr(CF_LBA1,by);            //D15..8
 by=(unsigned char)(lba>>16);
 CFWriteAdr(CF_LBA2,by);            //D23..16
 by=(unsigned char)(lba>>24);
 by&=0x0F;              //Nur die vier unteren Bits g黮tig
 by|=0xE0;              //LBA-Mode Drive0
 CFWriteAdr(CF_LBA3,by);          //D27..24
 CFWriteAdr(CF_STACOM,CF_READ_SEC);


 if(CFWaitDrq()) return 2;


 p=buf;
 
 for(i=0; i<BYTE_PER_SEC; i++)
  {
   *p++=CFReadAdr(CF_IO);
  }


 return 0;
}


//######################################################
unsigned char CFWriteSector(unsigned long lba, unsigned char *buf)
//######################################################
{
 unsigned int i;
 unsigned char by;
 unsigned char *p;


 if(lba>=maxsect) return 1; //sectornumber too big
 if(CFWaitReady()) return 1;
 
 CFWriteAdr(CF_SECCOUNT,1);   //einen Sektor schreiben


 by=(unsigned char)lba;
 CFWriteAdr(CF_LBA0,by);            //D7..0
 by=(unsigned char)(lba>>8);
 CFWriteAdr(CF_LBA1,by);            //D15..8
 by=(unsigned char)(lba>>16);
 CFWriteAdr(CF_LBA2,by);            //D23..16
 by=(unsigned char)(lba>>24);
 by&=0x0F;              //Nur die vier unteren Bits g黮tig
 by|=0xE0;              //LBA-Mode Drive0
 CFWriteAdr(CF_LBA3,by);          //D27..24
 CFWriteAdr(CF_STACOM,CF_WRITE_SEC);


 if(CFWaitDrq()) return 2;


 p=buf; //using a pointer is much faster than indexing buf


 for(i=0; i<BYTE_PER_SEC; i++)
  {
   CFWriteAdr(CF_IO,*p++);
  }


 return 0;
}


//######################################################
unsigned char CFIdentify(void)
//######################################################
{
// unsigned long maxtracks;
// unsigned int heads,sectors_per_track;
 unsigned int i;
 union Convert *cv;


 if(CFWaitReady()) return 1;


 CFWriteAdr(CF_STACOM,CF_IDENTIFY);


 if(CFWaitDrq()) return 2;
 
 for(i=0; i<BYTE_PER_SEC; i++) dirbuf=CFReadAdr(CF_IO);


// this is the only information we need
 cv=(union Convert *)&dirbuf[14];
 maxsect=(unsigned long)cv->ui << 16;         // number of sectors
 cv=(union Convert *)&dirbuf[16];
 maxsect+=cv->ui;


 return 0;
}


//######################################################
unsigned char CFWaitReady(void)
//######################################################
{
 unsigned char by;


 by=CFReadAdr(CF_STACOM);
 if(by & 0x01) return 1; //Fehler !


 do
  {
   by=CFReadAdr(CF_STACOM);
   by&=0xF0;
  
  }while(by!=0x50); //Endlosschleife m鰃lich !
 
 return 0;
}


//######################################################
unsigned char CFWaitDrq(void)
//######################################################
{
 unsigned char by;


 by=CFReadAdr(CF_STACOM);
 if(by & 0x01) return 1; //Fehler !


 do
  {
   by=CFReadAdr(CF_STACOM);
   by&=0xF8;
  
  }while(by!=0x58); //Endlosschleife m鰃lich !
 
 return 0;
}







cf.h文件如下:







#ifndef __COMPACT_FLASH_H 
#define __COMPACT_FLASH_H


#define CF_REGBASE 0x1000
//CF register adresses
#define CF_IO  0 //IO-Port
#define CF_FEATURES 1 //Errors Out / Features In
#define CF_SECCOUNT 2 //Sectorcount
#define CF_LBA0  3 //LBA 0-7
#define CF_LBA1  4 //LBA 8-15
#define CF_LBA2  5 //LBA 16-23
#define CF_LBA3  6 //LBA 24-27
#define CF_STACOM 7 //Status Out / Command In


//ATAPI commands
#define CF_READ_SEC 0x20
#define CF_WRITE_SEC    0x30
#define CF_IDENTIFY     0xEC


#define CFReadAdr(a)  (*(unsigned char volatile xdata *)(CF_REGBASE + a))
#define CFWriteAdr(a,d) (*(unsigned char volatile xdata *)(CF_REGBASE + a) = d)


//prototypes
extern unsigned char CFReadSector(unsigned long lba, unsigned char *buf);
extern unsigned char CFWriteSector(unsigned long lba, unsigned char *buf);
extern unsigned char CFIdentify(void);
extern unsigned char CFWaitReady(void);
extern unsigned char CFWaitDrq(void);


#endif







    此文件导出3个关键函数CFIdentify,CFReadSector,CFWriteSector,分别进行检测,读取扇区,写入扇区。实际应用中需要注意确定CF卡的51访问地址定义:#define CF_REGBASE 0x1000







一个参考的连接图,如果看不清楚,点击放大哈



 


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (1 个评论)

回复 CBQ 2006-4-9 00:05

野人大侠,您好!

请将AVR控制CF卡的程序和连接图发给我,好吗?谢谢!e_cbq@163.comrube.cheng@gmail.com