Assembler Fragen zu Timer des ATtiny13 (PWM)

Hallo LotadaC,
an diese Feinheiten muß ich mich weiter dran gewöhnen, an der Klammer "(1<<COMR0A)|(1<<xxxx)
hab ich mich schon gewöhnt.
Frage: Wie hast Du denn nur die .asm Datei geöffnet. Hast Du denn Studio4 o. 5 installiert?
Mit arduino geht das doch garnicht, oder?
Ich werde mich jetzt den 2313 zuwenden und mit Timer1 die ersten Gehversuche machen.
Mit UART hab ich nichts am Hut. Habe den AVR ISP mkII und die ISP getrennt für Tiny13 u. 3213
selbst zusammen gestrickt. (Taste Reset und 3 Taster zur freien Verwendung, zuzüglich
3 x Leds über ULN 2003 ansteuerbar...funzt einfach alles ohne Probleme.
Mit CTC will ich mich auch nochmal beschäftigen.
 

Anhänge

  • Quadro1.jpg
    Quadro1.jpg
    33 KB · Aufrufe: 9
  • Tri13klein.jpg
    Tri13klein.jpg
    38,8 KB · Aufrufe: 9
In der .asm wird das alles schön ordentlich als ASCII abgelegt. Du kannst das also mit jedem Editor betrachten/bearbeiten. Lediglich die Tabulatoren stimmen dann manchmal nicht. (Unter Andriod hänge ich an den Namen einfach noch ein .txt, dann öffnet der automatisch 'nen geeignetten viewer.)
Achso, AVRStudio 5.? hab ich. Auf ne weitere Installation von 6.? hate ich noch keine Lust, und beides paßt bei mir definitiv nicht mehr auf den Rechner.
P.S.: zum Betrachten/Präsentieren/Ausdrucken des Codes benutze ich auch ganz gern "Programmers Notepad" - da kann man sich fürs Syntax-Highlightning beliebige Schemes festlegen. (ich hab das ASM-Scheme kopiert, und an die AVR angepaßt)

Das mit den Klammern ist ein Tick von mir, mir gefällt es so besser. Mathematisch-logisch haben die boolschen Verknüpfungen ( zB "|") Vorrang vor der Schieberei ("<<"). Quatsch - andersrum ists.

Was hast Du gegen den HW-UART? Damit kann man sehr schön irgendwelche Fehler aufspüren, indem man halt mal schnell ein Byte an den PC etc. rüberschiebt. Wenn der UART einmal scharfgeschaltet ist, genügt dann die folgende Instruktion: "out UDR, Rechenregister".

Mit Arduino hab ich mich nicht beschäftigt - die gehen zum Programmieren meist über den Bootloader, oder?

P.S.: hier nochmal Dein Programm:
Code:
 ; Projekt: Projekt01

; Datei: contener03.asm                       Datum: 07.06.2012

; PORTB: Ausg�nge (SFR-Register)
; PB0 = Relais d1 (rechts/links-ab)
; PB1 = Relais d2 (rechts/links-auf)
; PB2 = Relais d3 (Rechtslauf)
; PB3 = Relais d4 (Linkslauf)
 
; PIND: Eing�nge (SFR-Register)
; PD0 = read1 (Readkontakt auf der Schiene)
; PD1 = read2 (Readkontakt rechts am Container-Terminal)

;AVR: Tiny 2313

        .INCLUDE  "tn2313def.inc"  ; Deklarationen f�r Tiny2313
        .EQU    takt = 1200000  ; Systemtakt 1,2 MHz 
        						
			        rjmp	   reset
		        .ORG	    OVF0addr		      ; Interrupt Vektoren
			        rjmp	   TIMER0_OVF		    ; Sprung zur ISR
		        .DEF     akku=r16        ; Register in akku benannt
        

;Stack initialisieren, PortB=Outp./ PortD=Inp.

reset:		   ldi		   akku,LOW (RAMEND);Stapel anlegen
			        out		   SPL,akku
			        ldi     akku,0xFF       ; Bitmuster 1111 1111
			        out     DDRB,akku       ; Port B = Output
        	  ldi		   akku,0x00		     ; Bitmuster 0000 0000
			        out		   DDRD,akku		     ; Port D = Input
; externe Widerst�nde (10K) vorhanden

;Timer0 initialisieren
			
           ldi		   akku,1<<CS02|1<<CS00	; Prescale = 1024
			        out		   TCCR0B,akku			  ; r16 in Steuerreg. TCCR0B
			        ldi		   akku,1<<TOIE0		 ; r16< 1 = Interrupt-Freigabe
			        out		   TIMSK,akku			   ; TIMSK = Timer Interrupt MaSK Register
			        sei						               ; I-Bit im Statusregister SREG
									                          ; 0 = Interrupt gesperrt
									                          ; 1 = "      "  freigegeben

;Arbeitsbeginn
			
		
			        ldi		   akku,0
			        out		   PORTB,akku		    ; alle Motoren=AUS

read1:		   sbic	   PIND,PD0		      ; springe, wenn PD0 = Low
			        rjmp	   read1			        
			        rcall	  zeit2			        ; Verz�gerung ca. 2 Sec.
			        rcall	  linksauf        ; Laufzeit ca. 5 Sec.
			        rcall	  zeit5           ; Verz�gerung ca. 5 Sec.
			        rcall	  rechtslauf      ; �nderung, Zeit auf 30 Sec.
			        rcall	  zeit5
			        rcall	  rechtsab        ; bis Kontakt read2
			        rcall	  zeit5
			        rcall	  rechtsauf       ; Laufzeit ca. 5 Sec.
			        rcall	  zeit5
			        rcall	  linkslauf       ; Laufzeit ca. 24 Sec.
			        rcall	  zeit5
			        rcall	  linksab         ; Laufzeit ca. 2 Sec.
loop:		    rjmp	   loop            ; verbleibt hier in der Schleife
			
; Linksauf-Fahrt / Halt

linksauf:	 ldi		   akku,0b00000010	; PB1
			        out		   PORTB,akku		    ; Linksauf-Fahrt	
			        rcall	  zeit5
			        ldi		   akku,0			
			        out		   PORTB,akku		    ; Linksauf-Halt
			        ret
;----------------------------------------------------------			

; Rechtslauf-Fahrt / Halt

rechtslauf:ldi		   akku,0b00000100	; PB2
			        out		   PORTB,akku		    ; Rechtslauf-Fahrt
			        rcall	  zeit30
			        ldi		   akku,0
			        out		   PORTB,akku		    ; Rechtslauf-Halt
			        ret
;----------------------------------------------------------			

; Rechtsab-Fahrt / Halt

rechtsab:	 ldi		   akku,0b00000001	; PB0
			        out		   PORTB,akku		    ; Rechtsab-Fahrt

read2:		   sbic	   PIND,PD1		      ; springe, wenn PD1=LOW
			        rjmp	   read2
			        ldi		   akku,0
			        out		   PORTB,akku		    ; Rechtsab-Halt
			        ret
;----------------------------------------------------------			

; Rechtsauf-Fahrt / Halt

rechtsauf:	ldi		   akku,0b00000010	; PB1
			        out		   PORTB,akku		    ; Rechtsauf-Fahrt	
			        rcall	  zeit5
			        ldi		   akku,0			
			        out		   PORTB,akku		    ; Rechtsauf-Halt
			        ret
;----------------------------------------------------------			

; Linkslauf-Fahrt / Halt

linkslauf:	ldi		   akku,0b00001000 ; PB3
			        out		   PORTB,akku		    ; Linkslauf-Fahrt
			        rcall	  zeit24
			        ldi		   akku,0
			        out		   PORTB,akku		    ; Linkslauf-Halt
			        ret
;----------------------------------------------------------

; Linksab-Fahrt / Halt

linksab:	  ldi		   akku,0b00000001 ; PB0
			        out		   PORTB,akku		    ; Linksab-Fahrt
			        rcall	  zeit2
			        ldi		   akku,0
			        out		   PORTB,akku		    ; Linksab-Halt
			        ret

;----------------------------------------------------------

; Pausenzeiten

zeit2:
			        ldi		   r17,0b00000011	 ; Zeit ca. <2 Sec.(Dez.=3)
pause2:		  tst		   r17				         ; teste r17 auf Null
			        brne	   pause2			       ; wenn keine Null nach pause2
			        ret
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

zeit5:
			        ldi		   r17,0b00010100	 ; Zeit ca. 5 Sec.(hex=14/Dez.=20)
pause5:		  tst		   r17				         ; teste r17 auf Null
			        brne	   pause5			       ; wenn keine Null nach pause5
			        ret
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

zeit24:		
			        ldi		   r17,0b01011100	 ; Zeit gemessen 24 Sec.(hex=5C/Dez.=92)
pause24:	  tst		   r17				         ; teste r17 auf Null
			        brne	   pause24			      ; wenn keine Null nach pause24
			        ret
;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

zeit30:		
			        ldi		   r17,0b01111000	 ; Zeit gemessen 30 Sec.(hex=78/Dez.=120)
pause30:	  tst		   r17				         ; teste r17 auf Null
			        brne	   pause30			      ; wenn keine Null nach pause30
			        ret
; ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

;Interrupt-ISR

TIMER0_OVF:push    r2              ; Kopie r2 auf den Stack, danach SP-1
           in      r2,SREG         ; Inhalt vom Statusregister in r2 laden
           dec     r17             ; ISR Abarbeitung (z.B. dec  r17)
           out     SREG,r2         ; Inhalt von r2 ins SREG laden
           pop     r2              ; SP+1, danach vom Stack in r2 laden
           reti
          .EXIT
 
mh...bin es garnicht gewohnt von Dir "schon Morgens" eine Antwort zu bekommen!

Hab mich nochmal mit Deinen Hinweis bez. CTC beschäftigt.
Wollte daraus etwas zerifizieren, aber das gelingt mir nicht.
Hast Du Dich etwa vertan mit COM0Bx..und meintest COM0Ax?
Ich kann die Bits von COM0B0 / 01 setzen wie ich will, ich bekomme
an OC0A oder OC0B nichts getoggelt.
Nur wenn ich (1<<COM0A0)|(1<<WGM01) setze, sehe ich an OC0A
einen Takt mit einer Periodenzeit, die ich über OCR0A ändern kann.
Oder sollte ich doch noch einen Fehler machen?
 
Kommt drauf an, was für Schichten ich hab. Und wie ich zur Arbeit bzw zurück komme (mit der Bahn sinds fast 3 Stunden einfache Fahrt - mit dem Auto nur anderthalb...)
So, nun zu Deiner Problematik:
-in diesem CTC-Mode inkrementiert der Timer prescalerabhängig mit dem Controllertakt. Jedesmal wird geprüft, ob Zählerregister (TCNT oder so) = OutputCompare Register A (bei anderen Timern kann das auch das InputCapture Register sein). Wenn die also gleich sind, wird der Timer zurückgesetzt (deswegen Clear Timer on Compare match).
-Zusatzlich kann der COMA-Pin dann noch getoggelt werden.
-Erreicht der Timer MAX (weil vielleicht grad OCRA neu beschrieben wurde), läuft er wie im normal mode über.
-Außerdem wird bei jedem Inkrement TNCT=OCRB geprüft, und die entsprechende Aktion (COMB-Bits) am entsprechenden Beinchen ausgeführt.

welche Werte hast Du denn den Compare-Registern (A/B) zugewiesen?
Ansonsten stell mal den Code rein.
 
Hallo LotadaC,

hier mal den Quell-Code:

Code:
; Projekt: Projekttiny 13                        Datum: 20.07.2012

; Datei: CTC-MOD2-0A.asm

; Test Mode 2 = CTC
.include "tn13def.inc"

; Takt an PB0 (Pin OC0A) Periode = 0,36ms 
.equ vConfTCCR0A = (1<<COM0A0)|(1<<WGM01)   

.equ vConfTCCR0B = (1<<CS00) ; no Prescale

.equ vMAX = 100  ; Wert für OCR0A | an PB0 (OC0A)

; Flash RAM auf Adresse 0 einstellen
.org 0

sbi DDRB,PB0         ;PB0 = OC0A als Output

ldi r16,vMAX          ;Wert für OCR0A laden  =100
out OCR0A,r16        ;und in Output Compare Register A laden

      
ldi r16,vConfTCCR0A  ; Einstellungen für den CTC-Modus2 laden
out TCCR0A,r16       ;und ins Timer/Counter Control Register 0A übertragen

ldi r16,vConfTCCR0B  ;Einstellungen für den Fast PWM-Modus laden
out TCCR0B,r16       ;und ins Timer/Counter Control Register 0B übertragen

Warte:
rjmp Warte ; Endlosschleife
 
.EXIT

Grüße

Rolf
 
Mit dem Code da oben sollte das COM0A-Beinchen alle 100 Takte kippen - Periodendauer also 200 Takte. Es müßte sich hier also ein 200stel der Taktfrequenz des Prozessors messen lassen. Wenn Du jetzt in TCCR0A auch COM0B0 mit setzt (und den entsprechenden Pin zum Ausgang machst (PORT-Register)), sollte sich dieselbe Frequenz auch am COM0B-Beinchen messen lassen. Über das OCR0B-Register läßt sich dann quasi die "Phasenverschiebung" zwischen den beiden Beinchen einstellen (wobei logischerweise nur OCR0B</=OCR0A Sinn macht.

nochmal ganz kurz zum allgemeinen Verständnis:

-als erstes mußt Du zwischen PWM und nonPWM-Modi unterscheiden. Bei den nonPWM wird beim CompareMatch irgendwas (COMxn-Tabellen) mit dem entsprechenden Beinchen gemacht, und sonst nie. Bei den PWM wird diese Aktion dann (üblicherweise) beim Überlauf/zurücksetzen des Timers wieder aufgehoben. Bei den PWM stellst Du mit dem Überlaufpunkt des Timers also eine feste (PWM-)Frequenz ein (erstmal Prozessortakt/Prescaler), und manipulierst die Pulsweite mit dem OCRegister(n).

-normalerweise läuft der Timer durch, bis er am "Ende" überläuft (MAX, 0xFF bei 8bit - bei den 16bit-Timern kann man manchmal auch 9bit, 10bit, logischerweise auch 16bit oder so wählen - das sind dann andere Modi). Diese Werte sind also von der (mehr oder weniger) festen Auflösung des Timers, dem Prescaler und der Taktfrequenz des Controllers abhängig- und lassen sich dadurch nur sehr grob einstellen. Um das jetzt halbwegs frequenzkorrekt zu bekommen, muß der Zähler also flexibel weiter begrenzt werden. Das sind dann halt CTC bzw frequenzkorrekte PWM. Das Register, welches den Vergleichspunkt für den Timer festlegt, läßt sich dann natürlich nicht mehr vernünftig für PWM einsetzen - beim Tiny13/Timer0 steht Dir aber nur OCR0A zur Verfügung, es gibt kein ICR0.

-bei den PWM-Modi wird zwischen "normalen" und phasenkorrekten PWM unterschieden. Der Unterschied ist, daß der Timer bei den phasenkorrekten zwischen 0 und TOP hin und her läuft, bei den "normalen" nicht. Daraus folgt dann auch eine andere Wirkung der, zur PWM eingesetzten Beinchen (diese werden jetzt nicht mehr beim Überlauf/Zurücksetzen des Timers zurückgesetzt, sondern beim Erreichen des OCRegisters beim Zurück zählen des Timers).
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)