>>502 >>503 ご親切にありがとうございます。
明日、クロックや信号を直に生成してポートから送ることを試してみたいと思います。
ちなみにMPLAB SIMでは、通信完了を待つ
while(PIR1bits.SSPIF == 0);で割り込みが来ずに、
無限ループになってしまいます。割り込みは全て有効にしてるはずなんだが・・・。
もしかしたらこの辺の設定がおかしい?続きはまた明日報告します。
505 :
502:2009/06/30(火) 01:27:48 ID:eu/kVUW9
>>504 昔のソースからエッセンスだけ抜き取った
素人なのでセオリーに則しているかは知らないけど動作は確認してる
CSだけ書き換えて試してくれ
#define SPI_INTERRUPT_FLAG PIR1bits.SSPIF
#define SPI_CS LATCbits.LATC0
void mySPIInit(void)
{
OpenSPI(SPI_FOSC_4, MODE_00, SMPEND);
}
void mySPIWrite(unsigned char data)
{
unsigned char tmp;
tmp = SPIBUF;
SPI_INTERRUPT_FLAG = 0;
SPIBUF = data; // write byte to SSP1BUF register
while( !SPI_INTERRUPT_FLAG ); // wait until bus cycle complete
tmp = SPIBUF; // Clear the SPIBUF
}
unsigned char mySPIRead(void)
{
unsigned char tmp;
tmp = SPIBUF;
SPI_INTERRUPT_FLAG = 0;
SPIBUF = 0xFF;
while(!SPI_INTERRUPT_FLAG);
return SPIBUF;
}
void MMCReset(void) //SPIモードへの移行
{
unsigned char ret;
SPI_CS = HIGH;
for(ret=0;ret<10;ret++)mySPIWrite(0xff);//ダミーの80クロック
SPI_CS = LOW;
mySPIWrite(0x40);
mySPIWrite(0x00);
mySPIWrite(0x00);
mySPIWrite(0x00);
mySPIWrite(0x00);
mySPIWrite(0x95);
while((ret=mySPIRead())!=0x01);
do{
SPI_CS = HIGH;
mySPIWrite(0xff);
SPI_CS = LOW;
ret=MMCcommand(1,0);
}while(ret != 0x00);
SPI_CS = HIGH;
}
そこまで甘やかさなくても良いんじゃねぇの?
507 :
natu:2009/06/30(火) 09:53:02 ID:d1hCoZqr
>>504 ADCON1でポートをデジタルI/Oにするか、MMC_SELECTをLATB2で
アクセスすれば動作しませんか?
508 :
774ワット発電中さん:2009/06/30(火) 10:26:05 ID:QKZyXf13
>>504 フラグ監視で待つんだから割り込みは有効にしちゃ駄目だよ
割り込み有効にしたらありもしない割り込みベクタに飛んで戻ってこなくなるんじゃないか
毎晩お世話になっております。
>>501 >>504などでうまく行かない者です。
いろいろありがとうございます。レスいただいたことは全て試していますが、
未だ状況はかわりません。
いまのところ原因はPICの設定にあるとにらんでいます。
というのも、ついさっき解ったことに、SDカードを一切接続せず、
DINをVccに接続してもSSPBUFには0x00が受信されていることがわかりました。
訂正:
DINはDOUTの間違いです、DOUTに何もつながず、
プルアップ抵抗を介してVccをつながれております。
プルアップなのに0x00だと?
Port初期化で ADCON1かANSEL設定忘れてない?
それから 出力bit操作は
PORTBbits.RBx じゃなく
LATBbits.LATBx にすると吉
テスター当ててみたら
516 :
774ワット発電中さん:2009/07/02(木) 10:11:53 ID:ScfpYnpw
>>510, 511
SDカードを接続する以前の問題じゃねえの。
SDカード接続せず、DINとDOを接続して、
自己ループで送信データが受信できるか試したほうが・・・
517 :
774ワット発電中さん:2009/07/02(木) 23:11:53 ID:LhbNQ8lL
こんばんは、SDカード読み書きがうまく行かず、連日お世話になっている者です。
SPI通信さえ行えないと騒いでいた件は、単なるプログラムミスでした。
>>501のソースで デバッグ用に入れた WriteEEPROM(0,response,1); は
正しくは &response で、デバッグ上の単純ミスでしたorz
再びSDカードを接続してみたところ、はじめはまた意味不明なコードが返ってくることがあったのですが、
配線を動かしているうちにいつの間にかデータ読み書きがうまくできるようになりました!!嬉しいです。
うまく行かなかったのはどうもノイズや電圧の揺らぎが影響していた可能性が大きいです。
いずれにせよみなさんのおかげです、本当にありがとうございます!!
しかし、まだ問題があります。(続く)
>>// レスポンスをPICのEEPROMに書き込み。
>>// (この関数は長い間使っているため信頼性は高いです)
>>
>>WriteEEPROM(0,response,1);
>>517に続き、残る問題なのですが、
0x00100000に読み書きしたつもりが、なぜか0x000E0E00を読み書きします。
どんなアドレスに書いたとしても0x1F200(269セクタ)前にズレてしまいます。
セクタ読み込みツールは複数のソフトで確認していますが、
どれでも読み込み結果は同じでした。これはSDカードの仕様の何か!?
0x00000000に書き込み、さらにそれを読み込んだところ、正常に処理が行え、
さらにSDカードのフォーマットを求められるようになりました。
つまり領域はあるということですね。
あまりくわしいことは解らないのですが、
ツールでは論理ドライブ名を指定して読み込むので、
物理ドライブとしてのセクターを頭から読んでいないようです。
249セクタはMBRなんだと思います。なんとなく解決しました。
521 :
774ワット発電中さん:2009/07/02(木) 23:55:14 ID:mq27eYiS
ググれよ
ここ質問スレじゃないし
俺様のデバッグに付き合えって態度だもんな
何だかんだ言って、みんな楽しんでるくせに(はぁと
気色悪い
526 :
774ワット発電中さん:2009/07/04(土) 06:27:50 ID:yj4xCHRd
CMD16のブロックサイズは、実際どれぐらいまで小さくできるでしょうか?
1〜32バイトぐらいになりますか?
これはSDカードに依存するんでしょうか?
>>520 Disk Probe とか \\.\PHYSICALDRIVE とかで
調べてみれば?
>>526 仕様ではカード依存。
Partial Writeがサポートされていれば1バイトでもOKらしい。
ありがとうございました
16バイト単位ぐらいで読み書きできればマイコンストレージにちょうどいいので
実験してみます
マイコンストレージならそんなに容量要らないと思うから各ブロックの頭数バイトずつだけ使ってあとはダミーデータで埋めておくのも手だな。
読み出しはともかく、書き込みは512が下限なのがほとんど。
なるほど
512バイト単位で先頭nバイトだけ使って、
以降は読み(書き)捨てるという方式も考慮すべきですね
ちょっともったいないですが2Gのカードで512バイト中、
32バイトしか使わないとしても、
2000000000 / 512 * 32 = 125000000で約120MB使えるから十分ですね
SunDisk MicroSD2GでCMD16で32バイトにして試してみました。
読み込みは上手くいきましたが、書き込みはどうやっても成功しませんでした。
素直に512固定で組んだ方が良さそうです。残念。
「Partial WriteがサポートされていればOK」だから、CSDレジスタのWRITE_BL_PARTIALが
1かどうかだけ調べればいいよ。
>>533をCMD9でCSD読んでみました(128bit=16byte)
00 26 00 32 5f 5a 83 ae fe fb cf ff 92 80 40 df
後ろから見ていき、
df 11011111=> 1101111 1 (CRC7 1b)
40 01000000 => 0 1 0 0 00 00 (FileFormatGrp copy PermWriteProt TempWriteProt FileFormat RSV2)
80 10000000 => 10 0 00000 (WRITE_BL_LEN_L WRITE_BL_PARTIAL RSV5)
92 10010010 => 1 00 100 10 (WP_GRP_ENA RSV2 R2W_FACTOR WRITE_BL_LEN_H)
この解釈で合ってますでしょうか?
このデータからすると
WRITE_BL_LENが 1001(=9)ではなく1010(=10)なので、1024Byteということかな?
WRITE_BL_PARTIALは0でした。
同様に6バイト目5a(0101 1010) 83(1 0 0 0 00 11)から 、
READ_BL_LEN は 1010(=10) 1024Byte、
READ_BL_PARTIALは1でした。
読み込みだけが成功するのに納得できました。
SDHCは、アドレスの指定法がx512のパラグラフになった、
という以外は以前のSDとそれ程変わりないと考えて良いでしょうか?
538 :
774ワット発電中さん:2009/07/11(土) 12:14:14 ID:M3BdOjVb
SDHCでは、CMD0 ---> CMD1 では初期化できないので
CMD0 CMD8 CMD58 ACMD41 .... で初期化してるなら
セクタ指定以外は同じ
SPIモードでの話しだけど。
ATmega88のSPIで、SDの読み書きをやってみたんですが、
水晶20MHzだと、SPR1=0 SPR0=0 SPI2X=0 のfosc/4で
5Mbps(610KB/sec)が限界でした。
SDとのSPIはこの辺りが限界と考えるべきしょうか?
それとも高クロックのMCUではもっといくのでしょうか。
540 :
774ワット発電中さん:2009/08/16(日) 16:22:25 ID:7N1LcDfv
答えは君の書き込みの中にある
>>540 この件ですが、SI,CLK,CSに送る3.3Vを抵抗分圧で作ってましたが、
抵抗値が高すぎるのが原因だったみたいです。
低く抑えたらmega88でのSPI最大クロックの10MHzで通信できました。
どれだけ書き込むかわからないので、先にeraseコマンド送って
消しておいてから、マルチブロックライトしようとしてますが、この作戦で
書き込み待ち(10msくらいが限界)を避けられますか?
やってみれば?
そうそう
SDカードを自作するスレ と勝手に読み間違えて危うく突っ込みそうになった俺 orz
〜えっさ、ほっさ、えっさ、ほっさ、おれたちゃ兄弟、どこきる兄弟♪
カメラからの映像を、
SDカードに記録してくれるICって無いかな?
SDカードのバージョン(ver.1or2)とファイルシステム(FAT16or32)の確認方法を教えてもらえませんか
ありがとうございます
読み出しサイズを512から128にするのはうまく行ったけど、
64にしようとしたらうまくいかない
そんなことってある?
552の原因が判った
ブロックサイズを変えると、その境界をまたいで読み出しができなかった
512バイト単位の物理ブロックの境界なら判るけど、
論理的な読み出し単位の境界で、なんでそんな制約が?