微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > avr的SD卡基本读写程序(二)

avr的SD卡基本读写程序(二)

时间:11-13 来源:互联网 点击:
SD卡读写子程序

硬件平台:atmega8L最小系统
硬spi(sd卡的初始化采用了io口模拟时序,因为在实验中发现要使用较低的速率才能稳定的初始化)
软件开发平台:ICC-AVR version 6.31a
硬件配置:atmega8L 内部8m时钟
sandisk 128m sd卡

几个基本的子程序及其介绍:

1.io口模拟spi,实现数据发送,在初始化时使用
void iodatatransfer(unsigned char iodata)
{
unsigned char num,b;
num=0x80;
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
//SD_Write|=(1SD_Write&=~(1if(iodata&num)
SD_Write|=(1else
SD_Write&=~(1delay_4ms();//4ms
WDR();//feed the dog
//SD_Write&=~(1SD_Write|=(1delay_4ms();//4ms
if(num>0x01)
num=num>>1;
}
}

2.io口模拟spi,实现数据读取,在初始化时使用
unsigned char iodataread(void)
{
unsigned char data,temp,b;
data=0;
temp=0;
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
SD_Write&=~(1delay_4ms();//4ms
WDR();//feed the dog

SD_Write|=(1temp=SD_READ;
temp&=0x10;//to maintain the pb.4 bit(data_in)
WDR();//feed the dog
if(temp)
{
data|=0x01;
}
if(b<7)
{
data=data<1;//
}
delay_4ms();//4ms
WDR();//feed the dog
}
return data;
}

3.io口模拟spi,实现指令发送及读响应,在初始化时使用
unsigned char iocmd(unsigned char *cmd)
{
unsigned temp,a,timeout;
temp=0xff;
timeout=0;
// Raise chip select -----/ss=1
SD_Disable();
WDR();//feed the dog

// Send an 8 bit pulse
iodatatransfer(0xff);
WDR();//feed the dog
// Lower chip select
SD_Enable();
for(a=0;a<6;a++)
{
iodatatransfer(*cmd++);
WDR();
//transfer cmd in io_mode
}
while(temp==0xff)//
{
WDR();//feed the dog
temp=iodataread();
if(timeout++>100)
{
break;
}
}
WDR();//feed the dog
return(temp);//the respone of the byte_write_operation
}

4.硬spi读数据
unsigned char Read_Byte_SD(void)
{
char Byte;
//SD_Enable();
SPDR=0xff;
while(!(SPSR&(1Byte=SPDR;
return(Byte);
}

5.硬spi写数据
void Write_Byte_SD(char Byte)
{
//SD_Enable();
SPDR=Byte;
while(!(SPSR&(1}

6.硬spi写指令及读响应
unsigned char Write_Command_SD(char *CMD)
{
unsigned char a;
unsigned char tmp=0xff;
unsigned char Timeout=0;
// Raise chip select -----/ss=1
SD_Disable();
// Send an 8 bit pulse
Write_Byte_SD(0xFF);

// Lower chip select
SD_Enable();
//Send the 6 byte command
for(a=0;a<0x06;a++)
{
Write_Byte_SD(*CMD++);
}
//Wait for the response
while(tmp==0xff)//
{
tmp=Read_Byte_SD();
if(Timeout++>100)
{
break;
}
}
//for some reason we need to delay here
//delay_1ms();
return(tmp);//the respone of the byte_write_operation
}

7.初始化
unsigned char SDInit(void)
{
unsigned char a,b,retry,erroetoken;
unsigned char CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};//cmd0
// Set certain pins to inputs and others to outputs
// Only SPI_DI (data in) is an input
//SD_Direction_REG==ddrb
SD_Direction_REG&=~(1SD_Direction_REG|=(1SD_Direction_REG|=(1SD_Direction_REG|=(1//SD_Direction_REG|=(1SD_Disable();
//We need to wait for the SD_Direction_REG to be ready
for(a=0;a<200;a++)
{
WDR();//feed the dog
nop();
nop();
};
delay_1ms();

SD_Disable();//
iodatatransfer(0xff);
WDR();//feed the dog
//return 0;///////////

retry=0;
SD_Enable();
while((erroetoken=iocmd(CMD))!=0x01)//
{
WDR();
//serial(erroetoken);
if(retry++>200)
{ //fail and return
return 1;
}
}
//return 0;///////////

//Send the 2nd command
retry=0;
CMD[0]=0x41;
CMD[5]=0xFF;
while(erroetoken=iocmd(CMD)!=0x00)
{
WDR();
if (retry++>200)
{
return 2;
}
}

//Set the SPI bus to full speed
SPCR=0x50;
SPSR|=0x01;
//Raise Chip Select
SD_Disable();
return 0;
}

8.设置每次读的字节数
char SD_set_length(unsigned int length)
{
unsigned char retry;
//Command to set the block length;
char CMD[]={0x50,0x00,0x00,0x00,0x00,0xFF}; //cmd16

CMD[3]=((length&0xFF00)>>8);//
CMD[4]= (length&0x00FF);
while(Write_Command_SD(CMD)!=0)//
{
WDR();
if (retry++>200)
{
return 1;
}
}
SD_Disable();
return 0;
}

9.write 512 bytes to a given sector from a Byte_byte_long Buffer
unsigned char SD_write_sector(unsigned long addr,unsigned char *Buffer,unsigned int Bytes)
{
unsigned int a;
unsigned char retry,temp;
//Command to read a block;
char CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF};//cmd24
CMD[1]=((addr&0xFF000000)>>24);
CMD[2]=((addr&0x00FF0000)>>16);
CMD[3]=((addr&0x0000FF00)>>8);
CMD[4]=(addr&0x000000FF);
//Send the write command

while(Write_Command_SD(CMD)!=0)
{
if (retry++>50)
{
return 1;
}
}
//Send the start byte
Write_Byte_SD(0xfe);
//Read off all the bytes in the block
for(a=0;a{
Write_Byte_SD(*Buffer++);
}
while((temp=Read_Byte_SD())&0x10);
//serial(temp);//according to p101 of datasheet
if((temp&0x0f)!=0x05)
return 2;
//Read CRC byte
while(SD_READ&0x10);//detect if data_in pb.4 is still busy(high)

// Set SD_Chip_Select to high
SD_Disable();
//SEI(); //re-enable

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top