[原创]资源共享:开放我的mmc/sd操作原代码
经过一段时间的努力,搞定了mmc/sd卡mp3 player,经过测试,320kbps文件极其流畅:). 这个上面SD成功的人不少,但是始终不见有人open source,见于这种情况,我准备开放我的mmc.c&mmc.h代码给大家,也表示对ouravr做些贡献.希望大家在弄mmc/sd mp3时候少走弯路.希望大家喜欢:).所有代码我都经通过了我的测试.我分别采用了software spi和hardware spi访问mmc/sd,软件spi速度很慢,我只能采用16mhz的时钟才能播放320kbps的文件:(. 硬件SPI速度极其快,速度有质的飞跃:)
下面是我对低层代码的一些测试:
My hardware:
CPU: ATnega162
Clock:8MHz
Data Source: Kingston 128MB High-Speed SD Card(white colour)
Test 1:
---------------------------------------------------
SPI:Software SPI
DATA block: 1MB
Time: 35s
Speed:about 28KB/s=224kbps
Test 2:
----------------------------------------------------
SPI:Hardware SPI
DATA block: 1MB
Time: 10s
Speed:about 100KB/s=800kbps. Very fast ^_^.
Test 3:
-----------------------------------------------------
The crystal of cpu has been changed!
Clock : 16MHz
SPI : Hardware SPI + software SPI(init mmc/sd)
DATA BLOCK: 1MB
Data Source : Kingston 128MB High-Speed SD
Time : 5.5S
Speed: about 200KB/S. Oh,my god,very very fast^_^!
Notice: Here I use software SPI to initialize mmc/sd,or I can't do it:(
先上传我的使用software spi操作mmc/sd代码给大家:)(硬件的稍后):
点击此处下载armok0167408.rar
说明:我没有画电子版本的sch,也没有时间画,当初就是在纸上画的:) 请仔细看mmc.h,看明白硬件连接.我先简单给个连接图:
SD M162 Port
----------------------------
1CS ---> PORTA.0
2 CMD/DI ---> PORTA.1
3 GND ---> NC(接相应的3.3V电源地)
4 Vcc ---> NC(接3.3V电源正)
5 CLK ---> PORTA.4
6 GND ---> NC(接相应的3.3V电源地)
7 DO ---> PORTA.6
8 NC ---> PORTA.7(MMC busy LED)
9 NC ---- 未连接
注意:8脚连上一个1K的电阻和一个LED送到PORTA.7上去作为MMC_BUSY_LED.忙信号是低电平驱动的.
另外连接到SD卡要进行电平转换.如下:
_________________ PORTA.0
|
|-|
| | 1.2K
|_|
|_________________CMD/DI(MMC/SD PIN)
|
|-|
| |2.2k
|_|
|
|
|_________________GND
|
---
-
另外SD的DATA OUT脚,也就是7脚DO不需要转换,直接连到CPU的PORTA.6.
编译环境cvavr.移植到GCC需要做些修改了:)
1. 在初始化时候要注意SPI速度,在初始化时候尽量降低SPI速度.我的卡(kingston 128MB)如果没有降低速度在发CMD0正常,发CMD1时候总出错!这个很重要一定要注意!!!! 在初始化成功后,尽可能提高SPI速度,我是将AVR的SPI速度提升到了极限,SPI2X也ENABLE.
2. 在操作mmc/sd之前,先发送80个脉冲给它.(/cs先禁止)
Good luck to all:)
-----此内容被elefan于2005-09-04,10:59:26编辑过
-----此内容被elefan于2005-09-04,11:02:31编辑过 期待中 收藏先。。。 谢谢共享!
给elefan的共享精神加200分! 谢谢armok:).写代码那几天天天熬到晚上1点. 是真的,花了我不少时间. 主要是MMC/SD操作很奇怪,初始化要用很低的SPI速度,害了我浪费了好几天时间,在这里再次提醒大家.咦,怎么加了200分才170呢? 怎么少了呢? 呵呵,是系统错误吧! 现在OK! 编程风格不错,是值得大家学习的程序。 程序包括基本操作部分外,还加了MMC_get_volume_info(void),调用能读出SD型号和容量:
eg: Product:SD512
Total: 512MB
另外有很所实用的供参考的程序.例如在m8515中操作mmc/sd,不可能缓冲一个sector,因此利用MMC_Start_Read_Sector()就可以打开一个LBA地址的512字节,接下来就是clock all data out了,请参考程序:) 支持!有时间好好研究 不错。
楼主DIY MP3多久了,一般需要什么开发工具?能指点一下吗?
谢谢! http://www.ulrichradig.de/site/atmel/avr_mmcsd/index.htm To kinsey: 做MP3将近一年:) 做这个其实也不需要什么特别工具.就我来说:
1. 硬件:
一块实验板,带STA013和CS4334,你也可以自己做和STA013和CS4334小板,然后与自己做的实验板子或者是站上马潮老师的实验板配合,接口就行了:)
2. 软件环境
关于编程环境,可以按自己熟悉的环境来GCC,CVAVR,ICCAVR,IAR都行.关键是自己觉得好用就行,因为C的移植性很强,所以也不要刻意去找编译器.
3. 其他资料
要找到好的参考资料,你不可能整天抱着那个datasheet去看.多看看别人怎么做,结合datasheet看,这样理解最快.
4. 最后就靠自己时间摸索能力,包括调试程序能力和硬件能力.出现问题要会迅速定位错误范围,不是瞎搞.那样你永远不知道在什么地方出错. 也就是说多动脑子比多动手要强的多.
-----此内容被elefan于2005-09-04,23:12:37编辑过 好东西,辛苦了。 哗,好东西,多谢共享 向elefan这种无私的精神致敬!什么时候MP3的测试整体出来啊!期待! 我正在测试楼主的程序,遇到一个问题,希望楼主不吝赐教,
我用ICC6.31A,在调用MMC端口初始化时,老是报错:
void MMC_Port_Init(void)
//****************************************************************************
{
//Config ports
MMC_Direction_REG.SPI_DI=0; //Set Pin MMC_DI as Input MMC_Direction_REG.SPI_Clock=1; //Set Pin MMC_Clock as Output
MMC_Direction_REG.SPI_DO=1; //Set Pin MMC_DO as Output
MMC_Direction_REG.MMC_Chip_Select=1; //Set Pin MMC_Chip_Select as Output
//busy led port init
MMC_Direction_REG.SPI_BUSY=1; //Set spi busy led port output
MMC_BUSY_LED=1; //busy led off
MMC_CS_PIN=1; //Set MMC_Chip_Select to High,MMC/SD Invalid.
}
报错内容如下:
!E mmc.c(25): field name expected
!W mmc.c(25): reference to `volatile unsigned char' elided
!W mmc.c(25): expression with no effect elided
!E mmc.c(25): syntax error; found `6' expecting `;'
!E mmc.c(25): lvalue required
!E mmc.c(26): field name expected
!W mmc.c(26): reference to `volatile unsigned char' elided
!W mmc.c(26): expression with no effect elided
!E mmc.c(26): too many errors
Done: there are error(s). Exit code: 1 好像是头文件中结构体出错,后来我又加了IO162V.H文件,可是依旧不能通过 To ljd166:
ICCAVR好象没有CVAVR中方便的位操作功能.例如:
//PORTB init
DDRB.0=1; //output mode
PORTB.0=1; //high status
你需要做些修改以适应ICCAVR编译器,具体我不是很熟悉,请仔细参考其user manual.
像程序中:MMC_Direction_REG.SPI_DI=0; //Set Pin MMC_DI as Input
我在mmc.h中做了详细描述. 可以进行'.'操作,就是位操作. 谢谢楼主,看来我可能需要重新编这段程序,不过楼主的这种风格我很喜欢,所以才保留下来,没有修改。 Toljd166 :
谢谢!你很喜欢,就可以在mmc.h中做些define就行了,可以继续使用:) Good luck to you:) 借问楼主:
怎么没有使用硬件SPI接口,而是用软件模拟的. 问一下楼主,你用的那个软SPI中间的Init_Flag那个量是干什么用的啊?
我也在做MP3,现在有个疑问,就是SPI口什么时候可以读取外部的数据,因为它没有向I2C那样读到了数据就把相应的标志置位啊? To myhk007:
Init flag是用来降低SPI速度的,我使用了SPI的最低速度但是还是初始化失败了,无赖,先换成软件SPI初始化SD,成功后,然后把AVR的硬件SPI速度提升到极限.请参考下面的代码:
//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
unsigned char MMC_Init(void)
//****************************************************************************
{
unsigned char retry,temp;
unsigned char i;
unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
//MMC_Port_Init(); //Init SPI port
for(i=0;i<200;i++) //Wait MMC/SD ready...
{
#asm("nop");
}
//Active SPI bus at low speed
//SPCR=0x53; //SPI Master,MSB First
//SPSR=0x00; //double speed disable,Fsck=Fosc/128
SPCR=0x00; //Disable SPI bus
Init_Flag=1; //Set Init flag
for (i=0;i<0x0f;i++)
{
Write_Byte_MMC(0xff); //send 74 clock at least!!!
}
//Send Command CMD0 to MMC/SD Card
retry=0;
do
{ //retry 200 times to send CMD0 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==200)
{ //time out
return(INIT_CMD0_ERROR);//CMD0 Error!
}
}
while(temp!=1);
//Send Command CMD1 to MMC/SD-Card
CMD = 0x41; //Command 1
CMD = 0xFF;
retry=0;
do
{ //retry 100 times to send CMD1 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{ //time out
return(INIT_CMD1_ERROR);//CMD1 Error!
}
}
while(temp!=0);
Init_Flag=0; //Clear the flag and use hardware SPI port
//Active High-speed SPI mode(Fsck=Fosc/2)
SPCR=0x50;
SPSR=0x01;
MMC_Disable();//set MMC_Chip_Select to high
return(0); //All commands have been taken.
}
//****************************************************************************
//Routine for reading a byte from MMC/SD-Card
unsigned char Read_Byte_MMC(void)
//****************************************************************************
{
unsigned char i,temp=0;
MMC_BUSY_LED=0;
if(Init_Flag)
{ //Software SPI
for (i=0; i<8; i++) //MSB First
{
SPI_SCK_PIN=0; //Clock Impuls (Low)
MMC_clk_delay();
temp = (temp << 1) + SPI_DI_PIN; //read mmc data out pin
SPI_SCK_PIN=1; //set Clock Impuls High
MMC_clk_delay();
}
MMC_BUSY_LED=1;
return(temp);
}
else
{ //Hardware SPI
SPDR=0xFF;
while(!(SPSR & 0x80)){};
MMC_BUSY_LED=1;
return (SPDR);
}
}
你看看我代码就知道,我知道我为什么要这样做(之前硬件初始化程序我屏蔽了). 读数据先送0XFF,实际上上发clk脉冲.你应该知道SPI是同步的,发数据时候,SPI也在接收数据,所以数据0XFF被送出后,在SPDR中就得到了要接收的数据.请参考上面的代码:) 多谢ELEFAN!今天就准备上电调试了,估计会遇到不少问题啊. 是用我喜欢的CVAVR啊。
强烈支持elefan的无私奉献精神。
可惜最近没空啊。
谢谢啦 谢谢共享,我在21ic上的AVR 论坛还找不到关于AVR 开发技术上的那么详细的讲解.
也谢谢站主. elefan 你的程序可能不是最优化的 这个可能是和你的电路有关系 我在网上查了不少的SD读写程序都没有你那么复杂 你可以试着把你的SPI接口与SD卡的下偏电阻去掉 初始化就不会那么困难了 其实它们之间是可以直接连接的 但是为了防止出现损坏SD卡 建议加上隔离电阻10~500欧之间 其他的没有什么区别
下面是我改写后的代码
点击此处下载armok0196526.rar
i = 3;
while(i--)
{
temp = MMC_Init();
if(temp == TRUE)break;
OSTimeDly(10);
}
if(i == 0)err_out(temp);
上面的代码是初始化SD卡 一般读写的时候和上面的代码一样
以上代码都是在M128 16M测试通过的 to hygbeyond:
谢谢你的意见,目前我的代码速度在16MHZ下测试为200KB/S.按照SPI速度:8MBPS计算,SD卡应该具有1MB/S字节传输速度,代码速度还不够理想.应该跟硬件有关(代码会在命令发送失败后会自动retry,估计这个有点耽误速度)我试着优化下硬件. avr-libc中就有源码. elefan 代码中初始化到SPI模式,少了个MMC_ENABLE. 初始化时速度慢, 我估计是sd和mmc的兼容性的原因, sd卡不知道设备是否支持高速, 所以用低速来初始化, 初始化完成后确定可以支持高速, 才进入到高速模式
我有一个闲置的32mSD, 拿来研究研究
谢了... 我用的也是32MB,因为刚开始不太明白SD的扇区操作,所以把SD的引导扇区给写坏,结果任何设备都无法对其格式化(包括DC,PC),最后没有办法,自己硬着头皮把引导扇区的开头的那几十个数据,一个一个地输进去,才救活了我的SD卡。 to ljd166 and all:
为了保护你的SD卡不被程序误写引导和FAT扇区,请不要乱call mmc_write_sector()函数,初学者多call mmc_read_sector()就可以了,搞坏了0扇区和FAT扇区就很麻烦了.确实要写,确保你所写的扇区在DATA区域中,并且SD中没有重要文件.
不懂FAT多看看sd的说明书,那里说的比较详细,资料就在本论坛. 唉,刚开始像无头苍蝇一样,胡乱试,结果出了错,不过还好我又把它给修好了。
谢谢楼主鞭笞,下次一定不敢随便乱试了:) 请教楼主一个问题,为什么我的SD卡在读写的时候,地址会有19的偏移,包括读和写 感谢,但我有一个地方看不懂,就是
uint8 MMC_write_sector(uint32 addr,uint8 *Buffer)和
uint8 MMC_read_sector(uint32 addr,uint8 *Buffer)函数,其中的:
temp = Write_Command_MMC(MMC_READ_BLOCK,addr<<9);看样子是传送块地址吧,块地址应该是在addr的BIT10以后的高字节把,应该
temp = Write_Command_MMC(MMC_READ_BLOCK,addr>>9);这样才能得到高位块地址吧?
希望高人能讲讲这是咋回事,谢谢. toljd166 : 能详细描述下吗?
to freny:
address<<9 意思是说address * 512.
SD/MMC卡是用字节定位来寻址. 不是常见的logic block address, 这里实际是把LBA地址转换为字节地址. 好,谢谢! 非常感谢elefan! 谢谢各位工程师!希望能看到硬件电路,便于新手学习啊! 硬件是利用SPI总线连接的,不会很复杂。关键是软件的调试部分。 这是我在ouravr的处女帖,跟楼主很有缘啊,以前在21ic和dianyuan网,我都是用elecfans注册的用户名,今次在ouravr注册elecfans可以顺便借楼主威名的光了呵呵。今年暑假我尝试用89s52模拟spi时序驱动sd卡,参考arm的程序自己编写了一小段,也制作了硬件,上电时序是通过了,其后的指定block长度的指令总是的不到response,至今没能解决,回学校之后,开始学习avr,打算借鉴楼主的程序,等测试通过了再发贴报告。谢谢elecfan先! 请教:
unsigned char MMC_read_sector(unsigned long addr,unsigned char *Buffer)
{
//Command 16 is reading Blocks from MMC/SD-Card
unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
unsigned char temp;
asm("cli"); //clear all interrupt.
//Address conversation(logic block address-->byte address)
addr = addr << 9; //addr = addr * 512
CMD = ((addr & 0xFF000000) >>24 );
CMD = ((addr & 0x00FF0000) >>16 );
CMD = ((addr & 0x0000FF00) >>8 );
temp=MMC_Read_Block(CMD,Buffer,512);
return(temp);
}
其中的
unsigned long addr
是指图中哪个,我要读的是123。TXT文件,不用FAT16系统的
http://cache.amobbs.com/bbs_upload782111/files_6/armok01128648.jpg
http://cache.amobbs.com/bbs_upload782111/files_6/armok01128647.jpg
-----此内容被ahui于2006-09-12,13:17:30编辑过
-----此内容被ahui于2006-09-12,13:18:49编辑过 我的一张MMC卡在NOKIA手机上被锁了,是不是可以这样的程序对它的扇区进行格式化?
(用MMC卡的格式化工具不行) 那位大虾有没有用CVAVR编译器写的SD/MMC的读写程序啊?论坛上都是ICC和GCC的。 to:elefan
你上面共享出来的SD/MMC程序好像就是CVAVR的吧!刚刚上面的我发的贴子还以为是ICC,GCC写的了,谢谢了! 请教一下,你用的那个查看分区的还一些详细资料的软件的名字叫什么??谢谢! 编辑工具: UltraEdit 功能很强大,你试着用下吧! to whimsy:
我没有写格式化函数,需要自己写一个,不要乱格式化. 接【43楼】
上次OK后,忘记接着发了,是上面的757 上面那个直接读磁盘数据的软件应该是winHex吧 怎么我用MMC_get_volume_info()来读一个32M的MMC卡 读出来的结果是这样的
Product:32***
Total: MB
请问哪位大虾也遇到我这种情况????希望高手指点。谢了 收藏一下,谢谢楼主共享 怎么我用MMC_get_volume_info()来读一个32M的MMC卡 读出来的结果是这样的
Product:32***
Total: MB
请问哪位大虾也遇到我这种情况????希望高手指点。谢了 .怎么没有人HELP ME ! 仔细研究中... 收下 顶一下楼主的好贴,我正好要用。
刚开始接触SD卡,向楼主和大家请教一些基本的问题:我采用MEGA16单片机,因AD采样的数据很多,我打算将采样的数据保存在SD卡中,数据采集完后用读卡器将数据读到电脑上分析,不知道这样用是不是要了解SD卡的文件系统规范?希望大家指教。
-----此内容被xiaotanlan于2006-11-12,12:15:30编辑过 to gl516: 可能是你的显示函数有问题,你再看看.
to 楼上: 需要了解FAT系统基本结构,你所有的数据读写要在FAT下进行 http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=198102&bbs_page_no=1&bbs_id=1000
这个FAT例子很好. 非常感谢楼主的热心!
画了一个简单的MEGA16L连SD卡的电路图,点击此处打开armok01135376.pdf
我打算程序先这样写以验证写入SD卡中的数据是否正确:连续写数据00H~FFH到SD卡中,并以文本文件(*.txt)的方式保存,不知一个文件能容纳多少次00H~FFH。然后用读卡器将写到SD卡中的数据读到电脑上显示,看是否为我写入的数据。我想应该了解FAT16文件系统原理就可以了吧,FAT32可以暂时不去管吧.另外楼主的程序读写SD卡是不在任何文件系统下进行的,楼主是否只是将SD卡当做普通EEPROM来用,这样的话读卡器是没办法读出里面的数据吧?另外,MEGA162也有SPI,楼主怎么没用硬件SPI,硬件SPI速度应该快吧?
-----此内容被xiaotanlan于2006-11-15,22:07:32编辑过 我把程序修改,以便ICC平台编译,可是没有delay_us(8)的定义,我不熟悉CVAVR,不知道这个delay_us(8)是不是延迟8us的意思? toxiaotanlan: 对,上面的程序是最底层操作,如果自己不想写USB驱动,直接使用mass storage方式查看,确实需要使用FAT系统。按照FAT系统写入数据,否则,电脑不认的。
开始为了调试方便,使用了软SPI,个人习惯罢了,不必深究。
后来在初始化的时候使用硬件SPI出问题,换了软SPI初始化,完成后,切换到硬件SPI方式读写数据。现在论坛上很多网友都调出了硬件SPI,我就没有放硬件SPI的代码,只需要稍微修改就可以了。
to knightdead: delay_us(8)是延迟8us,这个函数是cv系统库函数,你可以自己写个函数代替。 谢谢你的解答.
根据你共享的源码,我已经能够读取CSD ,CID .
调了我三天,都是硬件电路出的问题.
高兴! 非常感谢elefan,
通过参考楼主的程序我已经读出SD卡的0扇区,和用winhex读出的一样:
EB 58 90 4D 53 44 4F 53 35 2E 30 00 02 02 22 00
02 00 00 00 00 F8 00 00 3F 00 FF 00 00 00 00 00
00 CE 03 00 C7 03 00 00 00 00 00 00 02 00 00 00
01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 29 DB 5F 39 B8 4E 4F 20 4E 41 4D 45 20 20
20 20 46 41 54 33 32 20 20 20 33 C9 8E D1 BC F4
7B 8E C1 8E D9 BD 00 7C 88 4E 02 8A 56 40 B4 08
CD 13 73 05 B9 FF FF 8A F1 66 0F B6 C6 40 66 0F
B6 D1 80 E2 3F F7 E2 86 CD C0 ED 06 41 66 0F B7
C9 66 F7 E1 66 89 46 F8 83 7E 16 00 75 38 83 7E
2A 00 77 32 66 8B 46 1C 66 83 C0 0C BB 00 80 B9
01 00 E8 2B 00 E9 48 03 A0 FA 7D B4 7D 8B F0 AC
84 C0 74 17 3C FF 74 09 B4 0E BB 07 00 CD 10 EB
EE A0 FB 7D EB E5 A0 F9 7D EB E0 98 CD 16 CD 19
66 60 66 3B 46 F8 0F 82 4A 00 66 6A 00 66 50 06
53 66 68 10 00 01 00 80 7E 02 00 0F 85 20 00 B4
41 BB AA 55 8A 56 40 CD 13 0F 82 1C 00 81 FB 55
AA 0F 85 14 00 F6 C1 01 0F 84 0D 00 FE 46 02 B4
42 8A 56 40 8B F4 CD 13 B0 F9 66 58 66 58 66 58
66 58 EB 2A 66 33 D2 66 0F B7 4E 18 66 F7 F1 FE
C2 8A CA 66 8B D0 66 C1 EA 10 F7 76 1A 86 D6 8A
56 40 8A E8 C0 E4 06 0A CC B8 01 02 CD 13 66 61
0F 82 54 FF 81 C3 00 02 66 40 49 0F 85 71 FF C3
4E 54 4C 44 52 20 20 20 20 20 20 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 0D 0A 52 65
6D 6F 76 65 20 64 69 73 6B 73 20 6F 72 20 6F 74
68 65 72 20 6D 65 64 69 61 2E FF 0D 0A 44 69 73
6B 20 65 72 72 6F 72 FF 0D 0A 50 72 65 73 73 20
61 6E 79 20 6B 65 79 20 74 6F 20 72 65 73 74 61
72 74 0D 0A 00 00 00 00 00 AC CB D8 00 00 55 AA 楼主,你好。
我把MMC.C和MMC.H两个文件直接加到一个新工程中,怎么总编译不过。(我用的是codevision环境,你的两个文件什么都没有更改。)
产生的错误非常多。- 这个不是主文件吧?怎么没有发现MAIN函数。 我在调试中发现不同的sd卡的逻辑扇区0和物力扇区的对应关系不一样吗,我在16M的卡上READ_BLOCK(0+0X39)可以读到BPB,但在128M的MINI SD看上相同为制读出的数据全部为0,它的BPB的数据在READ_BLOCK(0+77)才可以读出,我真的搞不清楚,从那里可以看到这个偏移量呀?请给我一下指导,谢谢 0扇区是MBR,记录了分区表,读BPB应该在第一个分区的“0扇区" 0扇区是MBR,记录了分区表,读BPB应该在第一个分区的“0扇区" 多谢楼主!我下来学习. "多动脑子比多动手要强的多"
顶这句话 终于找到了。
各位,偶是新手。想请教几个问题。
折磨我好几个星期了。
先写过!
我第一开发SD FAT16驱动。
是一个电梯刷卡系统的一部分。
现在对SD卡硬件方面简直是无从入手;
目前,已经拿到MCU和SD卡了。
代码也参考了以上各位的。
但是我不知道应该如何开始着手。
以下是问题:
客户告诉我针脚如下:
CS p4_7
DI p4_6
CLK p4_5
DO p7_0
p4是一个Byte的地址,p4_7是这个Byte的最高位,p7也一样。
另外pd4是一个direct地址,pd7也一样。
是否还缺少什么呢??
看了一些例程,上面几乎没有写 针脚的一些信息。
小弟是第一次接触这个,帮帮我呀。
谢谢了。
#pragma ADDRESS p4_addr 03e8h /* Port P4 register */
#pragma ADDRESS pd4_addr 03eah /* Port P4 direction register */
direction 是干嘛用的??
/*------------------------------------------------------
Port P4 register
------------------------------------------------------*/
union byte_def p4_addr;
#define p4 p4_addr.byte
#define p4_0 p4_addr.b.b0 /* Port P4bit0 */
#define p4_1 p4_addr.b.b1 /* Port P4bit1 */
#define p4_2 p4_addr.b.b2 /* Port P4bit2 */
#define p4_3 p4_addr.b.b3 /* Port P4bit3 */
#define p4_4 p4_addr.b.b4 /* Port P4bit4 */
#define p4_5 p4_addr.b.b5 /* Port P4bit5 */
#define p4_6 p4_addr.b.b6 /* Port P4bit6 */
#define p4_7 p4_addr.b.b7 /* Port P4bit7 */
/*------------------------------------------------------
Port P4 direction register
------------------------------------------------------*/
union byte_def pd4_addr;
#define pd4 pd4_addr.byte
#define pd4_0 pd4_addr.b.b0 /* P4 direction registerbit0 */
#define pd4_1 pd4_addr.b.b1 /* P4 direction registerbit1 */
#define pd4_2 pd4_addr.b.b2 /* P4 direction registerbit2 */
#define pd4_3 pd4_addr.b.b3 /* P4 direction registerbit3 */
#define pd4_4 pd4_addr.b.b4 /* P4 direction registerbit4 */
#define pd4_5 pd4_addr.b.b5 /* P4 direction registerbit5 */
#define pd4_6 pd4_addr.b.b6 /* P4 direction registerbit6 */
#define pd4_7 pd4_addr.b.b7 /* P4 direction registerbit7 */
-----此内容被sd01101230于2007-03-26,10:18:27编辑过
-----此内容被sd01101230于2007-03-26,10:47:23编辑过 有人吗??
上面的PORTB是什么类型的针脚阿?
DDR又是什么针脚?
DATAPIN是???
反正那些阵脚是什么意思呀?
赐教阿。
能否发个给我啊。。。kakueiken@126.com
万分感谢。 完了 用 瑞萨的 M16C/6N4
不知道如何初始化SPI模式。
找了2天也没找到。
我以前从未接触过此类东西。有知道吗? 谢谢楼主的开源,,, 请教:
为什么在这里出现死循环:
uint8 MMC_read_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
uint8 temp;
uint16 i;
SPI_TransferByte(0xff);
MMC_Enable();
temp = Write_Command_MMC(MMC_READ_BLOCK,addr<<9);
if(temp != 0x00)
{
MMC_Disable();
return(READ_BLOCK_ERROR);
}
while(SPI_TransferByte(0xff) != 0xfe);//就这里
for(i=0;i<512;i++)
{
*Buffer++ = SPI_TransferByte(0xff);
}
SPI_TransferByte(0xff);
SPI_TransferByte(0xff);
MMC_Disable();
return(TRUE);
} 请教:
为什么在这里出现死循环:
uint8 MMC_read_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
uint8 temp;
uint16 i;
SPI_TransferByte(0xff);
MMC_Enable();
temp = Write_Command_MMC(MMC_READ_BLOCK,addr<<9);
if(temp != 0x00)
{
MMC_Disable();
return(READ_BLOCK_ERROR);
}
while(SPI_TransferByte(0xff) != 0xfe);//就这里
for(i=0;i<512;i++)
{
*Buffer++ = SPI_TransferByte(0xff);
}
SPI_TransferByte(0xff);
SPI_TransferByte(0xff);
MMC_Disable();
return(TRUE);
} 请教:
为什么在这里出现死循环:
uint8 MMC_read_sector(uint32 addr,uint8 *Buffer)
//****************************************************************************
{
uint8 temp;
uint16 i;
SPI_TransferByte(0xff);
MMC_Enable();
temp = Write_Command_MMC(MMC_READ_BLOCK,addr<<9);
if(temp != 0x00)
{
MMC_Disable();
return(READ_BLOCK_ERROR);
}
while(SPI_TransferByte(0xff) != 0xfe);//就这里
for(i=0;i<512;i++)
{
*Buffer++ = SPI_TransferByte(0xff);
}
SPI_TransferByte(0xff);
SPI_TransferByte(0xff);
MMC_Disable();
return(TRUE);
} 楼主你好,不知道你还会不会回来这里逛逛,我现在在尝试用MEGA16来读写SD卡,但对你的程序有些不明白的地方,首先,您为什么要像下面进行电平转换?其次SD读写数据的扇区地址从哪里开始呢?我接触单片机只有一个多月的时间,是个很菜的菜鸟,呵~望不吝赐教...不胜感激....
_________________ PORTA.0
|
|-|
| | 1.2K
|_|
|_________________CMD/DI(MMC/SD PIN)
|
|-|
| |2.2k
|_|
|
|
|_________________GND
|
---
- 楼主你好,不知道你还会不会回来这里逛逛,我现在在尝试用MEGA16来读写SD卡,但对你的程序有些不明白的地方,首先,您为什么要像下面进行电平转换?其次SD读写数据的扇区地址从哪里开始呢?我接触单片机只有一个多月的时间,是个很菜的菜鸟,呵~望不吝赐教...不胜感激....
_________________ PORTA.0
|
|-|
| | 1.2K
|_|
|_________________CMD/DI(MMC/SD PIN)
|
|-|
| |2.2k
|_|
|
|
|_________________GND
|
---
- 上面整个图是做TTL逻辑与CMOS逻辑转换,SD卡数据扇区需要看FAT,格式化成不同的FAT系统,数据扇区就不一样。 to flyhemcu :
上面的只是代码,需要你自己去建立工程,谢谢!
to zergl :物理扇区和逻辑扇区是不一样的,我们做底层最好看物理扇区,而非逻辑
to sd01101230 :你好像在51上移植,这个我没有试过,应该没有问题的。
to st_hb:我还没有遇到过死循环。 楼主真好人,谢谢,我现在没有接那个CMOS转换电路了,直接用3.3V的电压来供电,我现在用楼主给的代码来初始化SD卡(软件SPI模式)可以通过,初始化后我改成进入硬件SPI模式来读写数据,但没有反应,估计是程序有点问题吧,现在还在研究,发现单片机有点好玩了,呵,还是谢谢楼主... 有没有SD模式(4线模式)的初始化?请大虾指点? elefan:
你好,我看完SD卡的数据手册和参考网站里的一些sd卡原程序,因为我的编译系统是CVAVR,所以我用你的程序来初始化我的mmc卡,按照你的方法连接电路,不过我是按照硬件SPI的端口连接的(实际上还是软件SPI),以便以后用硬件SPI,在运行过程,我发觉CM0都写不进去,恳请大家帮帮忙,看是否程序问题。
* 编译软件:CodeVision AVR C 版本:1.24.48d 以上
* MCU : Atmega32-16PU 晶振: 7.37286MHz
**********************************************************************/
#include <mega32.h>
#include <delay.h> //延时函数的头文件
#define uint8 unsigned char
#define int8 signed char
#define uint16unsigned int
#define int16 signed int
#define uint32unsigned long
#define int32 signed long
/*----------------------MCU and MMC pins define------------------------*/
//SPI pins define
#define MMC_Write PORTB //SPI port register
#define MMC_Read PINB //Data PIN
#define MMC_Direction_REG DDRB //Direction register
#define SPI_DI 6 //-->MMC_DO_PIN
#define SPI_DO 5 //-->MMC_DI_PIN
#define SPI_Clock 7 //-->MMC_CLK_PIN
#define MMC_Chip_Select 4 //-->MMC_CS_PIN
#define MMC_DO_PIN MMC_Read.SPI_DI
#define MMC_DI_PIN MMC_Write.SPI_DO
#define MMC_CLK_PIN MMC_Write.SPI_Clock
#define MMC_CS_PIN MMC_Write.MMC_Chip_Select
//LED pins define
#define CMD_LED PORTA //LED LIGHT
#define CMD_LED_Direction DDRA //Direction register
#define CMD0_OK 0 //CMD 0 complete light
#define CMD1_OK 1 //CMD 1 complete light
#define CMD17_OK 2 //CMD 17 complete light
#define CMD24_OK 3 //CMD 24 complete light
#define SPI_BUSY 7 //busy led
#define CMD0_OK_LED CMD_LED.CMD0_OK
#define CMD1_OK_LED CMD_LED.CMD1_OK
#define CMD17_OK_LED CMD_LED.CMD17_OK
#define CMD24_OK_LED CMD_LED.CMD24_OK
#define MMC_BUSY_LED CMD_LED.SPI_BUSY //busy led for spi port
/*--------------------------Error define-----------------------------*/
#define INIT_CMD0_ERROR 0x01
#define INIT_CMD1_ERROR 0x02
#define WRITE_BLOCK_ERROR 0x03
#define READ_BLOCK_ERROR 0x04
/*--------------------------MMC_CS_select define-----------------------------*/
//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
#define MMC_Disable() MMC_Write.MMC_Chip_Select=1;
//set MMC_Chip_Select to low (MMC/SD-Card Active)
#define MMC_Enable() MMC_Write.MMC_Chip_Select=0;
#define nop() #asm("nop"); //asm nop defined in CVAVR
//---------------------------------------------------------------
// Prototypes
//---------------------------------------------------------------
// usart initialize
void usart_init(void);
// port initialize
void MMC_Port_Init(void);
//read a byte from MMC
uint8 Read_Byte_MMC(void);
//write a byte to MMC
void Write_Byte_MMC(uint8 value);
//read a block from MMC
uint8 MMC_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes);
//MMC initialize
uint8 MMC_Init(void);
//write data sector to MMC
uint8 MMC_write_sector(uint32 addr,uint8 *Buffer);
//write a command to MMC
uint8 Write_Command_MMC(uint8 *CMD);
//read MMC CSD
uint8 Read_CSD_MMC(uint8 *Buffer);
//read MMC CID
uint8 Read_CID_MMC(uint8 *Buffer);
//---------------------------------------------------------------------
static uint8Init_Flag; //Set it to 1 when Init is processing.
/*---------------------------------------------------------------------
函数功能: 本函数用于串行口的初始化操作。
备注: 本函数仅在主函数中调用一次即可。
----------------------------------------------------------------------*/
void usart_init(void)
{ /*设置波特率*/
UBRRL=0x03;//波特率=115200
/*接收、发送器使能*/
UCSRB=0x18;
/*设置帧格式: 8个数据位, 1个停止位*/
UCSRC=0x86;
}
/*---------------------------------------------------------------------
函数功能 :port initialize
函数入口参数:NO
函数出口参数:NO
说明 :
----------------------------------------------------------------------*/
void MMC_Port_Init(void)
{
//Config ports
MMC_Direction_REG.SPI_DI = 0; //Set Pin MMC_DI as Input
MMC_Direction_REG.SPI_Clock = 1; //Set Pin MMC_Clock as Output
MMC_Direction_REG.SPI_DO = 1; //Set Pin MMC_DO as Output
MMC_Direction_REG.MMC_Chip_Select = 1; //Set Pin MMC_Chip_Select as Output
//busy led port init
CMD_LED_Direction.CMD0_OK = 1; //set pin CMD0_LED as output
CMD_LED_Direction.CMD1_OK = 1; //set pin CMD0_LED as output
CMD_LED_Direction.CMD17_OK = 1; //set pin CMD0_LED as output
CMD_LED_Direction.CMD24_OK = 1; //set pin CMD0_LED as output
CMD_LED_Direction.SPI_BUSY = 1; //Set spi busy led port output
MMC_BUSY_LED = 1; //busy led off
CMD0_OK_LED = 1; //cmd0_ok_led off
CMD1_OK_LED = 1; //cmd0_ok_led off
CMD17_OK_LED = 1; //cmd0_ok_led off
CMD24_OK_LED = 1; //cmd0_ok_led off
MMC_CS_PIN = 1; //Set MMC_Chip_Select to High,MMC/SD Invalid.
}
//****************************************************************************
//Routine for Init MMC/SD card(SPI-MODE)
//****************************************************************************
uint8 MMC_Init(void)
{
uint8 retry,temp;
uint8 i;
uint8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
//MMC_Port_Init(); //Init SPI port
for(i=0;i<200;i++) //Wait MMC/SD ready...
{
#asm("nop");
}
Init_Flag=1; //Set the init flag
for (i=0;i<0x0f;i++)
{
Write_Byte_MMC(0xff); //send 74 clock at least!!!
}
//Send Command CMD0 to MMC/SD Card
retry=0;
do
{ //retry 200 times to send CMD0 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==200)
{ //time out
UDR = INIT_CMD0_ERROR;
while (!(UCSRA&0x20));
return(INIT_CMD0_ERROR);//CMD0 Error!
}
}
while(temp!=1);
UDR = ~INIT_CMD0_ERROR;
while (!(UCSRA&0x20));
CMD0_OK_LED = 0; //CMD 0 sent to MMC sucessful
//Send Command CMD1 to MMC/SD-Card
CMD = 0x41; //Command 1
CMD = 0xFF;
retry=0;
do
{ //retry 100 times to send CMD1 command
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{ //time out
UDR = INIT_CMD1_ERROR;
while (!(UCSRA&0x20));
return(INIT_CMD1_ERROR);//CMD1 Error!
}
}
while(temp!=0);
CMD1_OK_LED = 0; //CMD 1 sent to MMC sucessful
Init_Flag=0; //Init is completed,clear the flag
MMC_Disable();//set MMC_Chip_Select to high
return(0); //All commands have been taken.
}
//****************************************************************************
//Send a Command to MMC/SD-Card
//Return: the second byte of response register of MMC/SD-Card
//****************************************************************************
uint8 Write_Command_MMC(uint8 *CMD)
{
uint8 tmp;
uint8 retry=0;
uint8 i;
//set MMC_Chip_Select to high (MMC/SD-Card disable)
MMC_Disable();
//send 8 Clock Impulse
Write_Byte_MMC(0xFF);
//set MMC_Chip_Select to low (MMC/SD-Card active)
MMC_Enable();
//send 6 Byte Command to MMC/SD-Card
for (i=0;i<0x06;i++)
{
Write_Byte_MMC(*CMD++);
}
//get 16 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_MMC();
retry++;
}
while((tmp==0xff)&&(retry<100));
return(tmp);
}
//****************************************************************************
//Routine for reading a byte from MMC/SD-Card
//****************************************************************************
uint8 Read_Byte_MMC(void)
{
uint8 temp=0;
uint8 i;
MMC_BUSY_LED=0;
//Software SPI
for (i=0; i<8; i++) //MSB First
{
MMC_CLK_PIN=0; //Clock Impuls (Low)
if(Init_Flag) delay_us(10);
temp = (temp << 1) + MMC_DO_PIN; //read mmc data out pin
MMC_CLK_PIN=1; //set Clock Impuls High
if(Init_Flag) delay_us(10);
}
MMC_BUSY_LED=1;
return (temp);
}
//****************************************************************************
//Routine for sending a byte to MMC/SD-Card
//****************************************************************************
void Write_Byte_MMC(uint8 value)
{
uint8 i;
MMC_BUSY_LED=0;
//Software SPI
for (i=0; i<8; i++)
{//write a byte
if (((value >> (7-i)) & 0x01)==0x01) MMC_DI_PIN=1; //Send bit by bit(MSB First)
else MMC_DI_PIN=0;
MMC_CLK_PIN=0; //set Clock Impuls low
if(Init_Flag) delay_us(10);
MMC_CLK_PIN=1; //set Clock Impuls High
if(Init_Flag) delay_us(10);
}//write a byte
MMC_DI_PIN=1; //set Output High
MMC_BUSY_LED=1;
}
//****************************************************************************
//Routine for writing a Block(512Byte) to MMC/SD-Card
//Return 0 if sector writing is completed.
//****************************************************************************
uint8 MMC_write_sector(uint32 addr,uint8 *Buffer)
{
uint8 tmp,retry;
uint16 i;
//Command 24 is a writing blocks command for MMC/SD-Card.
uint8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
#asm("cli"); //clear all interrupt.
addr = addr << 9; //addr = addr * 512
CMD = ((addr & 0xFF000000) >>24 );
CMD = ((addr & 0x00FF0000) >>16 );
CMD = ((addr & 0x0000FF00) >>8 );
//Send Command CMD24 to MMC/SD-Card (Write 1 Block/512 Bytes)
retry=0;
do
{//Retry 100 times to send command.
tmp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{
return(tmp); //send commamd Error!
}
}
while(tmp!=0);
//Before writing,send 100 clock to MMC/SD-Card
for (i=0;i<100;i++)
{
Read_Byte_MMC();
}
//Send Start Byte to MMC/SD-Card
Write_Byte_MMC(0xFE);
//Now send real data Bolck (512Bytes) to MMC/SD-Card
for (i=0;i<512;i++)
{
Write_Byte_MMC(*Buffer++); //send 512 bytes to Card
}
//CRC-Byte
Write_Byte_MMC(0xFF); //Dummy CRC
Write_Byte_MMC(0xFF); //CRC Code
tmp=Read_Byte_MMC(); // read response
if((tmp & 0x1F)!=0x05) // data block accepted ?
{
MMC_Disable();
return(WRITE_BLOCK_ERROR); //Error!
}
//Wait till MMC/SD-Card is not busy
while (Read_Byte_MMC()!=0xff){};
//set MMC_Chip_Select to high (MMC/SD-Card Invalid)
MMC_Disable();
return(0);
}
//****************************************************************************
//Routine for reading data Registers of MMC/SD-Card
//Return 0 if no Error.
//****************************************************************************
uint8 MMC_Read_Block(uint8 *CMD,uint8 *Buffer,uint16 Bytes)
{
uint16 i; uint8 retry,temp;
//Send Command CMD to MMC/SD-Card
retry=0;
do
{//Retry 100 times to send command.
temp=Write_Command_MMC(CMD);
retry++;
if(retry==100)
{
return(READ_BLOCK_ERROR); //block write Error!
}
}
while(temp!=0);
//Read Start Byte form MMC/SD-Card (FEh/Start Byte)
while (Read_Byte_MMC() != 0xfe){};
//Write blocks(normal 512Bytes) to MMC/SD-Card
for (i=0;i<Bytes;i++)
{
*Buffer++ = Read_Byte_MMC();
}
//CRC-Byte
Read_Byte_MMC();//CRC - Byte
Read_Byte_MMC();//CRC - Byte
//set MMC_Chip_Select to high (MMC/SD-Card invalid)
MMC_Disable();
return(0);
}
//***************************************************************************
//Routine for reading CID Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
//***************************************************************************
uint8 Read_CID_MMC(uint8 *Buffer)
{
//Command for reading CID Registers
uint8 CMD[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
uint8 temp;
temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes
return(temp);
}
//***************************************************************************
//Routine for reading CSD Registers from MMC/SD-Card (16Bytes)
//Return 0 if no Error.
//***************************************************************************
uint8 Read_CSD_MMC(uint8 *Buffer)
{
//Command for reading CSD Registers
uint8 CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
uint8 temp;
temp=MMC_Read_Block(CMD,Buffer,16); //read 16 bytes
return(temp);
}
void main(void)
{
usart_init();
MMC_Port_Init();
MMC_Init();
while (1)
{
MMC_Init();
};
} 最近想用8051来采集GPS模块的经纬度数据存储在SD卡,SPI模式。我不了解AVR单片机,也不想重新学习了。不知道有谁移植过?请贴上程序。谢谢!!在网络上面找了好久,AVR的还有一些资料。
还有就是发送给SD卡的命令中有CRC位。程序中好象没有关注。CRC位不用管吗???等待ING! 看见了。CRC直接得出来了,就不用计算了。大致上应该这样移植到8051。
经过Keil检验,没有语法错误。逻辑错误就不知道了!赶明白上电测试就知道了!!
楼主都不给main函数。初始化有点难度。
欢迎给我邮件!
代码如下:(附件同样!)
点击此处下载armok01173896.zip
//2007-9-12 10:43redFe开始写
//联系我:wb4916@sohu.com
#include <AT89x52.H>
sbit spiSDCS= P2^7;
sbit spiSDDI= P2^6;
sbit spiSDDO= P2^4;
sbit spiSDCLK = P2^5;
sbit spiSDLED = P2^3;
#define uchar unsigned char //one byte
#define uintunsigned int //two bytes
#define ulong unsigned long //four bytes
#define slong signed long //four bytes
uchar CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
//向SD卡写入一个字节。
void writeByteSD(uchar value)
{
uchar i;
spiSDLED = 0;
for(i=0;i<8;i++)
{
if(value&0x80)
spiSDDI = 1;
else
spiSDDI = 0;
spiSDCLK = 0;
;
spiSDCLK = 1;
;
value <<= 1;
}
spiSDDI= 1;
spiSDLED = 1;
}
//从SD卡读取一个字节。
uchar readByteSD(void)
{
uchar i;
uchar dataRead = 0x00;
spiSDLED = 0;
for(i=0;i<8;i++)
{
spiSDCLK = 0;
;
if(spiSDDO)
dataRead += 1;
spiSDCLK = 1;
;
dataRead <<= 1;
}
spiSDLED = 1;
return(dataRead);
}
uchar writeCommandSD(void)
{
uchar temp;
uchar retry=0;
uchar i;
spiSDCS = 1;
writeByteSD(0xFF);
spiSDCS = 0;
//发6个字节的命令
for(i=0;i<6;i++)
{
writeByteSD(CMD);
}
//响应16位,第1个字节丢弃
readByteSD();
do{
temp = readByteSD();
retry++;
}while((0xFF==temp)&&(retry<100));
return(temp);
}
//使SD卡由SD模式切换到SPI模式
uchar initSD(void)
{
uchar i;
uchar temp;
uchar retry = 0x00;
for(i=0;i<200;i++)
;
//在上电后,主机启动 SCK 及在 CMD 线上发送 74 个高电平的信号,
//接着发送 CMD0 进入 SPI模式,然后发送 CMD1 激活初始化进程。
for(i=0;i<0x0F;i++)
writeByteSD(0xFF);
do{
temp = writeCommandSD();
retry++;
if(200 == retry)
return(1);
}while(temp != 1);
//发送CMD0
CMD = 0x41;
CMD = 0xFF;
retry = 0x00;
do{
temp = writeCommandSD();
retry++;
if(200 == retry)
return(2);
}while(temp != 0);
spiSDCS = 1;
return(0);
}
void main(void)
{
initSD();
} 我用了楼主的程序,能够读CID 正确 但是调用
void MMC_get_data_LBA(unsigned long lba, unsigned int Bytes,unsigned char *buffer)
读出来的数据不正确。 MMC_GotoSectorOffset(0,500);
void MMC_get_data_LBA(unsigned long lba, unsigned int Bytes,unsigned char *buffer)
读出来的数据 ,55 AA是有的 其他的都没有 FA 33 C0 8E D0 BC 00 7C 8B F4 50 07 50 1F FB FC BF 00 06 B9 00 01 F2 A5 EA 1D 06 00 00 BE BE 07 B3 04 80 3C 80 74 0E 80 3C 00 75 1C 83 C6 10 FE CB 75 EF CD 18 8B 14 8B 4C 02 8B EE 83 C6 10 FE CB 74 1A 80 3C 00 74 F4 BE 8B 06 AC 3C 00 74 0B 56 BB 07 00 B4 0E CD 10 5E EB F0 EB FE BF 05 00 BB 00 7C B8
这是执行
MMC_GotoSectorOffset(0,0);
MMC_get_data_LBA(0,100,buf);
中前100个字节的数据,
而WINHEX读出来的数据是
EB 58 90...... 【89楼】 ilan2003 小松工程
WINHEX应该去读物理磁盘才能读到你列出的数据
FA 33 C0 8E D0 BC
一看就是到这是MBR的数据
EB 58 90......
是DBR的数据
要读到必须先去处理MBR才能知道DBR在哪,不过有的卡是没有MBR的,所以程序还要去判断是否有MBR 哦谢谢了 看来程序的确是调通了
EB 58 90......是分区一的数据
FA 33 C0 8E D0 BC。。是启动分区的数据。
用物理分区打开,找到FA 33 C0 8E D0 BC...这些数据,
EB 58 90......在地址 0000CA00中发现了
所以物理分区包含了包括DBR,和MBR的数据,而打开逻辑分区只有DBR的数据对吧 可以这么理解。
“EB 58 90......在地址 0000CA00中发现了”
中的地址在MBR中会有记载的,就是在MBR中的分区表中的记录着。所以可以根据MBR的分区表找到分区1 我已经通过程序能够访问EB 58 90......的数据了,
但是奇怪的是
调用函数
MMC_get_data_LBA(0,100,buf);//中间的那个参数最大只能到达107超过程序就死机了 这个代码我没看过
中间那个参数是什么?数据长度?难道是数组溢出了? 数据长度我定义数组
uint08 ddd[];
这样会益处吗?我用的M8 有1k的ram 那奇怪了,你看看是不是程序里面也用了数组,如果来两个ddd不就挂了,
我都是动态分配内存的,用malloc 和 free来操作 C学的不好 malloc 和 free重来都不用的 LZ能否给出CAVR的硬件SPI,我正需要啊,谢谢! ding