MMC Hafıza Kart Uygulaması

Başlatan DumrulBey, 18 Kasım 2004, 00:35:09

DumrulBey

Merhaba,


http://www.cc5x.de/MMC/


C ustaları! Bu yukarıdaki devreyi aşağıdaki kodlar ile çalışacak bir şekilde CCS PIC C'ye uyarlayabilir miyiz? Yani yapın demiyorum, yapabilirsek uyarlamaya çalışacağım. Şimdi uzman olan arkadaşlar olayı şak diye fark eder herhalde...

#include <C:\cc5\16F877.H>
// Speicherschutz 12-13-4-5=aus, Debug 11=aus,ProgrammFlash 9=an, EEpromRead 8=an, NiederVoltProgr 7=aus
// NiederVoltReset 6=an, EinschaltTimer 3=an, WachDogTimer 2=aus, Oszilator 01=XC
#pragma config |= 0b.11.111101.11.00.10

#pragma bit CS @ PORTC.2	//Ausgang für Chip Select

#pragma origin 100		// Ab Adresse 100 im Programmspeicher
//*********************************************************************

void InitUSART()
{
BRGH=1;			// Hohe Geschwindigkeit für Datenübertragung
//SPBRG=129;		// (9600   baud @ 20MHz input clock)
//SPBRG=64;		// (19200  baud @ 20MHz input clock)
//SPBRG=32;		// (38400  baud @ 20MHz input clock)
SPBRG=10;		// (115200 baud @ 20MHz input clock)
SPEN = 1;		// Set_Serial_Pins;
SYNC = 0;		// Set_Async_Mode;
TX9 = 0;		// Set_8bit_Tx;
RX9 = 0;		// Set_8bit_Rx;
CREN = 1;		// Enable_Rx;
TXEN = 1;		// Enable_Tx;
RCIE=0;			// Rx Interrupt aus
}
//**********************************************************************

void SerString(const char *str)	// String seriell senden
{
char ps;
ps = *str;		// Pointer auf Start des Strings ins ps
while(ps>0)		// Prüfen ob String zu Ende ist
	{
	str++;			// Pointer auf nächstes Zeichen erhöhen
	if (ps== 0) break;	// Prüfen ob String zu Ende ist
	while(!TXIF);   	// Prüfen ob Register TXREG leer ist
	TXREG =ps ;		// Datenbyte senden
    	ps = *str;		// Inhalt des Pointers ins ps
	}
}
//********************************************************************

char SPI(char d)		// Über SPI-Schnittstelle senden
{				// 
SSPBUF=d;
while (!BF);			// 	Warten bis gesendet ist
return SSPBUF;			// gleichzeitig empfangen
}
//**********************************************************************

char Command(char befF,uns16 AdrH,uns16 AdrL,char befH )
{				// Einen Befehl zum MMC senden
char a;
SPI(0xFF);
SPI(befF);
SPI(AdrH.high8);
SPI(AdrH.low8);
SPI(AdrL.high8);
SPI(AdrL.low8);
SPI(befH);
SPI(0xFF);
return SPI(0xFF);		// Response als Rückgabewert
}
//**************************************************************************

bit MMC_Init()
{
// Init SPI
SMP=0;		// Input ist gültig in der Mitte des Clock's
CKE=0;		// Bei steigender Flanke Datenübernahme
CKP=1;		// High ist passiver Zustand
SSPM1=1;	// Geschwindigkeit f/64(312kHz), Master
//SSPM0=1;	// Geschwindigkeit f/16(1,25MHz), Master
SSPEN=1;	// SPI Ein

CS=1;		// MMC-Disabled

char i;		// Variablen

//MMC in SPI-Modus starten, Reset
for(i=0; i < 10; i++)SPI(0xFF);		// 10*8=80 mal takten
CS=0;					// MMC-Enabled

// CMD0
if (Command(0x40,0,0,0x95) !=1)goto Fehler ; 	// Reset

st:						// Wenn MMC nicht da ist, bleibt
// CMD1						// Programm hier stehen
if (Command(0x41,0,0,0xFF) !=0) goto st ;	// CMD1 solange wiederholen
/*
// CID auslesen
if (Command(0x4A,0,0,0xFF) !=0) goto Fehler;	// Karten ID-Nummer
for(i=0; i < 20; i++)
{
while(!TXIF);
TXREG =SPI(0xFF);
}

// CSD auslesen					// Kartenspezifische Daten
if (Command(0x49,0,0,0xFF) !=0) goto Fehler;
for(i=0; i < 20; i++)
{
while(!TXIF);
TXREG =SPI(0xFF);
}
*/
// Set Lenge (Default ist 512 Byte)
//if (Command(0x50,0,16,0xFF) !=0) goto Fehler;	// 16 Byte-Mode für Lesen

return 1;
Fehler:
return 0;
}
//**************************************************************************

void main(void)
{
INTCON=0;				// Interrupts aus
ADCON1=0x6;				// PortA Digital
TRISC=0b.1101.0011;			// sck rc3-0, sdo rc5-0, CS rc2-0.
TRISB=0b.0000.0010;   			// RB2>TX, RB1>RX
uns16 i;				// Variable 0...65535
InitUSART();				// Serielle Datenübertragung initialisieren
SerString("Ich bin ON ");		// Startmeldung
if (MMC_Init()) SerString("MMC ON ");	// MMC Initialisieren und Meldung falls OK!
//******************************************************************************

// Lesen  512 Byte-Mode 
if (Command(0x51,0,512,0xFF) !=0) SerString("Lese_resp_Fehler ");
while(SPI(0xFF) != 0xFE);			// Warten auf 0xFE, Anfang jeder Datenübertr.
for(i=0; i < 512; i++)
	{
	while(!TXIF);   			// Prüfen ob Register TXREG leer ist
	TXREG =SPI(0xFF);			// Datenbyte senden
	}
SPI(0xFF);				// Am Ende 2 Byte's ohne Bedeutung
SPI(0xFF);
//************************************************************************


// Schreiben  512 Byte-Mode
if (Command(0x58,0,512,0xFF) !=0) SerString("Schreib_resp_Fehler ");
SPI(0xFF);
SPI(0xFF);
SPI(0xFE);
for(i=0; i < 512; i++)
	{
	SPI('M');
	}
SPI(255);				// Am Ende 2 Byte's ohne Bedeutung senden
SPI(255);
i=SPI(0xFF);
i &=0b.0001.1111;
if (i != 0b.0000.0101) SerString("Schreib_Fehler ");
while(SPI(0xFF) !=0xFF);		// warten auf Ende des Busy -Zustandes.

//**********************************************************************
while(1);				//hier bleibt Programm stehen
}

Sevgiler, saygılar...[/b]
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)

aliuzun2004

Bende bu konuda bir ara araştırmıştım. Ama baştan çöküş yaşadım. Önce devreyi kurmak istedim ve malzeme aramaya başlamadım. Malesef mmc yi takacak yuvayı bir türlü bulamadım. Eğer mmc yuvasının nerde satıldığını biliyorsanız bu projeye yeniden başlayabilirim ve edindiğim deneyimleri sizlerle seve seve paylaşırım.

DumrulBey

Merhaba,

Arkadaşlar bu yıl içinde bir MMC uygulaması yapmam lazım. Hemde temellerini Ocak ayında atmam gerekiyor. Bu konuda pek bilgim yok. Uygulama yapanların püf noktalarını yeni açılan bölüme veya bu başlık altına bekliyorum. Biraz önce bir araştırma yaptım da www.microchipc.com adresine yeni bir başlık eklenmiş.



Kodları inceledim çok zor görünmüyor. Bu uygulamayı İngiliz Ed Waugh kodlamış. Peki arkadaşlar biz Türk'ler neler yaptık? Söz veriyorum ben de öğrendikçe sizlerle paylaşacağım. Ama bir başlangıç yapmak lazım. Uygulayanlar için soruyorum neler tavsiye edersiniz?

// Written by Ed Waugh 2004, www.edwaugh.co.uk

// for the original source, and hundreds more examples of PIC C code, see:
// http://www.microchipc.com/sourcecode/#mmc

int mmc_init();
int mmc_response(unsigned char response);
int mmc_read_block(unsigned long block_number);
int mmc_write_block(unsigned long block_number);
int mmc_get_status();


/************************** MMC Init **************************************/
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */

int mmc_init()
{
int i;

SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4 | SPI_SS_DISABLED);

*0x94 |= 0x40;                          // set CKE = 1 - clock idle low
*0x14 &= 0xEF;                          // set CKP = 0 - data valid on rising edge

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)

for(i=0;i<10;i++)                       // initialise the MMC card into SPI mode by sending clks on
{
        SPI_WRITE(0xFF);
}

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on) tells card to go to spi mode when it receives reset

SPI_WRITE(0x40);                        // send reset command
SPI_WRITE(0x00);                        // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95);                        // precalculated checksum as we are still in MMC mode

puts("Sent go to SPI\n\r");

if(mmc_response(0x01)==1) return 1;     // if = 1 then there was a timeout waiting for 0x01 from the mmc

puts("Got response from MMC\n\r");

i = 0;

while((i < 255) && (mmc_response(0x00)==1))     // must keep sending command if response
{
        SPI_WRITE(0x41);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 1;                   // if >= 254 then there was a timeout waiting for 0x00 from the mmc

puts("Got out of idle response from MMC\n\r");

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)

SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)

        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
puts("Got set block length response from MMC\n\r");
return 0;
}

/************************** MMC Get Status **************************************/
/* Get the status register of the MMC, for debugging purposes */

int mmc_get_status()
{

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)

        SPI_WRITE(0x58);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);                //
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
return 0;
}

/************************** MMC Write Block **************************************/

int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;

varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);

puts("Write block\n\r");                // block size has been set in mmc_init()

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)

        SPI_WRITE(0x58);                // send mmc write block
        SPI_WRITE(HIGH(varh));
        SPI_WRITE(LOW(varh));
        SPI_WRITE(HIGH(varl));
        SPI_WRITE(0x00);                // always zero as mulitples of 512
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
puts("Got response to write block\n\r");

SPI_WRITE(0xFE);                        // send data token

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

SPI_WRITE(i2c_eeprom_read(HIGH(i),LOW(i)));     // send data

}

SPI_WRITE(0xFF);                        // dummy CRC
SPI_WRITE(0xFF);

if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;

puts("Got data response to write block\n\r");

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)
return 0;
}



/************************** MMC Read Block **************************************/
/**** Reads a 512 Byte block from the MMC and outputs each byte to RS232 ****/

int mmc_read_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl;

varl=((block_number&0x003F)<<9);
varh=((block_number&0xFFC0)>>7);

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)

        SPI_WRITE(0x51);                // send mmc read single block command
        SPI_WRITE(HIGH(varh));      // arguments are address
        SPI_WRITE(LOW(varh));
        SPI_WRITE(HIGH(varl));
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;   // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)

puts("Got response to read block command\n\r");

if((mmc_response(0xFE))==1) return 1;   // wait for data token

puts("Got data token\n\r");

        for(i=0;i<512;i++)
        {
                putc(SPI_READ(0xFF));               // we should now receive 512 bytes
        }

SPI_READ(0xFF);                 // CRC bytes that are not needed
SPI_READ(0xFF);

OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)
SPI_WRITE(0xFF);                // give mmc the clocks it needs to finish off

puts("\n\rEnd of read block\n\r");

return 0;
}

/************************** MMC get response **************************************/
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/

int mmc_response(unsigned char response)
{
        unsigned long count = 0xFFFF;           // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point

        while(SPI_READ(0xFF) != response && --count > 0);

        if(count==0) return 1;                  // loop was exited due to timeout
        else return 0;                          // loop was exited before timeout
}

Sevgiler, saygılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)

aceofbase

Arkadaşlar denmeden bir yerden kopyalamışsınız sonrada bilgi paylaşımı diyosunuz hadi be sizde bi deneyin çalışmadığınız göreceksiniz ayıp bence çok ayıp bir yerden kopyala getir buraya yapıştır yalan yanlış çalışmıyor bu kardeşim deneyin görün

OG

aceofbase,

Burası, kod kopyalayıp yapıştırmaya engel bir yer değil.

Yazan arkadaş "ben yaptım çalıştı" deyip yalan söylemiş de değil.

Yani burası daha ilk mesajda saçmalama yeri değil.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

yalnayak

aceofbase ,
bu ne ruzgar,bu ne boran.mesaji iyi okumamissiniz belli.
devre kursaydin da calissaydi, kopyalayip yapistirmaya bu tepkiyi verirmiydin?
ya da 'paylasim icin sagol' deyip gidecekmiydin?
:oops:
Kızımın iffeti batmakta rezîlin gözüne... Acırım tükürüğe billâhi, tükürsem yüzüne..! MEHMED AKİF ERSOY  Kardan Adaminla,GUNES'e calim mi satiyorsun?

mustafacifci

arkadaşlar merak etmeyin ben geçen sene yaptım 1 ay uğraştım
sonunda çalıştırdım ve ses ile ilgili 3 adet projeyi yapıp sattım .
eğer biraz sabrederseniz kaynak kodlarını ve şemayı gonderirim.
çalışması garanti

Macera

Sayın Dumrulbey
İkinci mesajınızdaki devrede MMC 5 volt ilemi besleniyor?
3.3 volt olması gerekmiyormu?

MMC konektörü ile geçenlerde forumda konu açılmıştı.
Ama denemelerinizde eski floopy disklerinizin konnektörünü kullanabilirsiniz.

"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

Macera

Sayın aceofbase
Ben devreyi denedim çalıştı.
Yalnız bilmeniz gerekirki kartdan karta fark var.
Bendeki  denemelerde program bir MMC kartında çalışmadı ama diğerinde çalıştı.
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts