?? 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提供的接法,確實按它的接法是沒法收到響應的。我疏忽了,在帖上去之前沒有更改過來?,F在問題就是在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 + -