⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc.c

📁 SD卡读写源程序 环境为IAR 硬件平台MEGA16
💻 C
字号:
#include "mmc.h"
/******************************************************************************
                    FileName: mmc.c
                  
                    Description: MMC/SD卡驱动   

          Author:WangWeimin       Version : V1.0         Date: 2009/01/31
所引用的与硬件有关的函数如下:

                            void SPI_MasterInit(void)
                
                            U08 mmc_read_byte (void)
                
                            void mmc_write_byte (U08 _Byte_)
                
                            void uart_puthex(U8 hex)
                
                            void uart_putchar (U8 c)
                
                            void uart_putstring(U8 *s)
                    宏定义:
                                            
                            nop()
                
                            uart_innit()
                
                            MMC_Disable() 
                
                            MMC_Enable()
*******************************************************************************/
/*******************************************************************************/
/************************以下宏定义与硬件有关***********************************/
/*****************************移植须注意****************************************/
/*******************************************************************************/
/******************************************************************************/
//############################################################################
void SPI_MasterInit(void)
//############################################################################
{
spi_init();
}
//############################################################################
U08 mmc_read_byte (void)
//############################################################################
{
return (spi_read());
}
//############################################################################
void mmc_write_byte (U08 _Byte_)
//############################################################################
{
spi_write(_Byte_);
}

//############################################################################
//############################################################################
void uart_putchar (U8 c)
//############################################################################
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = c;
}
//############################################################################
void uart_puthex(U8 hex)
//############################################################################
{
U8 data[16]={"0123456789ABCDEF"};
uart_putchar('0');
uart_putchar('X');
uart_putchar(data[hex/16]);
uart_putchar(data[hex%16]);
}
//############################################################################
void uart_putstring(U8 *s)
//############################################################################
{
while(*s)
uart_putchar(*s++);
}
/******************************************************************************/
/************************以下与硬件无关***************************************/
/******************************************************************************/
//############################################################################
U08 mmc_init ()
//############################################################################
{
U08 Timeout = 0,a;
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};

MMC_Disable();

for(a=0;a<200;a++){ nop(); };

for (a = 0;a<20;a++)
{ 
mmc_read_byte();		
}

MMC_Enable();

for(a=0;a<200;a++){ nop(); };

while( mmc_write_command (CMD)!=1)
{
if (Timeout++ > 254)
{
 return(1);
}
}

Timeout = 0;
CMD[0] = 0x41;
//CMD[5]=0XFF;
while( mmc_write_command (CMD) !=0)
{
if (Timeout++ > 200)
{
return(2);
}
}

return(0);
}
//############################################################################
void mmc_goidel()
//############################################################################
{
U08 Timeout = 0;
U08 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
while( mmc_write_command (CMD)!=1)
{
if (Timeout++ > 200)
{
 return;//(1);
}
}

}
//############################################################################
U08 mmc_write_command ( U08 *cmd )
//############################################################################
{
U08 tmp=0xff;
U08 a;
for(a=0;a<16;a++) mmc_read_byte();
for(a=0;a<6;a++)  mmc_write_byte(cmd[a]);
for(a=0;a< 100;a++) 
{
tmp=mmc_read_byte();
if (tmp!=0xff)    break;
}
return(tmp);
}

//############################################################################
U08 mmc_write_sector (U32 addr,U08 *Buffer)
//############################################################################
{
U08 tmp;
U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; 
U16 a;
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
tmp = mmc_write_command (cmd);
if (tmp != 0)
{
return(tmp);
}
for (a=0;a<100;a++)
{
mmc_read_byte();
}
mmc_write_byte(0xFE);	
for (a=0;a<512;a++)
{
mmc_write_byte(*Buffer++);
}
mmc_write_byte(0xFF); //Schreibt Dummy CRC
mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
while (mmc_read_byte() != 0xff){};
return(0);
}
//############################################################################
void mmc_set_blocklen(U32 BLOCKLENTH,U8 RW)//1:read   0:write
//############################################################################
{
U08 cmd[] = {0x50,0x00,0x00,0x00,0x00,0xFF};
BLOCKLENTH = BLOCKLENTH << 1; //addr = addr * 512
cmd[1] = ((BLOCKLENTH & 0xFF000000) >>24 );
cmd[2] = ((BLOCKLENTH & 0x00FF0000) >>16 );
cmd[3] = ((BLOCKLENTH & 0x0000FF00) >>8 );
cmd[3] = BLOCKLENTH+(RW&0x01);
if (mmc_write_command (cmd) != 0)
{
  uart_putchar('*');
return;
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_read_block(U08 *cmd,U08 *Buffer,U16 Bytes)
//############################################################################
{	
U16 a;
if (mmc_write_command (cmd) != 0)
{
return;
}
while (mmc_read_byte() != 0xfe){};
for (a=0;a<Bytes;a++)
{
*Buffer++ = mmc_read_byte();
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_print_block(U32 addr,U16 Bytes)
//############################################################################
{	
U16 a;
U08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] =   addr&0xff;
if (mmc_write_command (cmd) != 0)
{
return;
}
while (mmc_read_byte() != 0xfe){};
for (a=0;a<Bytes;a++)
{
uart_puthex(mmc_read_byte());
if((a+1)%16==0)uart_putchar('\r');
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
//############################################################################
void mmc_write_block(U32 addr,U16 Bytes)////////////////////////////////////////////////////////////
//############################################################################
{	
U16 a;
U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] =   addr&0xff;
if (mmc_write_command (cmd) != 0)
{
return;
}
for (a=0;a<100;a++)
{
mmc_read_byte();
}
mmc_write_byte(0xFE);	
for (a=0;a<Bytes;a++)
{
mmc_write_byte(a);
}
//if(Bytes<512){
//for(a=0;a<(512-Bytes);a++)
//mmc_read_byte();
//}

mmc_write_byte(0xFF); //Schreibt Dummy CRC
mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
while (mmc_read_byte() != 0xff);
}
//############################################################################
void mmc_read_sector (U32 addr,U08 *Buffer)
//############################################################################
{	
U08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
mmc_read_block(cmd,Buffer,512);
}
//############################################################################
void mmc_read_cid (U08 *Buffer)
//############################################################################
{
U08 cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF}; 
mmc_read_block(cmd,Buffer,16);
}
//############################################################################
void mmc_read_csd (U08 *Buffer)
//############################################################################
{	
U08 cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
mmc_read_block(cmd,Buffer,16);
}
/******************************************************************************/
/************************以下仅做测试用****************************************/
/******************************************************************************/
/*************************************************

  Function:       // 将一个八位的二进制数 hex 放入一个扇区

  Description:    // 仅用于测试MMC卡

  Input:          //addr:第几个扇区  hex:八位的二进制数

*************************************************/
//############################################################################
U08 write_section(U32 addr,U8 hex)
//############################################################################
{
U08 tmp;
U08 cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; 
U16 a;
addr = addr << 9; //addr = addr * 512
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
tmp = mmc_write_command (cmd);
if (tmp != 0)
{
return(tmp);
}
for (a=0;a<100;a++)
{
mmc_read_byte();
}
mmc_write_byte(0xFE);	
for (a=0;a<512;a++)
{
mmc_write_byte(hex);
}
mmc_write_byte(0xFF); //Schreibt Dummy CRC
mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
while (mmc_read_byte() != 0xff){};
return(0);
}
/*************************************************

  Function:       // 打印一个扇区的内容,以HEX形式用串口显示

  Description:    // 仅用于测试MMC卡

  Input:          //addr:第几个扇区

*************************************************/
//############################################################################
void print_section(U32 addr)
//############################################################################
{
U08 cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; 
U32 a;
addr = addr << 9; //addr = addr * 512
cmd[1] =addr >>24;
cmd[2] =addr>>16;
cmd[3] =addr>>8;//&0xfe;
//cmd[4] =addr;
if (mmc_write_command (cmd) != 0)
{
return;
}
while (mmc_read_byte() != 0xfe);
a=0;
while(a<512)
{
uart_puthex(mmc_read_byte());
a++;
if((a%16)==0) uart_putchar('\r');
}
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
mmc_read_byte();//CRC - Byte wird nicht ausgewertet
}
/*************************************************

  Function:       // 打印csd数据

  Description:    // 仅用于测试MMC卡

  Input:          //Buffer:一个16*1字节的数组

*************************************************/
//############################################################################
void print_csd(U08 *Buffer)
//############################################################################
{
U08 tmp;
mmc_read_csd(Buffer);
for (tmp = 0;tmp<16;tmp++)
{
uart_puthex(Buffer[tmp]);
}
}
/*************************************************

  Function:       // 打印cid数据

  Description:    // 仅用于测试MMC卡

  Input:          //Buffer:一个16*1字节的数组

*************************************************/
//############################################################################
void print_cid(U08 *Buffer)
//############################################################################
{
U08 tmp;
mmc_read_cid(Buffer);
for (tmp = 0;tmp<16;tmp++)
{
uart_putchar(Buffer[tmp]);
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -