📄 430读写sd卡.txt
字号:
430读写SD卡
[MSP430开发工具] 微控设计网原创作品:MC430F14实验板
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-15 10:29:58 第2楼
void initSPI (void)
{
UCTL0 = SWRST; // 8-bit SPI Master **SWRST**
UTCTL0 = CKPH | SSEL1 | SSEL0 | STC; // SMCLK, 3-pin mode, clock idle low, data valid on rising edge, UCLK delayed
UBR00 = 0x20; // 0x02: UCLK/2 (4 MHz), works also with 3 and 4
UBR10 = 0x00; // -"-
UMCTL0 = 0x00; // no modulation
UCTL0 = CHAR | SYNC | MM | SWRST; // 8-bit SPI Master **SWRST**
UCTL0 &= ~SWRST; // clear SWRST
ME1 |= USPIE0; // Enable USART1 SPI mode
while (!(IFG1 & UTXIFG0)); // USART1 TX buffer ready (empty)?
}
// Initialize MMC card
char initMMC (void)
{
//raise SS and MOSI for 80 clock cycles
//SendByte(0xff) 10 times with SS high
//RAISE SS
int i;
// Port 3 Function Dir On/Off
// 3.0-mmcCD Out 0 - card inserted
// 3.1-Dout Out 0 - off 1 - On -> init in SPI_Init
// 3.2-Din Inp 0 - off 1 - On -> init in SPI_Init
// 3.3-Clk Out - -> init in SPI_Init
// 2.6-mmcCS Out 0 - Active 1 - none Active
P2DIR |= BIT6;
P3SEL |= 0x0E;
P3SEL &= ~0x11;
P3OUT |= 0x10;
P3DIR |= 0x0A;
initSPI();
//initialization sequence on PowerUp
CS_LOW();
for(i=0;i<10;i++)
spiSendByte(0xff);
CS_HIGH();
for(i=0;i<=9;i++)
spiSendByte(0xff);
return (mmc_GoIdle());
}
char mmc_GoIdle(void)
{
char response=0x01;
CS_LOW();
//Send Command 0 to put MMC in SPI mode
mmcSendCmd(MMC_GO_IDLE_STATE,0,0x95);
//Now wait for READY RESPONSE
if(mmcGetResponse()!=0x00)//应该是收到响应R1,也就是0,可是我总是收到是高电平,也不知是不是太快了,没收到,示波器看了,没有低电平的产生
return MMC_INIT_ERROR;
while(response==0x00)
{
CS_HIGH();
spiSendByte(0xff);
CS_LOW();
mmcSendCmd(MMC_SEND_OP_COND,0x00,0xff);
response=mmcGetResponse();
}
CS_HIGH();
spiSendByte(0xff);
return (MMC_SUCCESS);
}
// mmc Get Responce
char mmcGetResponse(void)
{
//Response comes 1-8bytes after command
//the first bit will be a 0
//followed by an error code
//data will be 0xff until response
int i=0;
char response;
while(i<=64)
{
response=spiSendByte(0xff);
if(response==0x00)break;
if(response==0x01)break;
i++;
}
return response;
}
[虚拟仪器工具] 虚拟示波器、逻辑分析仪、虚拟信号发生器
DC
荣誉:网站成员
职务:总版主
级别:光明使者
威望:+8
魅力:2
积分:2508
经验:117358
文章:2462
注册:06-03-07 23:42
发表: 2007-01-15 11:51:20 第3楼
这位兄弟,真不好意思。上次发表过的是转载国外的一位工程师的程序。SD卡操作我也没做过。
希望大家积极参与回贴,共同创造有活力的论坛。
[购买开发工具操作流程] 购买前必须了解如何操作
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-15 15:29:07 第4楼
谢谢版主
我用示波器看了,结果并不是没有响应,有响应R1,只是在执行这个函数mmcGetResponse()之前,响应已经给过了。也就是说,在命令和响应有个时间间隔N(CR),这个间隔很短,以至于还没等到我执行接受响应语句,响应就已经发完了,真FT。
可是我还是不明白,我的MCLK为8M,而我的SPI的CLOCK仅为250K,按SD卡的技术文档命令和响应时间间隔N(CR)为0~8个时钟个数,单位为8个Clock周期。我认为单位为8个SPI的Clock周期,也就是0~64个SPI的Clock周期。这样算来,执行语句的速度怎么也应该能收到响应吧!
困惑中,DC版主提供点高见
har mmc_GoIdle(void)
{
char response=0x01;
CS_LOW();
//Send Command 0 to put MMC in SPI mode
mmcSendCmd(MMC_GO_IDLE_STATE,0,0x95);
//Now wait for READY RESPONSE
if(mmcGetResponse()!=0x00)
return MMC_INIT_ERROR;
[购买开发工具操作流程] 购买前必须了解如何操作
debug
荣誉:网站成员
职务:论坛版主
级别:骑士
积分:286
经验:16351
文章:164
注册:06-03-07 23:49
发表: 2007-01-15 23:54:10 第5楼
// 3.0-mmcCD Out 0 - card inserted
// 3.1-Dout Out 0 - off 1 - On -> init in SPI_Init
// 3.2-Din Inp 0 - off 1 - On -> init in SPI_Init
// 3.3-Clk Out - -> init in SPI_Init
// 2.6-mmcCS Out 0 - Active 1 - none Active
上面是你的MCU IO配置吗?
P3.1 MOSI(SIMO) :主出从入
P3.2 MISO(SOMI) :主入从出
你现在的接法有错误!
你把SD/MMC 卡做为SPI主机了。实际上MPS430才是主机。
这样一来你不是把430的SPI OUT,与SD/MMC卡的OUT 相连了。
你把SPI与SD/MMC卡的DIN,DOUT交换一下口,最好是串一个100~330的电阻保护。
试试看!
仔细看看下图的SD卡接口
MCU SIMO ----->DI
MCU SOMI ----->DO
[MSP430开发工具] 微控设计网-MSP430FET仿真器
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-16 14:18:56 第6楼
首先谢谢debug,感谢您能花时间回答我的问题
您看的太仔细了。这是ti提供的接法,确实按它的接法是没法收到响应的。我疏忽了,在帖上去之前没有更改过来。现在问题就是在430执行接受响应的语句之前,响应已经发生。我想应该是spi接受有问题。这个问题在软件或者是在硬件上如何解决?
我用示波器看SD卡的输出,其输出一直为高(111……),在执行完mmcSendCmd(MMC_GO_IDLE_STATE,0,0x95);后产生数据为(……11)0 1000 0000(11……)但是我读RXBUF0里的值为0xFF,而0x01这个我想要的值没有收到!
我想在软件上解决的方法就是读控制SD卡的CLOCK,在430没有执行接受响应的语句之前,430不提供时钟信号,这样SD卡应该不会提供响应(个人想法)。但是430的spi模块似乎是只要MOSI和 MISO有数据传输就提供CLOCK!所以我困在这里。
另外,就是为什么在CSPY中执行一个函数,GO比单步运行的时间快很多,是不是执行GO频率和单步频率不一样?
[ 这个贴子最后由george500在2007-1-16 14:47:50编辑过 ]
[虚拟仪器工具] 虚拟示波器、逻辑分析仪、虚拟信号发生器
debug
荣誉:网站成员
职务:论坛版主
级别:骑士
积分:286
经验:16351
文章:164
注册:06-03-07 23:49
发表: 2007-01-16 16:24:54 第7楼
SPI 接口的通信方式是:
写数据:主机MOSI向从机发SCK和MOSI数据。不理会MISO.
读数据:主机向从机发SCK,并读取MISO的数据。不理会MOSI。
430的SPI我用过,我的测试方法是这样的。
将430的SPI口的MIOS,MOSI相连。
用下面的程序测试
//输入SPI输出数据,返回SPI 8CLK 的读数。
unsignd char SPI(unsiged char OutData);
unsigned char a,i;
for(i=0; i<128; i++)
{
a=SPI(i);
}
我当时测的结果是这样的。
OUT IN
0 xx
1 0
2 1
3 2
......
SPI是一个8位的移位寄存器,只有8BIT满了后,我们的程序才读得出来,
但是上面的例子中,写的同时马上读,是读不到的,原因是从8位的移位寄存器到总线要1个以上的CPU时钟才可。
你先把你的SPI训服了,再弄你的SD卡。
[购买开发工具操作流程] 购买前必须了解如何操作
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-18 11:32:49 第8楼
程序通过了,发出复位命令后就收到正确的响应了。
确实是SPI的事!
可是又发现问题
430发出命令计算卡容量:cardSize=MMC_ReadCardSize();计算出的结果是2032 664 576bytes
但是卡放入读卡器中用WinHex查看,它给出的结果是Free Space:2030 960 640bytes,Total Capacity(总容量):2031 226 368bytes。(这个Free Space是总容量减去文件系统所占的容量后的真正的数据区容量)。问题就是430计算的卡容量与用WinHex查看的结果不一致。
我觉得这个卡容量的误差倒是不大,可能是两个程序计算容量的算法上的不一致。更要命的问题是,430执行写SD卡命令mmcWriteSector(266240, buffer); (266240是我用WinHex查看SD卡真正数据区的开始地址,前面是引导扇区、FAT和根目录区),然后执行读SD卡命令mmcReadSector(266240, bbuffer);用cspy中watch查看buffer和bbuffer两个数组,发现内容确实一样,但是我用WinHex查看查看SD卡地址266240,没有写入任何数全是0!
不知debug对这种现象有什么高见
再次感谢debug的解释,谢谢您
[虚拟仪器工具] 虚拟示波器、逻辑分析仪、虚拟信号发生器
debug
荣誉:网站成员
职务:论坛版主
级别:骑士
积分:286
经验:16351
文章:164
注册:06-03-07 23:49
发表: 2007-01-18 13:00:55 第9楼
实读: 2032 664 576bytes 79280000
WinHex:2030 960 640bytes 790E0000
相差1A0000 1.625MByte
如果你可以确定你写入数据到SD卡后,读的回的Buffer不是同一个缓冲区,或是同一个缓冲区但清0过。那就可以证明你的R/W 没有问题。
另外你用WinHex查看下下这两下扇,有没有一个是你想要的数据:
266240 + (0x1A0000 / 512)
266240 - (0x1A0000 / 512)
[购买开发工具操作流程] 购买前必须了解如何操作
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-18 22:55:07 第10楼
看到了,
相差了249个扇区!我怎么就没想到在附近的扇区看看是否有数。
这样的话,按照块地址来写数据,在做文件系统时就很麻烦。假设做成文件的话,文件大小为一个簇,在数据区的一个簇写入数据,同时在FAT1FAT2中标记一个字节和在根目录中占用32个字节,而SD卡写操作只能以扇区的首地址写入,但是在FAT1FAT2中430必须在指定地址写一个字节(根目录也是一样)。这样的话用430以文件形式存储在SD卡将很难实现
是不是只能做一个文件大小正好为512个簇?(这样在FAT中可以直接写)
[虚拟仪器工具] 虚拟示波器、逻辑分析仪、虚拟信号发生器
debug
荣誉:网站成员
职务:论坛版主
级别:骑士
积分:286
经验:16351
文章:164
注册:06-03-07 23:49
发表: 2007-01-19 08:59:06 第11楼
这是一个FAT16文件系统的源码,你试试把你的读/写扇区的函数改到里面,再继续玩你的SD卡。
有几点注意:
1.扇区 不等于 簇,在FAT系统中记录的是簇号。 一个簇由多个扇区组成。在调试FAT16文件系统,时你最好在网上下一个关于 磁盘文件系统 的资料放在一边参考。
2.在FAT系统读写文件总是有问题时,记得对SD卡做一下格式化,但一定要选择FAT16类型,通常默认的是FAT32的。
此主题相关文件 083905.rar
[购买开发工具操作流程] 购买前必须了解如何操作
george500
级别:新手上路
积分:14
经验:1117
文章:10
注册:07-01-04 16:45
发表: 2007-01-19 11:06:19 第12楼
太感谢了,debug。文件系统程序写的好清楚!佩服佩服啊 Orz
我刚才试了一下,就是RAM小了点
那个全局变量BUFFER占用了512字节
看来得换一个1610了,149是不行了
[MSP430开发工具] 微控设计网-MSP430FET仿真器
powlo
级别:新手上路
积分:1
经验:14
文章:1
注册:07-03-15 14:33
发表: 2007-03-15 14:43:13 第13楼
楼上的朋友们你们好,小弟也正在用430做SD卡的项目,能不能发点例程给我,让小弟也参考一下,谢谢!!y-sheng@163.com
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -