Hi. Gleich zur Sache. Ich versuche gerade WAV-Files von einer Festplatte über einen DAC abzuspielen. Zum Testen des DAC hab ich mir ne Sinustabelle geschrieben, die einfach nur einen Sinus mit 1kHz ausgibt. Das funktioniert auch ganz gut. Genauso funktioniert die Ansteuerung der Festplatte alleine ganz gut! Um das Timing hinzubekommen, hab ich einen OUTPUT COMPARE Interrupt, durch den der OC1B Pin toggelt (takt für den DAC) und jedesmal ein Interrupt aufgerufen wird. Während des Interrupts werden dann die Daten an den DAC via SPI gesendet! Problem: Wenn ich jetzt den Interrupt aktiviert habe (also den DAC anspreche), dann funktioniert das Auslesen der Festplatte teilweise nicht mehr. Ich hab aber keine Ahnung warum. Normalweise sollte er das Auslesen zum Beispiel eines Sektors einfach unterbrechen, dann die ISR ausführen und dann ganz normal im Programm weitergehen, oder?? Vielleicht hat sowas schonmal jemand gemacht und kann mir dabei helfen! mfg Andreas -- Andreas Auer aauer1 (at) sbox.tugraz.at Student of Telematics http://home.pages.at/aauer1 Graz, University of Technology
Der Festplatte ist das egal, ob ne Pause drin ist. Ohen Quellcode kann man da kaum was sagen, aber schau mal ob irgendwelche Register in der IR verändert werden und so was anderes überschreiben.
Ok, mal ein bisschen Source: unsigned char hddReadDataRegister(unsigned char address, unsigned char *buffer) { unsigned int i = 0; hddReadInit(); HDD_ADDR_PORT = address << HDD_ADDR_OFFSET; for(i=0;i<512;i+=2) { while((hddGetStatus() & (STATUS_BSY | STATUS_DRDY)) != STATUS_DRDY); HDD_ADDR_PORT = address << HDD_ADDR_OFFSET; HDD_READ_PORT &= ~_BV(HDD_READ_PIN); asm volatile("nop\n\t"::); asm volatile("nop\n\t"::); buffer[i] = HDD_DATA_LOW_INPIN; buffer[i+1] = HDD_DATA_HIGH_INPIN; HDD_READ_PORT |= _BV(HDD_READ_PIN); } return (hddGetStatus() & STATUS_ERR); } So sieht der Code aus, der das 512 Bytes vom Datenregister der HDD rausliest. Jetzt noch kurz die ISR. Die ist in Assembler geschrieben. Der Grund dafür war einfach, dass mein C-Code einfach zu groß wurde. Der Interrupt wird übrigens etwa alle 10us aufgerufen! #include <avr/io.h> .global SIG_OUTPUT_COMPARE1B .extern sinustable .extern counter SIG_OUTPUT_COMPARE1B: push r17 ; 2 push ZH ; 2 push ZL ; 2 push r16 ; 2 in r17, 0x0e ; 1 lds r16, counter ; 2 ldi r17, 0 ; 1 ldi ZL, lo8(sinustable) ; 1 ldi ZH, hi8(sinustable) ; 1 add ZL, r16 ; 1 adc ZH, r17 ; 1 ldd r17, Z+1 ; 2 out 0x0f, r17 ; 1 ld r17, Z sbis 0x16, PB0 rjmp CONTINUE inc r16 inc r16 cpi r16, 0x60 brne NEXT ldi r16, 0 NEXT: sts counter, r16 CONTINUE: pop r16 pop ZL pop ZH LOOP_0: sbis 0x0e, SPIF rjmp LOOP_0 out 0x0f, r17 ; 1 pop r17 ; 2 reti ; 4 Vielleicht hat auch schonmal jemand sowas gemacht und weiß vielleicht noch nen Rat!? Besten Dank schonmal! mfg Andreas
Also, ich denke mein Code sind eigentlich ganz in Ordnung aus, oder? Jetzt hätte ich noch eine Bitte! Und zwar... es gibt ja einige unter euch, die schon ne Ansteuerung für ne Festplatte gemacht haben. Könnte mir jemand vielleicht seinen Code (auch ASM) geben, damit ich diesen dann ausprobieren könnte. Ich hab bei meinen schon alle möglichen Variationen ausprobiert. Aber irgendwie hat nichts so richtig gefruchtet! Danke, Andreas
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.