搜索
bottom↓
回复: 12

请教:如何应用现有的MP3程序实现对SD卡中数据进行读操作有高手指点一下,成功后愿意用M

[复制链接]

出0入0汤圆

发表于 2009-1-13 09:18:11 | 显示全部楼层 |阅读模式
各位好:

    我参照了网站上面藏其波和其他高手的MP3的案例,想读取SD卡中一个TXT文档的内容,不知道和MP3读取是否一样,请各位高手指点一下

大部分都是0X00,还有一部分是乱码

                                                                                                                                                  

                                                %PDF-1.6

%忏嫌

2933 0 obj <</Linearized 1/L 5138215/O 2935/E 313385/N 308/T 5079506/H [ 496 13829]>>

endobj

     

xref

2933 10

00000

00016 00000 n

0000014325 00000 n

0000014435 00000 n

0000014588 00000 n

0000014711 00000 n

0000014749 00000 n

0000014942 00000 n

0000015008 00000 n

0000016484 00000 n

000000049

6 00000 n

trailer

<</Size 2943/Prev 5079493/Root 2934 0 R/Info 2932 0 R/ID[<5DDDD5140CE7C5429C7DEBED72237869><09BD2C6D39A8FA4A9B5D3D07808D0C9B>]>>

startxref

0

%%EOF

   

2942 0 o

bj<</Length 13724/C 21663/Filter/FlateDecode/I 21685/O 21647/S 20537>>stream

x陟|kXSg嘱?'HH?損 jP磣懇h婦k1 E*盯?坔C!(J鹦?G谩G?j[唏?P⒌霢珟遴[[A抨催z??餆镧w}\滋噢蟖=

k蓦^鱶?哸T btk??~ 實?枌秊喲攆v?S褛e琑?3hY?挠c?扆?Q?留,U-K墾蜀SSx?媾挷?矹b???7洤W~虪銳Y韸??鉗Y

湑繴E~)咺UR?3蘆S妼窱?~枒O覫&O%揍,矪h<揯凟? g與:湨

~a硨?7?2搸デjt~螤+o笞昙蜍N嗯莩億煐昘鱠 jK7ρ眊?衷ヘ坑N5裩尔甲V2桇T蒺摉=?=?欚减u虝=貫p霪債4娅Jk ??蒹,,{?薑z稥謠/?喓O蒎X缷?又{亠

驥炜1?s鏮畑N)祱3_?雉R晘+??

(毃П瞤?z才磩錛*喧7郺篿熲稾揘檫

-鶠醵?+鸠豒響(疐?K趂鼏V溓紙穞?        箻?鋣:瞧?>-?YNs覵鹚~?W布襜

本贴被 paradise721 编辑过,最后修改时间:2009-01-14,08:49:31.

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2009-1-21 17:25:50 | 显示全部楼层
问题已经解决,年后将把源代码等奉上(明天回家了资料都在公司),希望能帮助一下和我一样迷茫的菜鸟!

出0入0汤圆

发表于 2009-1-16 09:25:28 | 显示全部楼层
我也希望能采用文本方式读写SD卡.

出0入0汤圆

 楼主| 发表于 2009-1-14 09:25:53 | 显示全部楼层
求SPI读取SD卡文件

出0入0汤圆

 楼主| 发表于 2009-1-14 08:51:07 | 显示全部楼层
用AVR读取MP3文件的和TXT文件一样吗?请教,谢谢

出0入0汤圆

 楼主| 发表于 2009-1-14 08:39:57 | 显示全部楼层
有高手指点一下,成功后愿意用Megal64+SJA1000 can模块全部资料(SCH+PCB+源文件(IAR))交换

出0入0汤圆

 楼主| 发表于 2009-1-13 09:21:58 | 显示全部楼层
#include <iom64v.h>

#include <macros.h>

#include <stdio.h>

#include "1011.h"

#include "mp3.h"

#include "sd.h"

#include "fat.h"

#include "uarst.h"



void key_port(void)

 {

 DDRD=0X00;

 PORTD=0XFF;

 }

void main()

{

key_port();

spi_init();

mp3_port_init();vs1011_init();vs1011_init();

sd_port_init();SD_Init();SD_Init();

uart0_init();

SPCR = 0x50;                //SPI始能,SPI主机模式

SPSR = 0x01;                //SPI倍速



fatInit();                  //查询SDFAT格式

if(Fat32Enabled)            //设置FAT格式标志

 FAT_MASK=FAT32_MASK;

else 

FAT_MASK=FAT16_MASK;





   while(1)

   { 

//播放音乐

   for(t=3;t<50;t++)

    {

        flag=0;

        mp3_play(fatGetDirEntry(t));

        }

    }

}





void mp3_play(unsigned long FirstClust)

{  

uint32 LBA,NextCluster;

uint16 i,data_pointer,rate;

uint8 n,t1;

NextCluster = FirstClust;



   while (1)

           {        

          LBA =fatClustToSect(NextCluster);

          for (i=0;i<SectorsPerCluster;i++)

                    {

                  if(flag==0)  ReadBlock(LBA+i);      //读完后文件指针自动后移

                  

        //按键处理程序

            //ST/PS键按下

          if(!(PIND&STOP))

           {

            delay_nus(250);

                if(!(PIND&STOP))

                {

                 flag^=0x01;

                 }

           }

          //VOLUP键按下

          if(!(PIND&VOLDOWN))  

           {

            delay_nus(250);

            if(!(PIND&VOLDOWN))  

                  {

                  vol=vol+((uint)(2<<8)+2);

                   if(vol>=0xF0F0) vol=0xF0F0; 

               else vs1011_cmd_write(0x0b,vol);    //每次左右声道VOL减2

                  }

           }

          //VOLDOWN键按下

          if(!(PIND&VOLUP)) 

            {

                delay_nus(250);

                if(!(PIND&VOLUP)) 

                  {

                   vol=vol-((uint)(2<<8)+2);

                   if(vol<=0x0505) vol=0x0505;

                   else vs1011_cmd_write(0x0b,vol);   //每次左右声道VOL加2

              }

                }

           //NEXT键按下

          if(!(PIND&NEXTSONG)) 

            {

                delay_nus(250);                

                if(!(PIND&NEXTSONG))  goto NEXT;       //跳到下一首歌曲

            }

            //PREV键按下

          if(!(PIND&PREVSONG)) 

            {

                delay_nus(250);

                if(!(PIND&PREVSONG))

                  {

                  t=t-2;goto NEXT;  //返回前一首歌曲

              }

                }

                

                 

                 data_pointer=0; 

        while(data_pointer<512)

        {    

            if(PINB&MP3_DATA_REQ)

               {

                 for(n=0;n<32;n++)

                           {

                    vs1011_data_write(BUFFER[data_pointer]);

                    data_pointer++;   

                          }

                                }

             if (data_pointer==511) break;   //如果现在的数据不够了,则跳出来

             }

        }

        NextCluster = fatNextCluster(NextCluster);

        if (NextCluster>=(CLUST_RSRVD&FAT_MASK))break;

        }

 NEXT: delay_nus(3);  /* 下一首歌曲*/

        

}

出0入0汤圆

 楼主| 发表于 2009-1-13 09:21:44 | 显示全部楼层
#include <iom64v.h>

#include <macros.h>

#include <stdio.h>



//UART0 initialize

// desired baud rate: 9600

// actual: baud rate:9600 (0.0%)

// char size: 8 bit

// parity: Disabled

void uart0_init(void)

{

 UCSR0B = 0x00; //disable while setting baud rate

 UCSR0A = 0x02;

 UCSR0C = 0x06;

 UBRR0L = 0x67; //set baud rate lo

 UBRR0H = 0x00; //set baud rate hi

 UCSR0B = 0x18; 

}

//串口输出字符串

void Puts( unsigned char *s)

{ 

         while (*s) 

      {

         putchar(*s);

         s++;

      }

}

出0入0汤圆

 楼主| 发表于 2009-1-13 09:21:22 | 显示全部楼层
#include <iom64v.h>

#include <macros.h>

#include <string.h>

#include "sd.h"

#include "fat.h"

#include "3310.h"



extern uchar BUFFER[512];

unsigned char  LONGNAME_BUFFER_ADDR[30];

unsigned char  DIRNAME_BUFFER_ADDR[30];

unsigned char *LongNameBuffer =                (unsigned char *) LONGNAME_BUFFER_ADDR;

unsigned char *DirNameBuffer =                (unsigned char *) DIRNAME_BUFFER_ADDR;

struct partrecord PartInfo;

unsigned char Fat32Enabled;

unsigned long FirstDataSector;

unsigned int  BytesPerSector;

unsigned int  SectorsPerCluster;

unsigned long FirstFATSector;

unsigned long FirstDirSector;

unsigned long FileSize;

unsigned long FatInCache = 0;



//********************************************************************************************

//读一个扇区

void ReadBlock(unsigned long LBA)

//********************************************************************************************

{   unsigned long temp;

    temp=LBA<<9;

    SD_Read_Block(temp);

}

/*-----------------------------------------------------------------------

 查询数据区一个簇开始扇区号

-----------------------------------------------------------------------*/

unsigned long fatClustToSect(unsigned long clust)

{

        return ((clust-2) * SectorsPerCluster) + FirstDataSector;

}

/*-----------------------------------------------------------------------

 查询一个簇所占扇区数

-----------------------------------------------------------------------*/

unsigned int fatClusterSize(void)

{

        // return the number of sectors in a disk cluster

        return SectorsPerCluster;

}

/*-----------------------------------------------------------------------

查询SD卡文件系统信息

-----------------------------------------------------------------------*/

unsigned char fatInit()

{

    unsigned int data;unsigned char t1,t2;



        struct bpb710 *bpb;

        // 读MBR结构

        ReadBlock(0);  

        // 读取分区表信息

        PartInfo = *((struct partrecord *) ((struct partsector *)BUFFER)->psPart);

        // 读引导扇区

        // 引导扇区号在PartInfo.prStartLBA中

        ReadBlock(PartInfo.prStartLBA);  //ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );

        bpb = (struct bpb710 *) ((struct bootsector710 *) BUFFER)->bsBPB;



        FirstDataSector        = PartInfo.prStartLBA;

        if(bpb->bpbFATsecs)

        {

                // bpbFATsecs非0,为FAT16,FAT表所占的扇区数在bpbFATsecs里

                FirstDataSector        += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;

        }

        else

        {

                // bpbFATsecs是0,为FAT32,FAT表所占的扇区数在bpbBigFATsecs里

                FirstDataSector        += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;

        }

        

        SectorsPerCluster        = bpb->bpbSecPerClust;

        BytesPerSector                = bpb->bpbBytesPerSec;

        FirstFATSector                = bpb->bpbResSectors + PartInfo.prStartLBA;

//查询SD卡文件系统分区类型

        switch (PartInfo.prPartType)

        {

                case PART_TYPE_DOSFAT16:

                case PART_TYPE_FAT16: 

                case PART_TYPE_FAT16LBA:

                        // 第一个目录扇区号为2

                        FirstDirSector        = CLUST_FIRST;

                        //FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;

                        Fat32Enabled = 0;

                        

                        break;

                case PART_TYPE_FAT32LBA:

                case PART_TYPE_FAT32:

                        

                        FirstDirSector = bpb->bpbRootClust;

                        Fat32Enabled = 1;

                        break;

                default:break;

                        //return 1;

        }

//查询SD卡文件系统信息

        switch (PartInfo.prPartType)

        {

                case PART_TYPE_DOSFAT16:

                                LCD_write_english_string(0,0,"DOSFAT 16");

                                break;

                case PART_TYPE_FAT16:

                                LCD_write_english_string(0,0,"FAT16 ");

                                break;

                case PART_TYPE_FAT16LBA:

                                LCD_write_english_string(0,0,"FAT16 LBA");

                                break;

                case PART_TYPE_FAT32LBA:

                                LCD_write_english_string(0,0,"FAT32 LBA");

                                break;

                case PART_TYPE_FAT32:

                                LCD_write_english_string(0,0,"FAT32");

                                break;

                default:

                                LCD_write_english_string(0,0,"No Partition!");

                                break;

        }

//显示磁盘容量

data=PartInfo.prSize>>11;

    LCD_set_XY(56,0);

    t1=data/100;

        LCD_write_char(t1+48);

        data=data%100;

        t1=data/10;

        LCD_write_char(t1+48);

        t2=data%10;

        LCD_write_char(t2+48);

        LCD_write_english_string(76,0,"M");

    LCD_write_english_string(0,1,"RATE");

        return 0;        

}



/*-----------------------------------------------------------------------

查询一个文件的开始簇

-----------------------------------------------------------------------*/

unsigned int baseentry = 0;

unsigned int entrycount = 0;





unsigned long fatGetDirEntry(unsigned int entry)

{

        unsigned long sector;

        struct direntry *de = 0;        // 防止compiler warning

        struct winentry *we;

        unsigned int hasBuffer;

        unsigned int b;

        int i,index;

        char *p;

        

                entrycount = 0;

                DirNameBuffer = 0;

        

        

        // 读取目录区数据

        sector = fatClustToSect(FirstDirSector);



        hasBuffer = 0;



        index = 16;        

        do 

        {

                if(index == 16)        // 是否该一人一扇区time for next sector ?

                {

                        ReadBlock(sector++);

                        de = (struct direntry *)BUFFER;

                        index = 0;

                }        

        

                if(*de->deName != 0xE5)

                {

                        // 如果if not a deleted entry

                        if(de->deAttributes == ATTR_LONG_FILENAME)

                        {

                                // we have a long name entry

                                we = (struct winentry *) de;

                                b = 13 *( (we->weCnt-1) & 0x0f);                                // index into string

                                p = &LongNameBuffer;

                                for (i=0;i<5;i++)        *p++ = we->wePart1[i*2];        // copy first part                        

                                for (i=0;i<6;i++)        *p++ = we->wePart2[i*2];        // second part

                                for (i=0;i<2;i++)        *p++ = we->wePart3[i*2];        // and third part

                                if (we->weCnt & 0x40) *p = 0;                                        // in case dirnamelength is multiple of 13

                                if ((we->weCnt & 0x0f) == 1) hasBuffer = 1;                // mark that we have a long entry

                        }

                        else

                        {

                                // we have a short name entry

                                // check if this is the end of a multi-part long name entry

                                if(hasBuffer)

                                {

                                        // a long entry name has been collected

                                        // is it a directory ?

                                        if(de->deAttributes == ATTR_DIRECTORY)

                                        {

                                                unsigned long save = FirstDirSector;

                                                unsigned int save2 = baseentry;

                                                unsigned long rval;

                                                

                                                strcpy(DirNameBuffer,LongNameBuffer);

                                                strcat(DirNameBuffer,"/");



//                                                rprintfStr(LongNameBuffer); rprintfProgStrM("/"); //EOL();



                                                // call recursively

                                                FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;

                                                rval = fatGetDirEntry(entry);

                                                FirstDirSector = save;

                                                baseentry = save2;

                                                if (rval)

                                                        return rval;

                                                else        

                                                {

                                                        // reload original sector

                                                        ReadBlock(sector-1);//ataReadSectors( DRIVE0,        sector-1, 1, SectorBuffer);

                                                        entrycount--;                        // decrement entry counter                

                                                        *DirNameBuffer = 0;

                         }

                                        }

                                        else // normal file entry

                                                if(entrycount == entry)                

                                                        break;

                                        hasBuffer = 0;        // clear buffer        

                                        entrycount++;        // increment entry counter                

                                }

                                // else ignore short_name_only entries

                        }

                }

                de++;

                index++;

        }        while (*de->deName || index == 16);        // 0 in de->deName[0] if no more entries



        if (hasBuffer == 0)                // end of entries

                return 0;

        

        FileSize = de->deFileSize;

        return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;

}



/*-----------------------------------------------------------------------

 在FAT表中查询下一个簇所在扇区号

-----------------------------------------------------------------------*/

unsigned long fatNextCluster(unsigned long cluster)

{

        unsigned long nextCluster;

        unsigned long fatMask;

        unsigned long fatOffset;

        unsigned long sector;

        unsigned int offset;

        

        if(Fat32Enabled)

        {

                // 一个表项为4bytes(32 bits)

                fatOffset = cluster << 2;

                // 设置 FAT32 bit mask

                fatMask = FAT32_MASK;

        }

        else

        {

                // 一个表项为2bytes(16 bits)

                fatOffset = cluster << 1;

                // 设置 FAT16 bit mask

                fatMask = FAT16_MASK;

        }

        

        //计算FAT扇区号

        sector = FirstFATSector + (fatOffset / BytesPerSector);

        //计算FAT扇区号中表项的偏移地址

        offset = fatOffset % BytesPerSector;

    

        ReadBlock(sector);



        // 读取下一个簇号

        nextCluster = (*((unsigned long*) &((char*)BUFFER)[offset])) & fatMask;



        // 是否文件的结束簇

        if (nextCluster == (CLUST_EOFE & fatMask))

                nextCluster = 0;

                

        return nextCluster;

}

出0入0汤圆

 楼主| 发表于 2009-1-13 09:20:54 | 显示全部楼层
#include <iom64v.h>

#include <macros.h>

#include "english_6x8_pixel.h"



#define LCD_PORT        PORTC

#define LCD_DC          BIT(0)  

#define LCD_CE          BIT(1)  

#define LCD_RST         BIT(2) 

 

void delay_1us(void)                 //1us延时函数

  {

   asm("nop");

  }

 

void lcd_port()

{

DDRC=0x03;

PORTC|=LCD_CE|LCD_DC;

DDRD=0xff;

PORTC|=LCD_RST;

}

/*-----------------------------------------------------------------------

LCD_write_byte    : 使用SPI接口写数据到LCD



输入参数:data    :写入的数据;

          command :写数据/命令选择;

-----------------------------------------------------------------------*/

void LCD_write_byte(unsigned char data, unsigned char command)

  {

    LCD_PORT&= ~LCD_CE ;                        // 使能LCD

    

    if (command == 0)

      {

          LCD_PORT&= ~LCD_DC ;        // 传送命令

          }

    else

      {

          LCD_PORT|= LCD_DC ;                        // 传送数据

          }



    SPDR = data;                        // 传送数据到SPI寄存器



    while ((SPSR & 0x80) == 0);         // 等待数据传送完毕

        

    LCD_PORT|= LCD_CE ;                        // 关闭LCD

  }

/*-----------------------------------------------------------------------

LCD_set_XY        : 设置LCD坐标函数



输入参数:X       :0-83

          Y       :0-5

-----------------------------------------------------------------------*/

void LCD_set_XY(unsigned char X, unsigned char Y)

  {

    LCD_write_byte(0x40 | Y, 0);                // column

    LCD_write_byte(0x80 | X, 0);                  // row

  }



/*-----------------------------------------------------------------------

LCD_write_char    : 显示英文字符



输入参数:c       :显示的字符;

-----------------------------------------------------------------------*/

void LCD_write_char(unsigned char c)

  {

    unsigned char line;

    c -= 32;

    for (line=0; line<6; line++)

      LCD_write_byte(font6x8[c][line], 1);

  }

/*-----------------------------------------------------------------------

LCD_write_english_String  : 英文字符串显示函数



输入参数:*s      :英文字符串指针;

          X、Y    : 显示字符串的位置,x 0-83 ,y 0-5        

-----------------------------------------------------------------------*/

void LCD_write_english_string(unsigned char X,unsigned char Y,char *s)

  {

    LCD_set_XY(X,Y);

    while (*s) 

      {

         LCD_write_char(*s);

         s++;

      }

  }

/*-----------------------------------------------------------------------

LCD_clear         : LCD清屏函数

-----------------------------------------------------------------------*/

void LCD_clear(void)

  {

    unsigned int i;



    LCD_write_byte(0x0c, 0);        //普通显示模式                

    LCD_write_byte(0x80, 0);    //设置RAM的X地址        



    for (i=0; i<504; i++)

      LCD_write_byte(0, 1);                //写0数据        

  }

/*-----------------------------------------------------------------------

LCD_init          : 3310LCD初始化

-----------------------------------------------------------------------*/

void LCD_init(void)

  {

    PORTD &= ~LCD_RST;          // 产生一个让LCD复位的低电平脉冲

    delay_1us();

    PORTD |= LCD_RST;

    delay_1us();

    LCD_write_byte(0x21, 0);        // 使用扩展命令设置LCD模式

    LCD_write_byte(0xc8, 0);        // 设置偏置电压

    LCD_write_byte(0x06, 0);        // 温度校正

    LCD_write_byte(0x13, 0);        // 1:48

    delay_1us();

    LCD_write_byte(0x20, 0);        // 使用基本命令

    LCD_clear();                    // 清屏

    LCD_write_byte(0x0c, 0);        // 设定显示模式,正常显示    

  }

出0入0汤圆

 楼主| 发表于 2009-1-13 09:20:33 | 显示全部楼层
#include <iom64v.h>

#include <macros.h>

#define uchar unsigned char

#define uint unsigned int

#define MP3_DDR        DDRB

#define MP3_PORT       PORTB

#define MP3_PIN        PINB

#define MP3_CMD_CS     BIT(4)

#define MP3_DATA_CS    BIT(7)

#define MP3_DATA_REQ   BIT(6)   

#define MP3_DATA_REST  BIT(5)   

void delay_Nus(unsigned int n)

        {

        unsigned char  b;

                for (b = 1; b<n; b++)

                        ;

        }

//SPI initialize

// clock rate: 500000hz

void spi_init(void)

{

 DDRB=0xF7;    //SI输入,SO,SCK,SS输出

 SPCR = 0x53;  //setup SPI

 SPSR = 0x00;  //setup SPI

}

void Write_Byte_SPI(unsigned char byte)

{   

    SPDR = byte;

    while (!(SPSR & (1<<SPIF)));

}

unsigned char Read_Byte_SPI(void)

{   

    SPDR = 0xFF;

    while (!(SPSR &(1<<SPIF)));

    return SPDR;

}

void mp3_port_init()

{

spi_init();

MP3_DDR|=MP3_DATA_CS |MP3_CMD_CS|MP3_DATA_REST;

MP3_DDR&=~MP3_DATA_REQ;

MP3_PORT|=MP3_DATA_CS |MP3_CMD_CS|MP3_DATA_REST;

//MP3_PORT&=~MP3_DATA_REST;

}

void vs1011_cmd_write(uchar address,uint data)

{ 

MP3_PORT|=MP3_DATA_CS;       //MP3_DATA_CS=1;

MP3_PORT&=~MP3_CMD_CS;       //MP3_CMD_CS=0;

Write_Byte_SPI(0x02);      //VS1011的写命令

//delay_nus(20);

Write_Byte_SPI(address);   //地址

Write_Byte_SPI(data>>8);

Write_Byte_SPI(data);

//delay_nus(200);

MP3_PORT|=MP3_CMD_CS;       //MP3_CMD_CS=1;

} 



void vs1011_data_write(uchar data)

{

MP3_PORT&=~MP3_DATA_CS;         //MP3_DATA_CS=0;

Write_Byte_SPI(data);

MP3_PORT|=MP3_DATA_CS;         //MP3_DATA_CS=1;

MP3_PORT|=MP3_CMD_CS;         //MP3_CMD_CS=1; 

}



uint vs1011_read(uchar address)

{

uchar temp1=0;

uint temp=0; 

MP3_PORT|=MP3_DATA_CS;        //MP3_DATA_CS=1;

MP3_PORT&=~MP3_CMD_CS;        //MP3_CMD_CS=0;

Write_Byte_SPI(0x03);      //VS1011的读命令

//delay_nus(20);

Write_Byte_SPI(address);   //地址

temp=Read_Byte_SPI();

temp=temp<<8;

temp1=Read_Byte_SPI();

temp=temp|temp1; 

MP3_PORT|=MP3_CMD_CS;       //MP3_CMD_CS=1;

return temp;



}



void vs1011_init(void)

{



delay_Nus(50);

vs1011_cmd_write(0x00,0x0800);     //NEW MODE

vs1011_cmd_write(0x02,0X75);       //BASS

vs1011_cmd_write(0x03,0X9800);     //CLOCK F

vs1011_cmd_write(0x0b,0X3030);    //VOLUME

}

出0入0汤圆

 楼主| 发表于 2009-1-13 09:20:03 | 显示全部楼层
上面的信息是什么意思啊,不是很明白啊,读写MP3文件和TXT文件有区别吗

#include <iom64v.h>

#include <macros.h>

#include "1011.h"

#define uchar unsigned char

#define uint unsigned int

#define MMC_CS_PIN     BIT(0)    //PORTB.0 

#define MMC_PORT       PORTB    



 uchar reading=0,a=0,pointer=0;

void sd_port_init()

{

MMC_PORT|=MMC_CS_PIN;

}

uchar BUFFER[512];                   //扇区缓冲区

uint i=0;

void delay_nus(uint n)

        {

        unsigned char  b;

                for (b = 1; b<n; b++)

                        ;

        } 

//****************************************************************************

//Send a Command to MMC/SD-Card

//Return: the second byte of response register of MMC/SD-Card

//****************************************************************************

uchar SD_Write_Command(uchar cmd,unsigned long arg)

{

   uchar tmp;

   uchar retry=0;

   

   //MMC_PORT|=MMC_CS_PIN;       //SD卡关闭   

   //send 8 Clock Impulse

   Write_Byte_SPI(0xFF);

   

   //set MMC_Chip_Select to low (MMC/SD-Card active)

   MMC_PORT&=~MMC_CS_PIN;       //SD卡使能



   Write_Byte_SPI(cmd|0x40);   //送头命令

   Write_Byte_SPI(arg>>24);

   Write_Byte_SPI(arg>>16);     //send 6 Byte Command to MMC/SD-Card

   Write_Byte_SPI(arg>>8);

   Write_Byte_SPI(arg&0xff);

   Write_Byte_SPI(0x95);       //仅仅对RESET有效的CRC效验码

  

   //get 8 bit response

   //Read_Byte_MMC(); //read the first byte,ignore it. 

   do 

   {  //Only last 8 bit is used here.Read it out. 

      tmp = Read_Byte_SPI();

      retry++;

   }

   while((tmp==0xff)&&(retry<100));  //当没有收到有效的命令的时候

   

   if(reading==0)

   MMC_PORT|=MMC_CS_PIN;            //MMC_CS_PIN=1;

   else MMC_PORT&=~MMC_CS_PIN;      //MMC_CS_PIN=0;   

   return(tmp);

}

//****************************************************************************

//SD卡初始化(SPI-MODE)

//****************************************************************************

uchar SD_Init(void)

{  

   uchar retry,temp;

   uchar i;

   MMC_PORT&=~MMC_CS_PIN;      //SD卡使能

  

  delay_nus(250);  //Wait MMC/SD ready...

   for (i=0;i<0x0f;i++) 

   {

      Write_Byte_SPI(0xff); //send 74 clock at least!!!

   }

   //Send Command CMD0 to MMC/SD Card

   retry=0;

   

   do

   { //retry 200 times to send CMD0 command 

     temp=SD_Write_Command(0,0);

     retry++;

     if(retry==100) 

     { 

      ;//CMD0 Error!

     }

   } 

   while(temp!=1);  

   

   //Send Command CMD1 to MMC/SD-Card

   retry=0;

   do

   { //retry 100 times to send CMD1 command 

     temp=SD_Write_Command(1,0);

     retry++;

     if(retry==100) 

     { 

     ;

     }

   } 

   while(temp!=0); 

   retry=0; 

   SD_Write_Command(16,512);     //设置一次读写BLOCK的长度为512个字节

  

   MMC_PORT|=MMC_CS_PIN;   //MMC_CS_PIN=1;  //set MMC_Chip_Select to high 

   return(0); //All commands have been taken.

} 

//****************************************************************************

//从SD卡读一个扇区  Return 0 if no Error.

//****************************************************************************

uchar SD_Read_Block(unsigned long address)

{  

   uchar temp=0;uint i=0;

   reading=1; 

   temp=SD_Write_Command(17,address);     //读出RESPONSE     

   while (Read_Byte_SPI()!= 0xfe)

   {;}  //直到读取到了数据的开始头0XFE,才继续

   for(i=0; i<512; i++)

        {

        BUFFER=Read_Byte_SPI();

        }

   Read_Byte_SPI();//CRC - Byte 

   Read_Byte_SPI();//CRC - Byte

   reading=0; 

   MMC_PORT|=MMC_CS_PIN;        //关闭SD卡

   return(temp);

}

出0入0汤圆

发表于 2009-8-21 17:18:32 | 显示全部楼层
学习了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-12 13:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表