MaWin schrieb: > Falk B. schrieb: >> Stimmt, aber Mr. AVR meint, das wäre in ASM einfach. > > Ist es auch, SPI Slave mit externem Takt (der ggf. trotzdem von innen > stammt per PWM Pin) und schon btauchtan keine PLL. Lern mal zitieren und sinnerfassendes Lesen, alter Mann. Es war EXPIZIT die Rede von einem EXTERNEN, SYNCHRONEN Takt zum Datensignal! Da nützt dir ein ASYNCHRONER Takt der nominell gleichen Frequenz herzlich wenig. >> Ich bezweifle, daß >> man es überhaupt hinbekommt, auch mit 16 MHz CPU-Takt. > > https://ww1.microchip.com/downloads/en/Appnotes/Atmel-2585-Setup-and-Use-of-the-SPI_ApplicationNote_AVR151.pdf Meinst du wirklich, daß ich nicht weiß, wie SPI beim AVR funktioniert? OMG!
avr schrieb: > Danke, exakt so war das gemeint. SPI Slave und der AVR läuft mit > internem Takt auf 8 MHz. Und das Problem des einfach gepufferten > Sendepuffers kann durch Interrupt mit maximal 5 Takte Latenz in > Assembler gelöst werden. Wie genau habe ich oben beschrieben. Beweise es mit einem lauffähigen Progamm. Alles andere sind Behauptungen und Ausreden.
c-hater schrieb: > Ich meine, das ist natürlich eine Sache, über die man eigentlich sowieso > nicht diskutieren müsste, da jeder mit hinreichender Kompetenz das > sowieso weiss, aber ich möchte halt, dass du es EXPLIZIT und > ÖFFENTLICH selber sagst. > > Deal? Ich weiß nicht was in deinem Leben so alles schief gelaufen ist, aber es ist eine Menge. Mein aufrichtiges Beileid.
Ist wohl mit einem Mikrocontroller wohl doch nicht so easy? Sry, ist nur ein oberflächlicher Eindruck.
Rente mit 76 schrieb: > Ist wohl mit einem Mikrocontroller wohl doch nicht so easy? > Sry, ist nur ein oberflächlicher Eindruck. Ja, weil du einen FPGA-Fetisch hast und nicht lesen kannst und willst. Beitrag "Re: Schieberegister ersetzen"
Falk B. schrieb: >> Ist es auch, SPI Slave mit externem Takt (der ggf. trotzdem von innen >> stammt per PWM Pin) und schon btauchtan keine PLL. > > Lern mal zitieren und sinnerfassendes Lesen, alter Mann. Es war EXPIZIT > die Rede von einem EXTERNEN, SYNCHRONEN Takt zum Datensignal! Da nützt > dir ein ASYNCHRONER Takt der nominell gleichen Frequenz herzlich wenig. Was hast du an "ggf." nicht verstanden? Es steht explizit externer Takt im zitierten Text. Über den SPI-Slave wird dieser zum asynchronen MCU-Takt einsynchronisiert. Falk B. schrieb: > Beweise es mit einem lauffähigen Progamm. Alles andere sind Behauptungen > und Ausreden. Ich muss dir gar nichts beweisen. Ich zeige eine Lösung auf und du kannst Einwände erheben. Der Einwand "funktioniert nicht, solange du es nicht demonstriert" ist ein Totschlagargument und eines Ingenieurs nicht würdig. Ich bin bereit über alle Einwände zu diskutieren oder sogar ungetesteten Code bereitzustellen, falls du es testen willst. Ich habe es wirklich nicht nötig, das auf richtiger Hardware zu testen. Glaube mir, diskutier mit mir oder bleib auf deiner Scheibe. Alles was ich hier anbiete ist mein Wissen über die AVR-Architektur aus der Zeit, in der ich sehr viel Assembler programmiert habe.
Kurz: Das AVR-SPI ist eine Zicke! Ab 18MHz schafft das SPI mit externem SCK Takt von 1MHz rechtzeitig ein neues Byte nachzufüllen und zuvor das empfangene zu sichern. Bei 16MHz ist's random. Bild vom Scope: D2 (kurze negative Pulse, Port D2): Negative Flanke wird NACH dem Datenaustausch erzeugt. D3 (SCK und OC0B verbunden): Die 1.024MHz gehören dazu (18,432/18). Die negative Flanke VOR dem Puls an D2 beginnt das neue Byte. (Was mich etwas verblüfft) D4 (MOSI hier mit MISO verbunden): Was raus geht, kommt auch wieder rein. Wird hier nur 1x zwischengespeichert. 0x0F wurde am Anfang nur einmal gesendet. (Nachtrag: es wird beim ersten Durchlauf noch ein zweites Mal gesendet, aber dann wird tmp überschrieben.) Geht mit AVR-SPI also gerade so ... Aber nicht mit internem Takt. So, da muss nun nur noch ein Zähler mit Begrenzung rein und ein LD und ein ST ... Gruß Jobst
:
Bearbeitet durch User
Interessant, eventuell verliert man mehrere Takte durch die beiden clock domains. Es gibt aber noch Optimierungspotenzial: - SPIDR erst schreiben, dann lesen - Interrupt benutzen Ich hab hier gerade nicht die Möglichkeit das zu testen. Das wäre dein Code so modifiziert, dass es meiner Meinung nach das Optimum ist.
1 | .include "m328def.inc" |
2 | .def tmp = r16 ; allgemeines Register |
3 | .org 0x0000 ; Reset Handler |
4 | rjmp init |
5 | |
6 | .org 0x0022 ; SPI ISR |
7 | out SPDR, tmp ; ETWAS etwas später |
8 | in R18, SPDR ; ETWAS aus SPI holen |
9 | wieder hinein schicken |
10 | CBI PORTD, 2 |
11 | MOV tmp, R18 |
12 | SBI PORTD, 2 |
13 | RETI |
14 | |
15 | init: |
16 | ldi tmp, LOW(RAMEND) |
17 | out SPL, tmp |
18 | ldi tmp, HIGH(RAMEND) |
19 | out SPH, tmp |
20 | ; Ports |
21 | SBI DDRD, 2 ; Testausgang |
22 | ; Timer 0 init |
23 | ldi tmp, 0x23 ; 00: OC0A disconnected |
24 | ; 10: OC0B |
25 | ; 00: Reserved |
26 | ; 01: mit WGM02 aus TCCR0B 101 - Phase correct PWM mit OCRA TOP |
27 | out TCCR0A, tmp |
28 | ldi tmp, 0x09 ; 0000: Reserved |
29 | ; 1: Siehe TCCR0A |
30 | ; 001: Clock/1 |
31 | out TCCR0B, tmp |
32 | ldi tmp, 17 ; TOP (teilt durch 18 - bei 18MHz) |
33 | out OCR0A, tmp |
34 | ldi tmp, 8 ; 50% Tastung |
35 | out OCR0B, tmp |
36 | ldi tmp, 0x01 ; Irq an |
37 | sts TIMSK0, tmp |
38 | SBI DDRD, 5 ; PD5 PWM-Port als Ausgang |
39 | ; SPI init |
40 | LDI tmp, 0x15 |
41 | OUT DDRB, tmp |
42 | SBI PORTD, 5 ; MISO Pullup |
43 | LDI tmp, (1<<SPE)|(0<<MSTR)|(1<<SPIE) ; IRQ, Enable SPI, MSB-first, Master, set clock rate fck/4 |
44 | OUT SPCR, tmp |
45 | LDI tmp, 0 ; No Doublespeed |
46 | OUT SPSR, tmp |
47 | ; START! |
48 | ldi tmp, 0x0F |
49 | out SPDR, tmp ; Etwas hineinwerfen |
50 | SBI PORTD, 2 |
51 | sei |
52 | loop: ; Hauptschleife |
53 | rjmp loop |
Jobst M. schrieb: > Kurz: Das AVR-SPI ist eine Zicke! Nein. Aber das Problem des unterbrechungsfreien Betriebs ist LANGE bekannt. Also nimmt man den UART im SPI-Mode. Beitrag "Re: Schieberegister ersetzen" > Ab 18MHz schafft das SPI mit externem SCK Takt von 1MHz rechtzeitig ein > neues Byte nachzufüllen und zuvor das empfangene zu sichern. Bei 16MHz > ist's random. Dein Test ist nur ein Anfang, die eingentliche Verzögerung fehlt. UNd die SPI-Takterzeigung durch einen Timer, der dann von außen wieder den SPI Takt füttert ist schräg ;-)
avr schrieb: > - SPIDR erst schreiben, dann lesen Möglich. Ich bin mir gerade nicht sicher, wie SPDR sich verhält, nachdem man eine neue Übertragung angestoßen hat. > - Interrupt benutzen Nein, die Zeit hast Du nicht. Wenn der IRQ auslöst, ist die vorherige Übertragung eigentlich schon beendet. Da muss das neue Datenwort dann schon im Register liegen. (Deshalb bin ich auch so verblüfft, dass das so noch rechtzeitig klappt.) Falk B. schrieb: > Aber das Problem des unterbrechungsfreien Betriebs ist LANGE > bekannt. Ja. Ist trotzdem eine Zicke. > Also nimmt man den UART im SPI-Mode. Ich wollte ja genau wissen, wo die Grenze bei SPI ist. > Dein Test ist nur ein Anfang, die eingentliche Verzögerung fehlt. Die ist aber recht Zeitunkritisch vor der Warteschleife zu installieren. Ich habe ja beschrieben wie. Wollte kein Silbertablett liefern. > UNd > die SPI-Takterzeigung durch einen Timer, der dann von außen wieder den > SPI Takt füttert ist schräg ;-) Wenn es mich zum Ziel führt, finde ich es angemessen. Da mir IRQs z.B. in einigen Fällen (in Verbindung mit Hardware) zu sehr jittern, ist dies eine häufig von mir angewandte Methode. Gruß Jobst
:
Bearbeitet durch User
Jobst M. schrieb: > Möglich. Ich bin mir gerade nicht sicher, wie SPDR sich verhält, nachdem > man eine neue Übertragung angestoßen hat. Das steht so im Datenblatt: The slave may continue to place new data to be sent into SPDR before reading the incoming data. The last incoming byte will be kept in the buffer register for later use. Jobst M. schrieb: > Nein, die Zeit hast Du nicht. > Wenn der IRQ auslöst, ist die vorherige Übertragung eigentlich schon > beendet. Da muss das neue Datenwort dann schon im Register liegen. Das gleiche trifft auf Polling zu, das hier im besten Fall 3 Takte benötigt, im worst case aber 6. Der Interrupt wird genauso ausgelöst, wenn SPIF gesetzt wird und schreibt dann nach 4-5 Takten auf SPDR. Und ja, es sind 4-5 Takte. Es gibt bei meinem Beispiel keinen "Interruptrahmen", kein Sichern von Status-/Registern.
avr schrieb: > [...] Keine Panik, ich werde es nachher ausprobieren. Im übrigen wäre das Datenblatt an dieser Stelle nicht zum erstem mal nicht korrekt, daher prüfe ich immer alles selber. Gruß Jobst
avr schrieb: > Es gibt bei meinem Beispiel keinen > "Interruptrahmen" Es gibt immer einen Interruptrahmen. Selbst dann, wenn garnix gesichert oder wiederhergestellt wird und wenn die ISR überhaupt nichts nützliches tut, sondern einfach nur durchlaufen wird (also z.B. nur aus einem reti direkt im Vektor besteht). Und dieser Rahmen ist halt im Minimum 8 Takte (plus mindestens einen, typisch aber eher zwei "Straftakte" in main(), wenn main nur aus rjmp main besteht) Wer das nichtmal das begreift, hat die Architektur nicht verstanden und sollte einfach mal seinen dummen Sabbel halten und die Grundlagen der Architektur lernen. Ende der Ansage.
Lol. Das Wort Interruptrahmen gibt es nicht, zumindest habe ich es in der Literatur noch nie gesehen. Es gibt Epilog und Prolog im Interrupt und dazu gehört die Interruptlatenz (die 4 Takte + pipeline stalls beim AVR beträgt) NICHT.
c-hater schrieb: > Es gibt immer einen Interruptrahmen. Selbst dann, wenn garnix gesichert > oder wiederhergestellt wird und wenn die ISR überhaupt nichts nützliches > tut, sondern einfach nur durchlaufen wird (also z.B. nur aus einem reti > direkt im Vektor besteht). Ja, teilweise wird 'ineffizient' gesichert, also auch Register, die in main gar nicht benutzt werden. Mach mal eine leere Main und eine ISR und schau dir das an. In dem Fall kann man mit ISR(XXX_vect, ISR_NAKED) den Pro- und Epilog verhindern.
avr schrieb: > Das Wort Interruptrahmen gibt es nicht, zumindest habe ich es in der > Literatur noch nie gesehen. Üblich ist eher die Bezeichnung Stackrahmen.
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.