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
:
Bearbeitet durch User
Du musst auch noch beachten, dass in der Initialisierung der SD Karte CLK max. 400 kHz betragen darf.
400 kHz muss eigentlich funktionieren. Aber wenn du auf der sicheren Seite sein willst, nimmst du was darunter, z.B. 200 kHz oder 125kHz (habe ich mal verwendet).
Hmm.., danke. Wie kann ich die 400Khz oder darunter jetzt wirksam erzeugen von 50Mhz. Das verstehe ich noch nicht. Danke. Gruss
Teil halt durch 128 oder 256. Ist doch vollkommen egal, da Synchron. Ob das nun 390kHz oder 195kHz sind...
Jup danke. Also gibt es keinen Wert der genau vorgeschrieben ist, als da unter 400KHz bleiben. Danke. Gruss
Die Frage ist doch noch eine ganz andere. Was soll mit der SD-Karte gemacht werden? Sollen hier etwas Daten abgelegt werden die später auch noch mit dem PC gelesen werden können? Gruß, Michael
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 | }
|
Softcore oder pures VHDL? Mit Softcore kein Thema, mit VHDL wird es schon sportlicher. Die Init und das Protokoll der SD ist ja nicht so einfach zusammengestrickt in VHDL.
Und hast Du dir auch schon mal überlegt wie Du am PC an die SD-Karte, bzw. an die einzelnen Sektoren (512 Bytes) kommst?
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
:
Bearbeitet durch User
hmmmm, schreib' doch einfach das C-Programm in ein VHDL-Programm um. Ist doch eh' alles das selbe...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.