Уведомления
Очистить все

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

6 Посты
4 Пользователи
0 Likes
22.1 Тыс. Просмотры
Radioded
(@sergey)
Estimable Member Admin
Присоединился: 5 лет назад
Сообщения: 184
Topic starter  

Когда-то подключал карточку памяти к МК 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 = 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);
delay_ms(300);
}

while(1);

}


Цитата
mas_nk
(@mas_nk)
Active Member
Присоединился: 15 лет назад
Сообщения: 19
 

А распиновку карт памяти и схему подключения можете выложить?


ОтветитьЦитата
Radioded
(@sergey)
Estimable Member Admin
Присоединился: 5 лет назад
Сообщения: 184
Topic starter  

Вот распиновка и схема включения карточки памяти MMC/SD

а вот схема включения при питании 5 вольт:


ОтветитьЦитата
TeXHaPb
(@texhapb)
New Member
Присоединился: 14 лет назад
Сообщения: 1
 

У меня вопрос, может немного глупый, но все-таки...
Как я понял, ответственность за 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'ки на компьютере с неизвестным ПО, например вирусами.


ОтветитьЦитата
sandro
(@sandro)
New Member
Присоединился: 12 лет назад
Сообщения: 2
 

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


ОтветитьЦитата
sandro
(@sandro)
New Member
Присоединился: 12 лет назад
Сообщения: 2
 

Чертов спамер................


ОтветитьЦитата