AVR技术william hill官网
直播中

zhangtaotao71

12年用户 393经验值
擅长:嵌入式技术
私信 关注
[AVR问答]

ATmage16 proteus 仿真MMC卡

上源程序:
#include
#include
typedef unsigned int uint;
typedef unsigned char uchar;
uchar CMD0[6]={0x40,0x00,0x00,0x00,0x00,0x95};//命令0
uchar CMD1[6]={0x41,0x00,0x00,0x00,0x00,0xff};//命令1
uchar CMD24[6];
uchar CMD17[6];
uchar a[512];
void delay(uint i)
{
    while(i--);
}
void spi_init(void)
{  
    DDRB|=BIT(4);//CS片选
DDRB|=BIT(5);//MOSI
DDRB&=~(1<<6);//MISO
DDRB|=BIT(7);//SCK
SPCR=0x12;//设置SPI
SPSR=0x00;
PORTB=0xff;
SPCR|=(1<<6);//使能SPI
}
uchar send(uchar dat)//发送数据
{   
    uchar dat1=0;
    SPDR=dat;
while(!(SPSR&(1<<7)));//等待数据发送完成
dat1=SPDR;
return dat1;
}
void SPI_HIGH(void)
{
    SPCR|=(0< SPSR|=(1< }
uchar send_cmd(uchar *CMD)//发送命令
{
   uchar i,dat;
   PORTB|=(1<<4);//CS=0;
   send(0xff);//一定要有这一步,否则可能初始化不能成功
   PORTB&=~(1<<4);
   send(CMD[0]);
   send(CMD[1]);
   send(CMD[2]);
   send(CMD[3]);
   send(CMD[4]);
   send(CMD[5]);
   do
   {
    dat=send(0xff);//读回命令的响应
i++;
   }while((i<200)&&(dat==0xff));
   return dat;
}
uchar MMC_init(void)//MMC卡的初始化
{
  uchar n=0xff,j=0xff;//MMC卡的初始化可能要多次发送命令才会初始化成功
  uint m;
  PORTB&=~(1<<4);
  for(m=0;m<0x0f;m++)
  {
     send(0xff);
  }//上电发送大于74个时钟 16*8
  do
  {
     n=send_cmd(CMD0);//发送CMD0复位,响应R1=0x01
  m++;
  }while((m<200)&&(n!=0x01));
  m=0;
  do
  {
    j=send_cmd(CMD1);//发送CMD1激活卡,响应R1=0x00
    m++;
  }while((m<2000)&&(j!=0x00));
  PORTB|=(1<<4);
  return n;//初始化成功
}
uchar write_byte(void)//
{  
    uint i;
uchar dat;
    CMD24[0]=0x58;
CMD24[1]=0x00;
CMD24[2]=0x00;
CMD24[3]=0x00;
CMD24[4]=0x00;
CMD24[5]=0xff;
send_cmd(CMD24);//命令只要发送一次就可了当初始化成功的时候
send(0xff);//填充时钟
send(0xfe);//发送起始令牌
for(i=0;i<512;i++)
{
     send(0x02);
}
send(0xff);
send(0xff);//两个字节的校检字节
dat=send(0xff);//接受到0x05表示成功
return dat;
}
void read_byte(void)//读数据块命令成功
{
    uint i;
    CMD17[0]=0x40+17;
CMD17[1]=0x00;
CMD17[2]=0x00;
CMD17[3]=0x00;
CMD17[4]=0x00;
CMD17[5]=0xff;
send_cmd(CMD17);//发送读数据命令的时候,只要发一次,不能多发否则会出现各种问题
while(send(0xff)!=0xfe);//等待第一个数据令牌
for(i=0;i<512;i++)
{
     a[i]=send(0xff);
}
send(0xff);
send(0xff);//两个字节的校检字节

}
void main(void)
{
    DDRD=0xff;
DDRC=0xff;
PORTD=0xff;
    DDRA=0xff;
PORTA=0xff;
spi_init();
PORTD=MMC_init();
PORTC=write_byte();
read_byte();
PORTD=a[510];
     while(1);
}
已经测试过正确

回帖(1)

hua2002

2013-10-31 10:02:20
{:20:}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分