Hi,
ich habe hier mit einem tiny2313 und vusb eine Schaltung zum Senden von
TTL pulsen gebaut. Funktioniert auch alles soweit, nur bekomme ich die
Länge der Pulse nicht in den Griff.
Wenn ich mit dem Oszilloskop drauf schaue, sehe ich zu ca. 50% etwa die
Pulslänge die ich eingestellt habe, und beim Rest der Pulse etwa 4.5-5
mal die gewünschte Dauer.
Ursprünglich hatte ich die Pulslänge über _delay_ms() gesteuert, weil es
dann aber auch schon nicht zuverlässig war, habe ich es jetzt auf einen
Timer umgestrickt.
Die Firmware basiert auf dem hid-custum-rq Beispiel aus der neusten vusb
Version. Ich habe ein neues Request definiert, und übergebe die
gewünschte Länge des Pulses dort.
Die komplette main.c hängt an, hier die (denke ich) relevanten Teile:
LED_PORT_DDR|=_BV(LED_BIT|TOGGLE_BIT);/* make the LED bit an output */
22
sei();
23
TIMSK=(1<<TOIE1);
24
TCNT1=0x0000;*/
25
for(;;){/* main event loop */
26
wdt_reset();
27
usbPoll();
28
}
29
}
30
ISR(TIMER1_OVF_vect)
31
{
32
TCCR1B=0x00;/* Stop Counter */
33
LED_PORT_OUTPUT&=~_BV(TOGGLE_BIT);/* TTL Low */
34
}
Wie kann das sein, dass ich zwischen TTL High und TTL Low verschieden
lange Zeiten sehe?
Clock ist 12MHz extern, d.h. ich sollte auch noch einen Faktor 1.5
zwischen Eingabe in der Host Software und echter Puslslänge sehen, das
ist aber auch nicht so. Das wäre aber konstant nicht tragisch. Nur dass
viele Pulse so viel länger werden geht nicht.
Schöne Grüsse,
Dieter
>Wie kann das sein, dass ich zwischen TTL High und TTL Low verschieden>lange Zeiten sehe?
Was erwartest du von einem Controller der eigentlich gar kein
USB kann? Der ist doch zu 80% nur mit dem USB Geraffel beschäftigt.
Wenn du genaue Zeiten willst dann verabschiede dich von vusb.
Dieter Ries schrieb:> habe ich es jetzt auf einen Timer umgestrickt.
Aber du hast nur halben Kram gemacht.
Um Pulse zu erzeugen, benutzt man den CTC-Mode des Timers und lässt das
Schalten des Ausgangs von der Hardware erledigen. Dann kann das USB
Rechenzeit, wie es lustig ist, verbraten. Das interessiert dann nicht.
mfg.
@holger: klar erwarte ich von dem Kleinen keine Höchstleistungen, aber
ein counter sollte davon ja nicht betroffen sein, und da das USB zeugs
keine Interrupts macht, sollte es sehr selten vorkommen, dass es genau
zwischen das Hochziehen des Pins und das starten des Timers funkt. Aber
es scheint, dass ich da was nicht fertig gemacht habe.
@Thomas Eckmann: Ich dachte, das hätte ich so gut wie möglich gemacht,
aber es scheint, dass mir da was entgangen ist.
Ich werd allerdings aus der Beschreibung im Datenblatt nicht 100%ig
schlau, wie ich dass damit lösen soll. Gibt's dazu irgendwo Beispiele
oder ausführlichere Doku?
Schöne Grüsse und schon mal danke für die Hilfe,
Dieter
Dieter Ries schrieb:> @holger: klar erwarte ich von dem Kleinen keine Höchstleistungen, aber> ein counter sollte davon ja nicht betroffen sein, und da das USB zeugs> keine Interrupts macht,
es reicht, wenn das USB Zeugs zum richtigen Zeitpunkt die Interrupts
mittels cli() abstellt und nach einer gewissen Zeit mittels sei() wieder
einschaltet.
Dünnes Eis:
Und da das USB Timing eher von der happigen Sorte ist, kann ich mir
schon vorstellen, dass der Code genau das immer wieder mal macht.
>und da das USB zeugs keine Interrupts macht,
Und wovon träumst du Nachts? Das USB Zeugs macht jede
Menge Interrupts. Das auch noch auf Int0 oder Int1?
Die haben höchste Priorität beim ATTiny2313.
Dein Timer kommt da nur noch mal so nebenbei dran.
ui, heute freundlich...
stimmt, dass es am Int1 hängt hab ich übersehen, cli()s sind keine im
code, danach hatte ich geschaut.
Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das
scheint mir schon recht viel.
Anyway, ich denke das Problem muss sich lösen lassen, zumal es mir nicht
auf's exakte Timing, wann der Puls ankommt, sondern nur auf die
Pulslänge ankommt. Ich werd mal in die Sache mit dem CTC reinschauen,
vielleicht hilft das.
Schöne Grüsse,
Dieter
>ui, heute freundlich...
Du hast mich an einem guten Tag erwischt;)
Ich kann noch ganz anders.
>stimmt, dass es am Int1 hängt hab ich übersehen, cli()s sind keine im>code, danach hatte ich geschaut.
Das braucht man in einem Interrupt nicht.
>Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das>scheint mir schon recht viel.
Das ist völlig irrelevant was dir viel erscheint.
Dieser Software USB Kram verbrennt halt einiges an Rechenzeit.
Dieter Ries schrieb:> Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das> scheint mir schon recht viel.
Ich kenn jetzt die USB Spec nicht, ob das zulässig ist bzw. ob du da
Probleme bekommst.
Aber du kannst ja mal versuchen, die Aufrufe von usbPoll() auszusetzen,
während du den Puls laufen lässt.
Aber im Grunde stimmt das schon. Den Puls kann dir der Timer ganz
alleine auch erzeugen. Allerdings ist das dann ein PWM Modus. Das
einzige Problem sehe ich eigentlich darin, dass du eine Obergrenze für
die Pulslänge hast, weil du einplanen musst, dass der Timer rechtzeitig
gestoppt werden muss, ehe er in den nächsten PWM-Zyklus geht. So etwas
wie eine "One-Puls"-PWM gibt es leider nicht.
@holger: da hab ich ja noch mal Glück gehabt. War im Endeffekt auch
genau das Problem, die Interrupts haben dazwischengefunkt.
@Uwe S.: Ich benutze schon die neuste Version. Und von 12MHz auf 20MHz,
was wieder Timingschwierigkeiten mit dem USB mit sich bringen dürfte,
würde das Problem ja auch nur weniger häufig auftreten lassen.
Vorerst läuft das ganze jetzt, ich disable das entsprechende Interrupt
während ich den Puls mache, so kommt es zwar manchmal zu broken pipe
fehlern in der USB Kommunikation, aber das erholt sich wieder, und meine
Pulse werden halbwegs genau generiert.
Ich glaube ich schau mir das aber trotzdem noch mal über PWM an.
Schöne Grüsse
Hallo,
ich habe ein ähnliches Problem mit dem VUSB und dem Timer Overflow
Interrupt.
Scheinbar schein mein Overflow Interrupt das USB und dadurch das
Speichern von Variablen etwas durcheinander zu bringen. Mal klappt alles
doch meistens nicht.
In meinem Fall verwende ich die beiden Timer des Tiny44 im FastPWM mode.
Jetzt wollte ich noch nen laufenden Timr haben und dafür im Overflow ISR
einfach eine Variable hochzählen und in der Main loop abfragen.
Leider klappt das nicht zuverlässig.
Daher die Frage, wie man bei Nutzung von VUSB noch irgendwie mit den
Timer ISRs arbeiten kann.
Hier wäre ich um Tipps sehr dankbar.
Dieter Ries schrieb:> Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das> scheint mir schon recht viel.
Ist es nicht. VUSB arbeitet immer eine komplette
LowSpeed-USB-Transaktion in einer einzigen ISR ab. Das sind (Kleinkram
wie Reaktionszeiten nicht mitgerechnet) bis zu 96 USB-Bits bei einer
Bitrate von 1,5MBit/s.
Rechnen kannst du alleine? Wenn's schon zum Lesen der Quelltexte nicht
reicht...
Da steht die Arbeitsweise von VUSB nämlich auch als recht umfangreicher
Kommentar drinne...
@c-hater: der Kommentar war wohl eher auf die vorherigen Post bezogen.
Da dies schon etwas zurück liegt, scheint das Problem bei Herrn Ries als
erledigt.
Sollte dies nicht der Fall sein, bitte ich um eine kurze Erläuterung
zwischen dem Zusammenhang zu dem Post vom 20.10.2013
Grüße
Peter