Работа с MMC/SD картой памяти.

Делимся исходными кодами

Работа с MMC/SD картой памяти.

Сообщение Radioded » 28 мар 2009, 18:12

Когда-то подключал карточку памяти к МК ATmega32, с файловой системой не стал заморачиваться, спокойно можно писать побайтно, а читать блочно. На компе надо будет ставить WinHEX чтобы работать без файловой системы, там можно считать или записать каждый байт.
Вот сам исходник:
Код: Выделить всё
/*    
   MMC/SD application - SPI mode
   ATMega32
   LCD 16*2

*/

//_____ INCLUDES _________________________________________

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <lcd.h>

#define MMC_CS_1       PORTB |=0b00001000                  
#define MMC_CS_0       PORTB &=0b11110111
#define OK 0x01
#define FAIL 0x02

//#define cbi(reg, bit) (reg&=~(1<<bit))
//#define sbi(reg, bit) (reg|= (1<<bit))

/** MMC/SD card SPI mode commands **/
/*
#define CMD0  0x40    // software reset
#define CMD1  0x41    // brings card out of idle state
#define CMD9  0x49    // ask card to send card speficic data (CSD)
#define CMD10 0x4A    // ask card to send card identification (CID)
#define CMD12 0x4C    // stop transmission on multiple block read
#define CMD13 0x4D    // ask the card to send it's status register
#define CMD16 0x50    // sets the block length used by the memory card
#define CMD17 0x51    // read single block
#define CMD18 0x52    // read multiple block
#define CMD24 0x58    // writes a single block
#define CMD25 0x59    // writes multiple blocks
#define CMD27 0x5B    // change the bits in CSD
#define CMD28 0x5C    // sets the write protection bit
#define CMD29 0x5D    // clears the write protection bit
#define CMD30 0x5E    // checks the write protection bit
#define CMD32 0x60    // Sets the address of the first sector of the erase group
#define CMD33 0x61    // Sets the address of the last sector of the erase group
#define CMD34 0x62    // removes a sector from the selected group
#define CMD35 0x63    // Sets the address of the first group
#define CMD36 0x64    // Sets the address of the last erase group
#define CMD37 0x65    // removes a group from the selected section
#define CMD38 0x66    // erase all selected groups
#define CMD42 0x6A    // locks a block
#define CMD58 0x7A    // reads the OCR register
#define CMD59 0x7B    // turns CRC off
*/

char buffer[15];
unsigned int i;
char mmc_block[512];
char number;

char hello[]="   Hello!";
char cmd0_ok[] = "CMD0 OK";
char cmd0_fail[] = "CMD0 FAIL!!!";
char cmd1_ok[] = "CMD1 OK";
char cmd1_fail[] = "CMD1 FAIL!!!";
char mmc_init_ok[] = "MMC init OK";
char mmc_error[]= "Error";
char mmc_write_error[] = "Write Error";
char mmc_read_error[] = "Read Error";

unsigned char temp=0;
unsigned int i=0;

ISR(INT0_vect){
   GICR &= ~(1<<INT0);
   
   _delay_ms(15);
   if ((PIND & 0b00000100) == 0){      // OK
   
      PORTD ^=(1<<7);          // toggle Led
      
   }
   
   _delay_ms(30);
   GICR |= (1<<INT0);

}

void spi_init(void){

   DDRB = 0b10111111;                                                      // all outputs, MISO - input
   SPCR = (0<<SPIE)|(1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0);      // master OSC/8

}


unsigned char spi_transmit(unsigned char data){

   SPDR = data;
   while(!(SPSR & (1<<SPIF)));                     // wait until transmitting
   return SPDR;
}

unsigned char mmc_command( unsigned char befF, unsigned int AdrH, unsigned int AdrL, unsigned char befH){

   spi_transmit(0xFF);
   spi_transmit(befF);
   spi_transmit((AdrH & 0xFF00)>>8);
   spi_transmit(AdrH & 0x00FF);
   spi_transmit((AdrL & 0xFF00)>>8);
   spi_transmit(AdrL & 0x00FF);
   spi_transmit(befH);
   spi_transmit(0xFF);
   
   return spi_transmit(0xFF);
}

unsigned char mmc_init(void){

   MMC_CS_1;
   _delay_ms(5);

   for(i=0; i<10; i++) {
     temp = spi_transmit(0xFF);
     _delay_us(10);
   }

   MMC_CS_0;
   _delay_ms(5);
   
   if (mmc_command(0x40, 0, 0, 0x95) == 0x01){            // CMD0
     clearlcd();
     _delay_ms(10);
     showstr(cmd0_ok);
   } else{
     clearlcd();
     _delay_ms(10);
     showstr(cmd0_fail);
     return 0;
   }
   

   while(mmc_command(0x41,0,0,0xFF) != 0x00) _delay_ms(10);   // CMD1
   
   clearlcd();
   _delay_ms(10);
   showstr(cmd1_ok);
   
   //if (Command(0x50,0,512,0xFF) !=0) showstr(mmc_error);      // CMD16 - set block length

   return OK;
}


void mmc_write(void){

   if (mmc_command(0x58,0,0,0xFF) !=0){   // CMD24 - write a single block
      
     clearlcd();
     showstr(mmc_write_error);
   
   }
   
   spi_transmit(0xFF);
   spi_transmit(0xFF);
   spi_transmit(0xFE);
   
   for (i=0; i<512; i++) spi_transmit(i & 0xFF);
   
   spi_transmit(0xFF);
   spi_transmit(0xFF);
   temp = spi_transmit(0xFF);
   
   if ( (temp & 0b00011111) != 0b00000101){
      
     clearlcd();
     showstr(mmc_write_error);
      
   }
   
   while(spi_transmit(0xFF) != 0xFF);

}

void mmc_read(void){

   if ((mmc_command(0x51,0,0,0xFF)) != 0){
      
     clearlcd();
     showstr(mmc_read_error);
   
   }
   
   while (spi_transmit(0xFF) != 0xFE);
   
   for(i=0; i < 512; i++) mmc_block[i] = spi_transmit(0xFF);              // Передача байта данных

   spi_transmit(0xFF);                                          // CRC16
   spi_transmit(0xFF);


}

void delay_ms(unsigned int t){
   unsigned int i;
   for (i=0; i<t; i++) _delay_ms(1);
}

int main (void) {

   
   lcdinit();
   spi_init();
   
   DDRD = 0b10000000;          // inputs and PD7 - output
   PORTD |=(1<<2);
   PORTB = 0b00001000;
   
   MCUCR = 0b00001010;         // Falling edge
   GICR |= (1<<INT0);

   clearlcd();
   showstr(hello);

   delay_ms(400);

   if (mmc_init() == OK){
   
   _delay_ms(100);
   clearlcd();
   _delay_ms(10);
   showstr(mmc_init_ok);
   
   }
   
   SPCR = (0<<SPIE)|(1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0);      // CK/2
   SPSR = (1<<SPI2X);
   
   clearlcd();
   
   delay_ms(600);
   mmc_write();

   delay_ms(100);
   mmc_read();
   delay_ms(600);
   
   for (i=0; i<512; i++){
   
      clearlcd();
      _delay_ms(10);
      lcddata(mmc_block[i]);
      delay_ms(300);
   }


   while(1);
   
}
Вложения
mmc.rar
Исходник для SD/MMC и библиотека для LCD 16*2 (без неё не будет работать showstr() и т.д.)
(6.2 КБ) Скачиваний: 1695
Аватара пользователя
Radioded
Site Admin
 
Сообщения: 180
Зарегистрирован: 07 ноя 2008, 02:47
Откуда: Москва

Работа с MMC/SD картой памяти.

Сообщение mas_nk » 05 май 2009, 11:56

А распиновку карт памяти и схему подключения можете выложить?
mas_nk
 
Сообщения: 19
Зарегистрирован: 26 мар 2009, 15:18

Re: Работа с MMC/SD картой памяти.

Сообщение Radioded » 05 май 2009, 23:52

Вот распиновка и схема включения карточки памяти MMC/SD
mmc.gif
распиновка карты памяти MMC/SD
mmc.gif (25.8 КБ) Просмотров: 23649

а вот схема включения при питании 5 вольт:
electron.png
подключение
electron.png (5.13 КБ) Просмотров: 23511
Аватара пользователя
Radioded
Site Admin
 
Сообщения: 180
Зарегистрирован: 07 ноя 2008, 02:47
Откуда: Москва

Re: Работа с MMC/SD картой памяти.

Сообщение TeXHaPb » 12 апр 2010, 16:23

У меня вопрос, может немного глупый, но все-таки...
Как я понял, ответственность за Write-Protection ложится целиком на устройство чтения. Существует ли возможность программного обхода этого ограничения (может быть, к примеру, возможность программирования каких-либо регистров Card-Reader'а) для абстрактного устройства чтения и для вот такого в частности:
Код: Выделить всё
[17490.921243] usb 1-3: New USB device found, idVendor=058f, idProduct=6366
[17490.921247] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[17490.921249] usb 1-3: Product: Mass Storage Device
[17490.921251] usb 1-3: Manufacturer: Generic
[17490.921253] usb 1-3: SerialNumber: 058F63666433
[17490.922056] scsi13 : SCSI emulation for USB Mass Storage devices
[17496.048646] scsi 13:0:0:0: Direct-Access     Multiple Card  Reader     1.00 PQ: 0 ANSI: 0

Меня это интересует с точки зрения - надежно ли использование защищенной от записи Flash'ки на компьютере с неизвестным ПО, например вирусами.
TeXHaPb
 
Сообщения: 1
Зарегистрирован: 12 апр 2010, 16:14

Re: Работа с MMC/SD картой памяти.

Сообщение sandro » 16 окт 2011, 18:17

Не уверен, что я создал тему в правильном разделе, если что перенестите пожалуйста. Суть проблемы такова - есть SD карта на 6 гекаров, после возврата ее мне, карта стала 32 метра. Точнее комп предлагает отформатировать 32 метра. Куда делись остальные гекатры и как с них восстановить инфу?
sandro
 
Сообщения: 2
Зарегистрирован: 16 окт 2011, 18:14

Re: Работа с MMC/SD картой памяти.

Сообщение sandro » 13 ноя 2011, 11:22

Чертов спамер................
sandro
 
Сообщения: 2
Зарегистрирован: 16 окт 2011, 18:14


Вернуться в Исходники



Кто сейчас на конференции

Зарегистрированные пользователи: Bing [Bot]