Hallo! Ich möchte mit dem ATtiny 461A mehr als die vorhandenen 3 PWM-Kanäle erzeugen. Dafür lasse ich den Timer1 als 8bit Timer laufen und steuere die PWM-Ausgänge durch den Compare-Interrupt. Neben dem setzen des Ausgangs lade ich in der Compare-Interrupt-Routine das Register OCR1D mit dem Zeitwert für den nächsten Ausgang. Das ganze funktioniert auch, nur wenn zwei Zeitwerte direkt aufeinander folgen, führt der zweite nicht zu einem Interrupt. In den Beschreibungen habe ich einen Hinweis gefunden das der Interrupt erst mit dem nächsten Timer-Takt erfolgt. Ist das der Grund weswegen aufeinander folgende Vergleichswerte nicht funktionieren. Leider bin ich noch auf keine Lösung gekommen. Nur jeden zweiten Wert zu verwenden finde ich zu grob. Ich hoffe ich habe das vertsändlich beschrieben. Vielen Dank für eure Hilfe! Gruß stefan
Laber nicht rum, sondern zeige und den Quelltext und beschreibe den Anwendungsfall. Ich vermute, es geht um Modellbau-Servos. Warum nimmst du dazu nicht einen der zahlreichen längst erprobten Codes?
Es geht um das Dimmen von LEDs. Hier der Code: ; ATtiny461A ;*********************************************************************** ************************ .include "tn461Adef.inc" .device attiny461A .def dimm1=r1 .def dimm2=r2 .def dimmrot=r3 .def Einzeln=r4 .def Prell=r5 .def Speichern=r6 .def Flag=r7 .def RGB=r8 .def dimmgruen=r9 .def dimmblau=r10 .def Merker2_T=r11 .def RGBneu=r12 .def Merker=r16 .def Merker2=r17 .def Merker1_I=r18 .def TimerL=r19 .def TimerH=r20 .def Dat1=r21 .def Adr1=r22 .def Adr2=r23 .def BitN=r24 .def Ausgabe1=r25 .def Ausgabe2=r26 .def Taste=r27 .def Merker_T=r28 .def ZLow=r30 .def ZHigh=r31 ;********************************************************************* ; Interruptvektoren : ;********************************************************************* rjmp RESET ; Reset Handler rjmp EXT_INT0 ; IRQ0 Handler rjmp PCINT ; PCINT Handler rjmp TIM1_COMPA ; Timer1 CompareA Handler rjmp TIM1_COMPB ; Timer1 CompareB Handler rjmp TIM1_OVF ; Timer1 Overflow Handler rjmp TIM0_OVF ; Timer0 Overflow Handler rjmp USI_START ; USI Start Handler rjmp USI_OVF ; USI Overflow Handler rjmp EE_RDY ; EEPROM Ready Handler rjmp ANA_COMP ; Analog Comparator Handler rjmp ADC_ISR ; ADC Conversion Handler rjmp WDT ; WDT Interrupt Handler rjmp EXT_INT1 ; IRQ1 Handler rjmp TIM0_COMPA ; Timer0 CompareA Handler rjmp TIM0_COMPB ; Timer0 CompareB Handler rjmp TIM0_CAPT ; Timer0 Capture Event Handler rjmp TIM1_COMPD ; Timer1 CompareD Handler rjmp FAULT_PROTECTION ; Timer1 Fault Protection EXT_INT0: PCINT: TIM1_COMPA: TIM1_COMPB: TIM0_OVF: USI_START: USI_OVF: EE_RDY: ANA_COMP: ADC_ISR: WDT: EXT_INT1: TIM0_COMPA: TIM0_COMPB: TIM0_CAPT: FAULT_PROTECTION: reti ;********************************************************************* ; Timer1 Overflow ;********************************************************************* TIM1_OVF: in Flag,SREG sbi PORTB,2 sbi PORTA,3 sbi PORTA,5 out SREG,Flag reti ;********************************************************************* ; Timer1 Compare D ;********************************************************************* TIM1_COMPD: in Flag,SREG cpi Merker_T,0 breq TimerTest ldi Merker_T,1 out OCR1D,Merker_T cbi PORTB,2 clr Merker_T rjmp TIM1_END TimerTest: ldi Merker_T,2 out OCR1D,Merker_T ldi Merker,20 out TIMSK,Merker ldi Merker,148 out TIMSK,Merker cbi PORTA,3 rjmp TIM1_END RGB_direkt: sbrs RGB,0 rjmp TIM1_Gruen cbi PORTB,2 TIM1_Gruen: sbrs RGB,1 rjmp TIM1_Blau cbi PORTA,3 TIM1_Blau: sbrs RGB,2 rjmp TIM1_Next cbi PORTA,5 TIM1_Next: cpi ZLow,112 brne NextPWM ldi ZLow,103 NextPWM: ld Merker_T,Z+ Next_ok: out OCR1D,Merker_T inc ZLow ld RGB,Z+ mov Merker_T,RGB cpi Merker_T,0 breq TIM1_Next TIM1_END: out SREG,Flag reti ;********************************************************************* ; Initialisierungsroutine ;********************************************************************* RESET: ldi Ausgabe1,255 out DDRA,Ausgabe1 ldi Ausgabe2,191 out DDRB,Ausgabe2 ldi Merker,0 out PORTA,Merker ldi Merker,64 out PORTB,Merker clr Einzeln clr Speichern clr RGBneu clr ZHigh ldi ZLow,103 ldi Merker,128 out TCCR0A,Merker ldi Merker,4 out TCCR0B,Merker ldi Merker,163 out TCCR1A,Merker ldi Merker,8 out TCCR1B,Merker ldi Merker,160 out TCCR1C,Merker ldi Merker,0 out PLLCSR,Merker ldi Merker,0 out TCCR1D,Merker ldi Merker,0 out TC1H,Merker ldi Merker,148 out TIMSK,Merker sei ;********************************************************************* ; Hauptprogramm ;********************************************************************* Start: OutOK: ori Ausgabe1,40 out DDRA,Ausgabe1 ori Ausgabe2,46 out DDRB,Ausgabe2 mov Merker,dimm1 out OCR1A,Merker mov dimmblau,dimm1 mov dimmgruen,dimm2 mov Merker,dimm2 out OCR1B,Merker ;*********************************************************************** ******************************************************************* ;RGB dimm-Werte sortieren und in RAM speichern ;*********************************************************************** ******************************************************************* clr RGBneu cp dimmrot,dimmgruen brsh grbl cp dimmrot,dimmblau brsh blkl sts 103,dimmrot ldi Merker,1 sts 104,Merker cp dimmgruen,dimmblau brsh grma sts 106,dimmgruen ldi Merker,2 sts 107,Merker sts 109,dimmblau ldi Merker,4 sts 110,Merker rjmp SortEnde grma: sts 109,dimmgruen ldi Merker,2 sts 110,Merker sts 106,dimmblau ldi Merker,4 sts 107,Merker rjmp SortEnde grbl: cp dimmgruen,dimmblau brsh blkl sts 103,dimmgruen ldi Merker,2 sts 104,Merker cp dimmrot,dimmblau brsh roma sts 106,dimmrot ldi Merker,1 sts 107,Merker sts 109,dimmblau ldi Merker,4 sts 110,Merker rjmp SortEnde roma: sts 109,dimmrot ldi Merker,1 sts 110,Merker sts 106,dimmblau ldi Merker,4 sts 107,Merker rjmp SortEnde blkl: sts 103,dimmblau ldi Merker,4 sts 104,Merker cp dimmrot,dimmgruen brsh roma2 sts 106,dimmrot ldi Merker,1 sts 107,Merker sts 109,dimmgruen ldi Merker,2 sts 110,Merker rjmp SortEnde roma2: sts 109,dimmrot ldi Merker,1 sts 110,Merker sts 106,dimmgruen ldi Merker,2 sts 107,Merker SortEnde: ;*********************************************************************** ******************************************************************* ;gleiche dimmwerte finden ;*********************************************************************** ******************************************************************* lds Merker,103 lds Merker2,106 cp Merker,Merker2 breq Gleich36 lds Merker,104 sts 105,Merker lds Merker,106 lds Merker2,109 cp Merker,Merker2 brne Ungleich69 lds Merker,107 lds Merker2,110 or Merker,Merker2 sts 108,Merker ldi Merker,0 sts 111,Merker rjmp GleichEnde Gleich36: lds Merker,104 lds Merker2,107 or Merker,Merker2 sts 105,Merker ldi Merker,0 sts 108,Merker lds Merker,106 lds Merker2,109 cp Merker,Merker2 brne MaxUngl ldi Merker,7 sts 105,Merker ldi Merker,0 sts 111,Merker rjmp GleichEnde Ungleich69: lds Merker,107 sts 108,Merker MaxUngl: lds Merker,110 sts 111,Merker GleichEnde: ;*********************************************************************** ******************************************************************* rjmp Start
Sorry, mit Assembler kenne ich mich zu wenig aus. Kannst du für die anderen Experten vielleicht noch präzisieren, was "nur wenn zwei Zeitwerte direkt aufeinander folgen" genau bedeutet?
Wenn der 1. PWM Ausgang bei einem Timerwert von zum Beispiel 120 ausgeschaltet wird und der 2. PWM Ausgang bei 121 ausgeschaltet werden soll, dann wird für den 2. PWM-Wert kein Timer-Inerrupt ausgelöst. Obwohl die Abarbeitungszeit der Timer-Inerrupt-Routine deutlich unter dem Zyklus vom Timer liegt. Was muss ich beachten wenn der Timer-Interrupt bei einem nur um eins höheren Timerwert direkt wieder ausgelöst werden soll? Danke und GRuß!
Ich kann zwar Assembler, aber das Programm ist mir zu unübersichtlich, allein schon das Aufdröseln der TCCR1n. Darum nur ein Rat: > ldi Merker,160 > out TCCR1C,Merker Die erste Zeile schreibt man üblicherweise als ldi Merker,(1<<COM1A1S)|(1<<COM1B1S) > sts 108,Merker Statt 108 gibt man im Bereich .dseg einen Namen an, z.B. Hase Hase: .byte 1 ; mein Name ist Hase und schreibt dann im Programm sts Hase,Merker
Immerhin verstehe ich jetzt dein Problem :-) Im Datenblatt steht dazu auf Seite 90: "The Timer/Counter1 register values go through the internal synchronization registers, which cause the input synchronization delay, before affecting the counter operation. " Und auf Seite 94 steht: "The OCR1x Registers are double buffered when using any of the Pulse Width Modulation (PWM) modes... The double buffering synchronizes the update of the OCR1x Compare Registers to either top or bottom of the counting sequence. " Wenn ich das richtig verstehe, muss der neue Wert also nicht nur um 1 höher sein, sondern er wird sogar bis zum nächsten Zyklus verzögert.
> when using any of the Pulse Width Modulation (PWM) modes
Eben das lässt sich bei der obigen Schreibweise nur recht mühsam
feststellen.
TCCR1A.PWM1A und TCCR1A.PWM1B sind beide gesetzt, also PWM Mode.
> Und das erkennen Sie so aus der Lamäng? Das ist kein Kunststück. Ein bisschen Assembler kann ich schon, aber ein bisschen Phantasie hätte schon genügt: >ldi Merker,163 >out TCCR1A,Merker 163 ist binär 1010 0011 die beiden niedrigsten Bits aktivieren laut Datenblatt den PWM Modus.
Ich wollte den tiny461 zunächst nur mit seinen PWM-Kanälen nutzen. Inzwischen möchte ich aber mit einem Tiny noch mehr LEDs ansteuern als PWM-Kanäle vorhanden sind. Mir geht es also nicht um die hier auch verwendeten PWM-Kanäle, die übrigens völlig fehlerfrei funktionieren, sondern um die Software-PWM-Kanäle mit dem 8bit-Timer1.
Dann könnte es eine gute Idee sein, nicht mehr den PWM Modus zu benutzen
Lässt sich nicht der Timer0 dafür (mit-)verwenden? Ich sehe zwar, dass er aktiviert wird, kann aber seine Aufgabe nicht erkennen.
Der Timer0 wird für das Auswerten einer IR-Fenbedienung genutzt. Ich bin davon ausgegangen das der Timer1 für die Hardware-PWM einfach durchläuft und auch für andere Zwecke genutzt werden kann. Gibt es in der BEschreibung einen Hinweis das dies nicht möglich ist? Hatte bisher keinen Hinweis in der Richtung finden können.
? Stefan Us hat ja bereits die betreffende Passage aus dem Datenblatt zitiert.
Beitrag #5222945 wurde von einem Moderator gelöscht.
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.