Код: Выделить всё
#include <mega128.h>
#include <delay.h>
////////////////////////////////////////////////////////////////////////////////////////////
// ATmega128:
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// microSD (HC) 3,3 V
// TX -
// RX - 7 mA.
// Ожидание - 0 mA.
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////// crc (!) System
unsigned int crc; // crc
unsigned int bcrc; // crc буфер
unsigned int a; // a - счёт
unsigned int b; // b - счёт
/////////////////////////////////////////////// счёт
unsigned char x; // x - счёт
/////////////////////////////////////////////// счёт
unsigned char x1; // x1 - счёт
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// fcrc:
void fcrc(void)
{
crc ^= bcrc;
for( a = 0; a < 16; a++ ){
if (crc & 0x8000) crc = ( crc << 1 ) ^ 0x1021; // CRC-16-CCITT // 0x1021
else crc = crc << 1;
};
}
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// microSD:
/////////////////////////////////////////////// программный SPI3 microSD:
unsigned char tx3; // tx3 - SPI3
unsigned char rx3; // rx3 - SPI3
unsigned char mask3; // mask3 - SPI3
////////////////////////////////////////// программный SPI3/4МГц/0.000.060 microSD:
void SPI3(void)
{
rx3=0; // сброс RX
mask3=0b10000000;
do {
if (tx3 & mask3) PORTD.7 = 1;// выход MOSI
else PORTD.7 = 0;// выход MOSI
delay_us(2);
PORTD.6=1; // выход SCK
if (PIND.5) rx3 |= mask3; // вход MISO
PORTD.6=0; // выход SCK
mask3=(mask3>>1);
}
while (mask3);
delay_us(2);
PORTD.7 = 0; // сброс MOSI
}
/////////////////////////////// таймаут microSD:
unsigned char tm_microSD; // таймаут microSD.
/////////////////////////////// error microSD:
unsigned char error_microSD_EEPROM; // error_microSD_EEPROM. -начальное 0.
/////////////////////////////// буфер microSD:
unsigned char bufer_microSD[512]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// TX_microSD:
void TX_microSD(unsigned long x)
{
/////////////////////// crc bufer_microSD[512]:
crc=0xFFFF;
for (b=0;b<510;b=b+2) {
bcrc=bufer_microSD[b]; bcrc=(bcrc<<8)|bufer_microSD[b+1]; fcrc();
};
bufer_microSD[510]=(crc>>8); // crc
bufer_microSD[511]=crc; // crc
///////////////////////////////////////////////
PORTB.0=0; // SS microSD
/////////////////////// запись Data:
tx3=0x58; SPI3(); // 01xx xxxx + Номер команды - CMD24
tx3=(x>>24); SPI3(); // адрес
tx3=(x>>16); SPI3(); // адрес
tx3=(x>>8); SPI3(); // адрес
tx3=x; SPI3(); // адрес
tx3=0x00; SPI3(); // 0000 0000. CRC - 0
// ответ R1: 0000 0000 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); // STATUS R1 0000 0000
//////////////////////////////////////////////////////////////////////////////// метка:
tx3=0xFE; SPI3(); // 0xFE метка для команды - CMD24
//////////////////////
for (a=0; a<512; a++) {
tx3=bufer_microSD[a]; SPI3(); // bufer_microSD > microSD
};
////////////////////
tx3=0x00; SPI3(); // CRC - 0
tx3=0x00; SPI3(); // CRC - 0
/////////////////////////////////////////////////////////// ответ - данные приняты 0xE5:
tx3=0xFF; SPI3(); // SPI пустой
/////////////////////////////////////////////////// ждём окончания записи... OUT = 0xFF:
while ( (x1 != 0xFF) && (tm_microSD != 255) ) {
tx3=0xFF; SPI3(); x1=rx3; // MOSI 0x00 > MOSI 0xFF // -цикл 34...53
tm_microSD++;
};
//////////////
if (tm_microSD == 255) { // таймаут microSD:
error_microSD_EEPROM |= 0b00010000; // 0001 0000 - error microSD_TX
};
tm_microSD = 0; // сброс таймаут tm_microSD.
////////////////////////////////////////////////////////////////
PORTB.0=1; // SS microSD
////////////////////////////////////////////////////////////////////////////////////////
// microSD - ток = 0 mA.
}
////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// RX_microSD:
void RX_microSD(unsigned long x)
{
PORTB.0=0; // SS microSD
/////////////////////// читать Data:
tx3=0x51; SPI3(); // 01xx xxxx + Номер команды - CMD17
tx3=(x>>24); SPI3(); // адрес по 512 байт
tx3=(x>>16); SPI3(); // адрес по 512 байт
tx3=(x>>8); SPI3(); // адрес по 512 байт
tx3=x; SPI3(); // адрес по 512 байт
tx3=0x00; SPI3(); // 0000 0000. CRC - 0
// ответ R1: 0000 0000 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1=rx3; // STATUS R1 0000 0000
////////////////////////////////////////////////////////////////////// ждём метку (0xFE):
while ( (x1 != 0xFE) && (tm_microSD != 255) ) {
tx3=0xFF; SPI3(); x1=rx3; // MOSI 0xFF > MOSI 0xFE // -цикл ...5
tm_microSD++;
};
//////////////
if (tm_microSD == 255) { // таймаут microSD:
error_microSD_EEPROM |= 0b00000100; // 0000 0100 - error microSD_RX
};
//////////////
tm_microSD = 0; // сброс таймаут tm_microSD.
//////////////////////////////////////////////////////////////////////////// читать Data:
for (a=0; a<512; a++) {
tx3=0xFF; SPI3(); bufer_microSD[a]=rx3;// microSD > bufer_microSD
//////////////////////////////////////////////////////////
};
tx3=0x00; SPI3(); // CRC - 0
tx3=0x00; SPI3(); // CRC - 0
///////////////////////
PORTB.0=1; // SS microSD
//////////////////////////////////////////////////////////////////////////////
tx3=0xFF; SPI3(); // SPI пустой (!)
// microSD - ток = 0 mA.
///////////////////// crc bufer_microSD[512] RX:
crc=0xFFFF;
for (b=0;b<512;b=b+2) {
bcrc=bufer_microSD[b]; bcrc=(bcrc<<8)|bufer_microSD[b+1]; fcrc();
};
/////////////////////////// проверка crc:
if (crc != 0) {
error_microSD_EEPROM |= 0b00000010; // error_microSD_crc
};
///////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
////////////////////////////////////////////// SPI2 программный microSD
DDRD.5=0; // MISO
PORTD.5=1; // MISO +(!) 0xFF
DDRD.6=1; // SCK
PORTD.6=0; // SCK
DDRD.7=1; // MOSI
PORTD.7=0; // MOSI
DDRB.0=1; // SS
PORTB.0=1; // SS
////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////// инициализация microSD:
///////////////////////////////// Преамбула - 80 синхроимпульсов.
for (x=0; x<10; x++) { tx3=0xFF; SPI3(); }; // "11111111"
PORTB.0=0; // SS microSD
/////////////////////////////////////////////////////////////////
//сброс microSD и перевод в режим SPI:
tx3=0x40; SPI3(); // 01xx xxxx + Номер команды - CMD0
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x95; SPI3(); // CRC7
// ответ R1: 0000 0001 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0001
//состояния интерфейса microSD (напряжение хоста и любой шаблон):
tx3=0x48; SPI3(); // 01xx xxxx + Номер команды - CMD8
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x01; SPI3(); // 0000 0001 -напряжение хоста 2.7 – 3.6 V
tx3=0xAA; SPI3(); // 1010 1010 -1010 1010 -проверочный шаблон
tx3=0x87; SPI3(); // CRC7
// ответ R7: 0000 0001; 0000 0000; 0000 0000; 0000 0001; 1010 1010
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); // STATUS R1 0000 0001
tx3=0xFF; SPI3(); // 0000 0000
tx3=0xFF; SPI3(); // 0000 0000
tx3=0xFF; SPI3(); // 0000 0001 -напряжение хоста 2.7 – 3.6 V
tx3=0xFF; SPI3(); x1 = rx3; // 1010 1010 -проверочный шаблон
/////////////////////////////////////////////////////////////////
while ( (x1 != 0x00) && (tm_microSD != 255) ) { // MOSI 0xFF > MOSI 0x00 // -цикл 2...21
//////////////////////////////// ждём ответ R1: 0000 0000 STATUS:
//старт microSD: // microSD версия v.2 и выше.
tx3=0x77; SPI3(); // 01xx xxxx + Номер команды - CMD55
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // CRC7
// ответ R1: 0000 0001 - команда microSD принята
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0001
//
tx3=0x69; SPI3(); // 01xx xxxx + Номер команды - CMD41
tx3=0x40; SPI3(); // 0100 0000 - хост поддерживает карту памяти высокой емкости SD
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // 0000 0000
tx3=0x00; SPI3(); // CRC7
// ответ R1: 0000 0000 - инциализация microSD завершена.
tx3=0xFF; SPI3(); // задержка 1 байт 0xFF
tx3=0xFF; SPI3(); x1 = rx3; // STATUS R1 0000 0000
/////////////////////////////////////////////////////////////////////
tm_microSD++; // таймаут microSD.
};
//////////////
if (tm_microSD == 255) { // таймаут microSD:
error_microSD_EEPROM |= 0b00000001; // 0000 0001 - error init microSD
};
tm_microSD = 0; // сброс таймаут tm_microSD.
///////////////////////////////////////////
PORTB.0=1; // SS microSD
//////////////////////////////////////////////////////////////////////////////////
// microSD - ток = 7 mA.
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
RX_microSD(x);
TX_microSD(x);
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
}