PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OCR2 Interrupt durch ADC



The Man
21.07.2007, 16:19
Moin Moin!

ich will auf dem OC2 eine 50/50 Frequenz ausgeben, die durch einen Poti über den ADC variabel ist. Jetzt stehe ich vor dem problem das ich in den OCR2 nur Konstanten laden kann. Ich wollte das Ganze im CTC betreiben.
Wie ich das mit den anderen TIMER Modi und 50/50 umsetzen soll weiß ich nicht da ich immer an dem Problem mit der Konstanten und dem OCR2 ende. Wichtig dabei ist, das die Frequenz von der Hardware generiert wird und nicht, dass ich durch software den TCNT beschreibe und die Zeit bis zum Bottom ändern kann.

Hat dafür jemand eine Idee?

danke
The Man

wkrug
21.07.2007, 21:58
Soweit ich weiß wird im CTC Mode ein Timer Overflow Interrupt getriggert sobald der Zähler auf 0 gesetzt wird - teste das mal im Simulator.
In diesem Interrupt könntest Du deine neuen Werte für das Comparematch Register übernehmen.
Alternativ könnte das auch im Comparematch 2 Interrupt machbar sein der ebenfalls getriggert werden sollte.
Kannst ja vorerst nur mal schauen ob im Simulator sie entsprechenden Flags gesetzt werden.
Werden Sie gesetzt, brauchst Du nur noch den entsprechenden Interrupt freigeben und eine kleine Datenübernahmeroutine schreiben.

The Man
22.07.2007, 08:36
So,
ichhab jetzt mal in den letzten drei Zeilen des Initilisierungscodes eine Konstante in OCR2 gladen. das war jedenfalls der Plan. Denn kommt nichts an. Kann das an Vist liegen? Könnte ma jemand den Code bei sich im Simulator laufen lassen? Es soll hier ein intrrupt durch den ADC getriggert werden und in der Routine der Analogwert in OCR2 landen.


.include "m8def.inc"

.def analog1 = r17
.def analog2 = r18
.org 0x0000
rjmp reset
.org ADCCaddr ; ADC Interrupt Vector Address
rjmp hitvalue
reset:

;Stack wird bei Interrupts benötigt!
ldi r16,HIGH(RAMEND)
out SPH,r16
ldi r16,LOW(RAMEND)
out SPL,r16
ldi r16,0b01100010 ;internal Vref - Channel
out ADMUX,r16
ldi r16,0b10101101 ;freerun - interrupt enable - prescaler 32
out ADCSRA,r16
ldi r16,255
out DDRD,r16
ldi r16,0b11100001 ; toggle OC2 on comparematch - presc 128
out TCCR2,r16
ldi r16,0b10101010
out OCR2,r16
sei
mainloop:



rjmp mainloop


hitvalue:

in analog1,ADCH
ori analog1,0b00000001
out PORTD,analog1
out OCR2,analog1


reti

albundy
22.07.2007, 13:38
Hallo,

das funktioniert schon. Du solltest aber den Interrupt auch freigeben.

in r16,TIMSK
ori r16,(1<<OCIE2)
out TIMSK,r16

und dabei beachten, dass in deinem Fall OCR2 nicht sofort, sondern
erst beim Timer2 Überlauf aktualisiert wird.

The Man
24.07.2007, 14:26
moin,

die Idee war aber auch gar nicht, einen TIMER Interrupt zu machen.
Es soll nur einer durch die fertige ADC Wandlung erfolgen und der PWM rein von der Hardware kommen. Oder kann man keinen PWM generieren, ohne Interrupt?

izaseba
24.07.2007, 16:51
Oder kann man keinen PWM generieren, ohne Interrupt?
Klar geht das, aber nicht in CTC Modus.
Nimm z.B. Fast PWM, der Nachteil ist halt, daß der Timer von 0-255 laufen muß, d.h. Du kannst Dir die Frequenz nicht ganz fein einstellen, nur so wie der Prescaller das erlaubt, also F_CPU/Prescaller.
Durch verändern der OCR2 stellst Du dann die Pulsweite ein.
Es läuft dann komplett ohne Interrupts.

Gruß Sebastian

wkrug
24.07.2007, 17:14
... Er will ja die Frequenz anhand der A/D Wandlerwerte verändern, wenn ich das richtig verstanden habe.
Das funktioniert aber nur dann sauber, wenn er das Comparematch Register beschreibt wenn TCNT 0 ist.
Sonst könnte Theoretisch ein niedrigerer Wert des Comparematch Registers vorliegen als der Zähler TCNT bereits hat.
Dadurch müsste TCNT eine komplette Zählung über den Überlauf drüber machen um den Comparematch Wert zu erreichen.
Folge: ein Überlanger Impuls wird ausgegeben.

izaseba
24.07.2007, 18:30
#-o sorry ich hab da was falsch gelesen, klar hast Du recht, ich dachte er will PWM machen :oops:
Gruß Sebastian

The Man
25.07.2007, 14:21
m´kay
also wenn ich das richtig sehe, muss ich mich für ein 50\50 Signal von der Idee des Interruptfreien PWM verabschieden. Dann mach ich das über einen OCR2 Interrupt mit com Befehl.

wkrug
25.07.2007, 20:42
also wenn ich das richtig sehe, muss ich mich für ein 50\50 Signal von der Idee des Interruptfreien PWM verabschieden.
Die reine PWM Ausgabe kann natürlich hardwaremässig ohne Interrupt erfolgen.
Nur wenn der Wert des Comparematch Registers geändert werden soll muß das in einem zum TCNT synchronen Zeitfenster geschehen. Also z.B. Im Timer Overflow Interrupt.

Du kannst natürlich auch TCNT pollen und bei einem Zählerstand von 0 das Comparematch Register neu laden.

Dabei kann es aber passieren, das deine Routine diesen 0 Zählerstand "übersieht". Darum würde ich es zweckmässigerweise doch in einem Interrupt machen.
Da der Timer ohnehin schon belegt ist, schenkst Du eigentlich auch keine Ressourcen her.

Hanni
25.07.2007, 21:14
Wobei der Begriff Pulsweitenmodulation bei einem frequenzveränderlichem syncronem Rechtecksignal definitiv falsch am Platz ist.

Im übrigen ist der beste Weg tatsächlich den neuen Wert bei einem Timer Overflow zu übernehmen.

Grüße,
Hanni