Hi,
ich habe hier ein schräges Problem mit meinem V-USB-Code. Der
funktioniert prinzipiell super, es sei denn ISR(TIMER0_COMPA_vect)
enthält Code.
So funktioniert alles ordnungsgemäß und das USB-Gerät wird erkannt:
ISR(TIMER0_COMPA_vect)
{
}
TCCR0A = (1<<WGM01); // CTC Modus
TCCR0B |= (1<<CS01); // Prescaler 8
OCR0A = 15; // 100 kHz
TIMSK |= (1<<OCIE0A);
Sobald in der ISR aber Code drin ist, wird das Gerät nicht mehr erkannt:
static volatile unsigned int pulseOnCtr=0,pulseOffCtr=0;
ISR(TIMER0_COMPA_vect)
{
if (pulseOnCtr>0)
{
pulseOnCtr--;
if (pulseOnCtr==0)
{
}
}
else if (pulseOffCtr>0)
{
pulseOffCtr--;
}
}
Ich weiß, dass die ISR so noch nichts sinnvolles macht, aber es reicht
um die USB-Verbindung nicht zu stande kommen zu lassen.
Hat jemand eine Idee, was die Ursache sein könnte? Was an dem Code in
der ISR ist falsch?
Danke!
Deine leere isr wird wahrscheinlich wegoptimiert, auf jeden Fall werden keine Register gerettet. Vielleicht mag v-USB keine ISRs?
es muss nichts falsch sein. du darfst vusb aber einfach nicht länger als x takte unterbrechen. steht irgendwo in der beschreibung.
ich habe mir deinen Code nicht weiter angeschaut, aber wenn deine Kommentare stimmen, dann würde die ISR mit 100 kHz aufgerufen werden. Das kann selbst bei deinen kleinen Code schon zuviel sein, so das wichtige Sachen für USB zurückgesteckt werden müssen, und diese nicht mehr im richtigen Zeitfenster behandelt werden konnte. Reduzier die Frequenz mal auf 100 Hz. Btw. Mit welcher CPU Frequenz fährst du? Du kannst dir ja mal spasseshalber das Dissambly anschauen, die Takte von den Assemblerbefehlen zählen (inkl. den ganzen Push und Pop), und dann mal schauen, wieviel Zeit eigentlich für den restlichen Code bleibt. Ist nur eine Vermutung, könnte dir aber weiterhelfen.
Du darfst V-USB nicht zu lange unterbrechen, nimm lieber einen µC mit Hardware USB anstatt dieser frickel-Lösung.
Karl K. schrieb: > // 100 kHz Keine Chance VUSB mit 'net 100kHz ISR zu unterbrechen, die jeweils ca. 50 Takte verbraucht. Da sind gleich 5 MCycles der 12 weg, VUSB verträgt sowas nicht.
tja schrieb: > Btw. Mit welcher CPU Frequenz fährst du? Die CPU läuft mit 16,5 MHz. Wenn ich die Frequenz auf 10 kHz senke, klappt es wieder. Allerdings erscheint mir das schon sehr wenig, in der ISR werden initial (also pulseOnCtr und pulseOffCtr beide auf 0) nur ein paar Takte verbraten. Das bringt den V-USB tatsächlich schon aus dem Tritt?
MWS schrieb: > Keine Chance VUSB mit 'net 100kHz ISR zu unterbrechen, die jeweils ca. > 50 Takte verbraucht. Autsch, dass da schon mal 50 Zyklen rein für die Verwaltung draufgehen wusste ich nicht...irgend eine Chance die Frequenz wenigstens auf 20 kHz hochzubekommen ohne das V-USB die Grätsche macht?
Karl K. schrieb: > es sei denn ISR(TIMER0_COMPA_vect) > enthält Code. Der Code in einem ISR ist so kurz wie möglich zu halten, und dann ist zum unterbrochenen Programm zurückzukehren, oder der Hardware-Interrupt wieder zu enablen. Sonst besteht die Gefahr, dass andere Interrupt Requests nicht rechtzeitig bedient werden. Die Ausrechnung irgenwelcher Dinge kann meist später erfolgen, wenn jemand die Daten des Interrupts anfordert. Oft teilt man deshalb die ISR in einen schnellen Raw-ISR, der z.B. nur ein Timer-Register liest, und einen Mediated ISR, der z.B. dann das Datum daraus errechnet, auf.
Karl K. schrieb: > Autsch, dass da schon mal 50 Zyklen rein für die Verwaltung draufgehen > wusste ich nicht...irgend eine Chance die Frequenz wenigstens auf 20 kHz > hochzubekommen ohne das V-USB die Grätsche macht? War nur geschätzt, aber 2 volatiles, da werden jeweils LD(S), modify, ST(S) draus, die verwendeten Register und das Statusregister muss gesichert werden. Multipliziert mit 100kHz werden da schnell jede Menge Cycles verbraucht und VUSB ist empfindlich. Schau Dir das Disassemblat an, oder simulier's. Wüsste nicht, wie 100kHz klappen soll, denn um maximalen Speed zu erreichen, müssten Prozessorregister für die uints reserviert sein und da spielt der Compiler nicht mit.
Karl K. schrieb: > Autsch, dass da schon mal 50 Zyklen rein für die Verwaltung draufgehen > wusste ich nicht...irgend eine Chance die Frequenz wenigstens auf 20 kHz > hochzubekommen ohne das V-USB die Grätsche macht? VUSB mag keine Interupt Last, weil Atmel AVR MCUs keine Interrupt Prioritäten oder unterbrechbare Interrupts kennen. Andere Interrups verzögern die VUSB Interrupts, die relativ genau getimed sind. Abhilfe: Man nehme eine Atmel MCU mit integriertem USB, da hat man das Problem VUSB nicht mehr. Die Hardware USB Implementationen bei der Interrupt Latenz nicht empfindlich.
am code kann man aber noch ein stück optimieren. pulseOnCtr wird 3 mal verwendet, ist vermutlich volatile - das kosten viel zeit. lass man das volatil weg und caste in der main auf volatile. Dann wird die ISR schneller.
Hp M. schrieb: > oder der Hardware-Interrupt > wieder zu enablen. Ein sei() am Anfang der ISR und bei den Variablen das "volatile" weglassen hat geholfen - Danke!!! :-)
Karl K. schrieb: > Ein sei() am Anfang der ISR und bei den Variablen das "volatile" > weglassen hat geholfen - Danke!!! :-) Das verspricht noch interessante Ergebnisse ;D
yay, wahrscheinlich hast du jetzt einen zufallszahlengenerator. :D
Du kannst deine Timer ISR auch als ISR_NOBLOCK deklarieren, damit erlaubst du V-USB, welches immer die höchste Priorität haben sollte, die ISR zu unterbrechen:
1 | ISR(TIMER0_COMPA_vect, ISR_NOBLOCK) |
Vorsicht vor Race Conditions. Die Timer ISR sollte mgölichst an nichts rumfummeln, was der V-USB IRQ benutzt.
Karl K. schrieb: > Hi, > > ich habe hier ein schräges Problem mit meinem V-USB-Code. Ach, jetzt sind die "Schmalspurelektroniker im Hipsterforum" doch wieder gut genug ;-) @Glühwürmchen: kannst du von mir aus löschen ...
test schrieb: > yay, wahrscheinlich hast du jetzt einen zufallszahlengenerator. :D Nö, die erzeugte Frequenz ist ausreichend stabil.
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.