||
因工程需要存储大量的数据,今天参考参考德国人的一个基于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
一个参考的连接图,如果看不清楚,点击放大哈
野人大侠,您好!
请将AVR控制CF卡的程序和连接图发给我,好吗?谢谢!e_cbq@163.com或rube.cheng@gmail.com