CLK ür SD-Karte festlegen.

OP #3680347
Lesenswert?

Hallo, guten Tag.
Ich habe hier ein Timingplan für die SD-Karte.
Da müssen ja bestimmte Clocks eingehalten werden.

Ich habe 50Mhz beim DE1, welche CLK-Länge muss ich jetzt bitte beim FPGA 
für ein Clocks nehmen?

Danke.
Gruss
Angehängte Dateien:
OP #3680764
Lesenswert?

Ich möchte die Daten am PC lesen.
Ich möchte nur in 512 Byte-Blöcke lesen und schreiben weiter nicht.

GRuss

So wie hier:
1
//Routine zur Initialisierung der SD-Karte (SPI-MODE)
2
uint8_t sd_init(void)
3
{
4
  uint16_t sd_timeout = 0;
5
  uint16_t i;
6

7
  //Konfiguration des Ports, an den die SD-Karte angeschlossen wurde
8
    /*
9
     D6  (do) SS    = SD_Chip_Select
10
     B5  (do) MOSI  = SPI_DO
11
     B6  (di) MISO  = SPI_DI
12
     B7  (do) SCK   = SPI_Clock
13
    */
14

15
  DDRB |= (1<<7) | (1<<5) | (1<<4);              //SPI konfigurieren
16
  DDRD |= (1<<6);
17
  
18
  PORTD |= (1<<6);                  //Disable
19

20
  for(i = 0; i < 200; i++)
21
  {
22
    __asm__ __volatile__ ("nop" ::);               //Wartet eine kurze Zeit
23
  }
24

25
  //Aktivieren des SPI - Bus, Clock = Idle LOW
26
  //SPI Clock teilen durch 128 (Wir werden erst nach der Initialisierung richtig schnell)
27
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0) | (1<<SPR1);          //Enable SPI, SPI im Master Mode  
28
  SPSR = (0<<SPI2X);
29

30
  //Bringe SD-Karte in den SPI-Mode
31
  for (i = 0; i<10; i++)
32
  {                       //Sendet 20*8 Clocks an die SD-Karte
33
    sd_writeByte(0xff);
34
  }
35

36
  //Sendet Kommando CMD0 an SD-Karte
37
  uint8_t CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};          //CMD0
38
  while(sd_writeCommand(CMD) != 1)
39
  {
40
    if (sd_timeout++ > 300) return 1;              //Abbruch bei CMD0
41
  }
42
  
43
  for (i = 0; i<10; i++)
44
  {                       //Sendet 20*8 Clocks an die SD-Karte
45
    sd_writeByte(0xff);
46
  }
47
  
48
  //Sendet Kommando CMD1 an SD-Karte
49
  sd_timeout = 0;
50
  CMD[0] = 0x41;                  //CMD1
51
  CMD[5] = 0xFF;
52
  while(sd_writeCommand(CMD) != 0)
53
  {
54
    if (sd_timeout++ > 600)
55
    {
56
      sd_timeout = 0;
57
      CMD[0] = 0x77;                  //ACMD
58
      CMD[5] = 0x01;
59
      while(sd_writeCommand(CMD) != 0)
60
      {
61
      if (sd_timeout++ > 600) return 2;             //Abbruch bei CMD1 und ACMD
62
      }
63
    }
64
  }
65
  
66
  //SPI Bus auf maximale Geschwindigkeit  (Clk/2)
67
  SPCR &= ~((1<<SPR0) | (1<<SPR1));              //Clear SPR0+SPR1
68
  SPSR = SPSR|(1<<SPI2X);                //Set SPI2X
69

70

71
  PORTD |= (1<<6);                  //Disable
72
  return(0);                    //OK
73
}
74

75

76

77
//Sendet ein Kommando an die SD-Karte
78
uint8_t sd_writeCommand(uint8_t *cmd)
79
{
80
  uint8_t tmp = 0xff;
81
  uint16_t sd_timeout = 0;
82
  uint8_t i;
83
  //SD_Chip_Select high (SD-Karte Inaktiv) 
84
  PORTD |= (1<<6);                  //Disable
85

86
  //sendet 8 Clock Impulse
87
  sd_writeByte(0xFF);
88

89
  //SD_Chip_Select low (SD-Karte Aktiv)
90
  PORTD &= ~(1<<6);                  //Enable
91

92
  //sendet 6 Byte Commando
93
  for (i = 0; i<0x06; i++)                //sendet 6 Byte Kommando zur MMC/SD-Karte
94
  {
95
    sd_writeByte(*cmd++);
96
  }
97

98
  //Wartet auf ein gueltige Antwort von der MMC/SD-Karte
99
  while (tmp == 0xff)
100
  {
101
    tmp = sd_readByte();
102
    if (sd_timeout++ > 500)
103
    {
104
      break;                    //Abbruch da die MMC/SD-Karte nicht Antwortet
105
    }
106
  }
107
  return tmp ;
108
}
109

110

111
//Routine zum Empfangen eines Bytes von der SD-Karte 
112
uint8_t sd_readByte(void)
113
{
114
  uint8_t sd_Byte = 0;
115
  SPDR = 0xff;
116
  while(!(SPSR & (1<<SPIF)))
117
  {
118
    ;
119
  }
120
  sd_Byte = SPDR;
121
  return sd_Byte;
122
}
123

124
//Routine zum Senden eines Bytes zur SD-Karte
125
void sd_writeByte(uint8_t Byte)
126
{
127
  SPDR = Byte;   //Sendet ein Byte
128
  while(!(SPSR & (1<<SPIF)))                //Wartet bis Byte gesendet wurde
129
  ;
130
}
131

132

133
//Routine zum Schreiben eines Sektors
134
uint8_t sd_writeSektor(void)
135
{
136
  uint8_t cmd[6];
137
  uint32_t sd_l_sektor_index = sd_sektor_index * 512;  //die Adressierung der SD-Karte wird in Bytes angegeben, Sektor wird von Blocks in Bytes umgerechnet
138

139

140
  cmd[0] = 0x58;
141
  cmd[1] = ((sd_l_sektor_index & 0xFF000000) >>24 );
142
  cmd[2] = ((sd_l_sektor_index & 0x00FF0000) >>16 );
143
  cmd[3] = ((sd_l_sektor_index & 0x0000FF00) >>8 );
144
  cmd[4] = 0;
145
  cmd[5] = 0xFF;
146

147
  //Sende Kommando cmd24 an SD-Karte (Write 1 Block/512 Bytes)
148
  uint8_t sd_error = sd_writeCommand(cmd);
149
  if (sd_error != 0)
150
  {
151
    return(sd_error);
152
  }
153

154
  //einen Moment warten und Clock senden
155
  for(uint8_t i = 0; i < 100; i++)
156
  {
157
    sd_readByte();
158
  }
159
  
160
  
161
  //Sende Start Byte an SD-Karte
162
  sd_writeByte(0xFE);
163
  
164
  
165
  //Schreiben des Blocks (512Bytes) auf SD-Karte
166
  for(sd_data_index = 0; sd_data_index < 512; sd_data_index++)
167
  {
168
    //sd_writeByte(sd_data_buffer[sd_data_index]);      //Daten senden
169
    sd_writeByte(123);              //Der Einfachheit wegen testweise nur 123 als Muster schreiben
170
  }
171

172
  //Block schliessen:
173
  //CRC-Byte schreiben
174
  sd_writeByte(0xFF); //Schreibe Dummy CRC
175
  sd_writeByte(0xFF); //CRC Code wird nicht benutzt
176

177
  //Fehler beim schreiben? (Data Response XXX00101 = OK)
178
  sd_error = sd_readByte();
179
  if((sd_error & 0x1F) != 0x05)
180
  {
181
    PORTD |= (1<<6);                  //Disable
182
    return(sd_error);
183
  } 
184

185
  //Warte auf SD-Karte busy
186
  while (sd_readByte() != 0xff)
187
    ;
188
 
189
  //SD-Karte Inaktiv schalten (Chip Select auf high)
190
  PORTD |= (1<<6);                  //Disable
191

192
  //Wenn wir hier angekommen sind ist die Welt in Ordnung!
193
  return 0;
194
}
195

196
//Routine zum Lesen eines Sektors
197
uint8_t sd_readSektor(void)
198
{
199
  uint8_t cmd[6];
200
  uint32_t sd_l_sektor_index = sd_sektor_index * 512;  //die Adressierung der SD-Karte wird in Bytes angegeben, Sektor wird von Blocks in Bytes umgerechnet
201
  
202
  cmd[0] = 0x51;          //Sektoren Byteweise angeben
203
  cmd[1] = ((sd_l_sektor_index & 0xFF000000) >> 24);  //MSB isolieren und in Position rücken
204
  cmd[2] = ((sd_l_sektor_index & 0x00FF0000) >> 16);  //...   "
205
  cmd[3] = ((sd_l_sektor_index & 0x0000FF00) >> 8);  //LSB   "
206
  cmd[4] = 0;
207
  cmd[5] = 0xFF;
208
  
209
  //Sende Kommando an SD-Karte (Read 1 Block/512 Bytes)
210
  uint8_t sd_error = sd_writeCommand(cmd);
211
  if (sd_error) return sd_error;
212
  
213
  //Wartet auf Start Byte (0xFE) von der SD-Karte 
214
  uint16_t sd_timeout = 500;
215
  while ((sd_readByte() != 0xfe) && (sd_timeout))
216
  {
217
      if(sd_timeout-- == 0) return 2;              //War wohl nix...
218
  }      
219
  
220
  //Hole die Daten
221
  for(sd_data_index = 0; sd_data_index < 512; sd_data_index++)
222
  {
223
    sd_data_buffer[sd_data_index] = sd_readByte();
224
  }
225
  
226
  
227
  //CRC-Byte auslesen
228
  sd_readByte();  //CRC - Byte wird nicht ausgewertet
229
  sd_readByte();  //CRC - Byte wird nicht ausgewertet
230
  PORTD |= (1<<6);                  //Disable
231
  
232
  //Wenn wir hier angekommen sind ist die Welt in Ordnung!
233
  return 0;
234
}
OP #3680788
Lesenswert?

Ich habe den HXD-Editor, der kann die Datenblöcke lesen bzw sieht die 
SD-Karte auf der untersten Ebene.

Das hatte ich vor jahren mit einem Atmega32 und meinem Roboter gemacht.
Das Ding fuhr im Zimmer rum und habe mit einem Abstandssensor Daten 
eingescannt und am PC wieder ausgelesen mit HXD und einen Grafikumriss 
nach den Daten erstellt.

Gruss

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren