pwm mit tiny15

1avr2

Neues Mitglied
21. Jan. 2010
28
0
0
Sprachen
habe mal wieder ein problem bei der pulsweitenmodulation pwm.

den beitrag von hannes lux habe ich gelesen, aber da bin ich leider noch weit entfernt.
moechte nur eine ganz einfache pwm realisieren. das datenblatt habe ich auch benutzt
jedoch ohne erfolg.

kann sich das listing mal jemand anschauen?

Code:
; dimmer mit pwm an portb1 = pin6
;
.nolist
.include "tn15def.inc"
.list
;
    sbi ddrb,pb1        ; led pwm out

    ldi r16,(1<<com1a1)|(0<<com1a0)|(1<<pwm1)
                    ; bei ocr1a=ocr1b output pwmn=h=5volt

    out tccr1,r16        ; pwm einschalten

    ldi r16,50            ; ocr1a mit 50 laden
    ;out ocr1a,r16
    ;ldi r16,7            ; vergleichswert 7

    out ocr1b,r16
    ldi r16,(1<<psr0)    ; timer ein
    out tccr1,r16

loop:

    rjmp loop

p.s. in der nachricht sind im asm listing noch absaetze erkennbar, bei der vorschau jedoch nicht mehr?
 
Hallo 1avr2,

du verwechselst die beiden Compare-Register. Der Timer läuft im PWM-Modus von 0x00 bis <OCR1B>. Wird der Wert <OCR1B> erreicht, startet er wieder von 0x00.
Kommt es dabei zu einem Comparematch mit <OCR1A>, wird am Pin OC1A (das ist PB1), die Funktion ausgeführt, die du mit den Bits COM1A1 und COM1A0 eingestellt hast, in deinem Fall also Clear bei Comparematch set bei 0x00.

Problem 1:
Bei dir ist <OCR1A> größer als <OCR1B>, es kommt nie zu einem Comparematch. (teilweise hast du auch Befehle auskommentiert)

Problem 2:
Du setzt nie ein Prescalerbit (siehe Register TCCR1), der Timer läuft somit erst garnicht (... normalerweise, er läuft aber tatsächlich, dafür ist Problem 3 verantwortlich)

Problem 3:
Du setzt in TCCR1 ein falsches Bit, das Bit PSR0. Dieses Bit gehört zu dem Register SFIOR und hat die selbe Bitposition wie CS10.

Problem 4:
Mit dem letzten "out TCCR1, r16" überschreibst du die Einstellungen im Register TCCR1, die du am Anfang vorgenommen hast.


Vielleicht hilft dir das ja weiter.

Grüße,
Dirk


Noch ein Hinweis:

Der ATmega15 ist veraltet. Hiermit keine neuen Designs machen. Wenn man ggf. mal den Mikrocontroller tauschen muss, hat man eventuell Schwierigkeiten den noch zu bekommen.
Ersatztyp wäre der ATtiny25, der hat auch ein paar Features mehr (siehe auch Appnote AVR501).

Falls es beim Einfügen des Codes Probleme gibt, auch vielleicht mal vorher den Code in einen anderen Editor einfügen und dann erbeut in die Zwischenablage kopieren, eventuell werden bestimmte Steuerzeichen nicht richtig übernommen.
 
Code:
; dimmer mit pwm an portb1 = pin6
;
.nolist
.include "tn15def.inc"
.list
;
	sbi ddrb,pb1		; led pwm out

	; portb4=pin6 als eingang mit taster
	; soll ein/aus verhaeltnis aendern

	;	cbi ddrb,pb4
	;	sbi portb,pb4
	
	; bit 6=pwm, clear bei comparematch, 1 cs10 fuer timerstart
	; 1 fuer simulator bzw 1111 cs10-cs13 fuer vorteiler 1024

	ldi r16,(1<<com1a1)|(0<<com1a0)|(1<<pwm1)|(1<<cs13)|(0<<cs12)|(0<<cs11)|(1<<cs10)
					
	out tccr1,r16
	
	; vergleichswerte in ocr1a bzw ocr1b
	; ocr1b = spannungshoehe ???
	; ocr1a = an zeit im verhaeltnis zu ocr1b ???
	; bei ocr1a=50 und ocr1b=255 ca 1:5
		
	ldi r16,200				; 50 ergibt verhaeltnis 1:5
	out ocr1a,r16			; ocr1a=3 bzw ocr1b=9 fuer simulator

	ldi r16,250
	out ocr1b,r16


loop:
;	sbis pinb,pb4
;	rjmp dimmen
	rjmp loop

;dimmen:
;	ldi r17,ocr1a
;	inc r17
;	out ocr1a,r17
;	rjmp loop


	


; ocr1b ist ein 8-bit schreib-lese register. das register wird nur im pwm
; benuetzt und begrenzt den oberen wert bis zu dem der counter zaehlt. 

; im pwm mode arbeitet timer 1 als aufwaertszaehler bis zu dem wert 
; der in ocr1b abgelegt ist.

hallo dirk,

danke fuer deine tipps,

pwm funktioniert jetzt 'mauell'. d.h. wenn ich den wert von ocr1a ueber das programm aendere funktioniert es,
aber ich wollte eigentlich mit einem taster an pb4 die led dimmen. funktioniert leider nicht.
das programm mit taster ist als ;kommentar gekennzeichnet.
hast du vielleicht noch eine idee?

gruss bernhard.
 
Hallo Bernhard,

du hast bei dem Pin PB4, der ja nach Reset bereits Eingang ist, den Pullup-Widerstand nicht aktiviert. Die Wahrscheinlichkeit ist hoch, dass du sofort nach Reset im PIN-Register eine "0" liest. Du springst dann zu dimmen, und inkrementiertst das Compareregister OCR1A. <OCR1A> ist ganz schnell (innerhalb ein paar us) größer als <OCR1B> (Timer TOP), es kommt dann nicht mehr zum CompareMatch, bis OCR1A (16Bit) irgendwann überläuft.

Auch wenn du das abfangen würdest, du hast bei der Tastenauswertung keinerlei Zeitglied, so dass OCR1A viel zu schnell inkrementiert wird, das führt zu einem "Schalteffekt". Dekrementieren hast du noch nicht realisiert, OCR1A ist dann immer auf Maximumwert (falls du nach oben hin begrenzt hast).

Auf die Schnelle habe ich leider keine fertige Lösung parat.

Gruß,
Dirk
 
habe endlich wieder ein bischen zeit fuer einen neuen versuch einer pwm mit tiny 15.
laut einem elektor forum eintrag muss man nur das register ocr1a aendern. kann man das pwm signal am simulator verfolgen ??
kann das so funktionieren?


Code:
; einfache pwm mit tiny 15 durch incrementieren von ocr1a
; inhalt von ocr1a sollte pwm aendern

   .include "tn15def.inc"
    .def temp =r16
    .def pwm =r17
    .cseg
    .org $0000
;-----------------------------------------------------------------


;----------------------------------------------------------------
; init portb

	sbi portb,1			; portb1 als ausgang
;-----------------------------------------------------------------
start:
    ldi temp,0x62
    ldi pwm,0x00        ; Setze erstmal "pwm" auf 0
    out TCCR1,temp      ; Lade Timerregister, damit PWM stattfindet
    ldi temp,0x00
    out OCR1A,temp 



loop:	

	dec pwm				; ocr1a=temp + 1 fuer veraenderliche pulsbreite
	rjmp timedelay		; pause
lo2:
	out ocr1a,pwm
	rjmp loop


timedelay:
						; delay fuer pwm, drei fuer simulator
	ldi r19,3			; sonst ff=255
lo1:	
	dec r19
	brne lo1
	rjmp lo2
 
Irgendwie finde ich bei Atmel nicht viel zum verwendeten µC - aber immerhin ein DB vom Tiny15L
-Was soll ".cseg" (hier) bewirken? Direkt danach legst Du sowieso fest, daß ab Adresse 0 übersetzt werden soll (korrekt, da keine IRQ, und das der Reset-Einsprungpunkt ist)
-die start-Marke macht bisher auch (noch) keinen Sinn
-der Übersichtlichkeit halber würde ich statt ldi temp, 0x62 schreiben:
Code:
ldi temp, (1<<PWM1)|(2<<COM1A0)|(2<<CS10)
Dann ist schneller erkennbar, daß Du den PWM aktivierst, OutputCompareMode 2 verrwendest, und der Prescaler des Timers Nummer 2 in der Tabelle ist.
-nachdem Du 62hex ins Register temp und 0 ind Register PWM geladen hast, schreibst Du 62hex nach TCCR1, was den Timer mit PWM (und der, grad im OCR1A stehenden value) direkt startet. Danach lädst Du (nochmal) 0, diesmal nach temp, und schreibst das ins OCR1A (was jetzt den PWM-duty verändert)
sinniger wäre meiner Meinung nach:
Code:
    ldi pwm,0x00        ; Setze erstmal "pwm" auf 0
    out OCR1A,pwm
    ldi temp,(1<<PWM1)|(2<<COM1A0)|(2<<CS10)
    out TCCR1,temp      ; Lade Timerregister, damit PWM stattfindet und starte timer
-den Kommentar in der loop verstehe ich nicht, mMn dekrementierst Du einfach immer den OCR1A.
(-ich persönlich mag diese Art der "Pausenerzeugung" (Leerschleifen) nicht, wenn möglich würde ich das versuchen, mittels TimerÜberlaufInterrupt desselben Timers, oder eines anderen Timers zu lösen

Zu der Simulator Frage: Meine Erfahrung ist, daß der Simulator bei eher spezieller Hardware Probleme bekommt. So wie ich das sehe, verwendest Du einen Timer-Prescaler, der aus einer 2ten Taktquelle abgeleitet, und wesentlich schneller als der eigentliche µC-Takt ist. Der Next-Step-Button geht mMn aber die Prozessortakte durch (also vielleicht einfach mal in einem Testprogramm den Timer (mit so einem Prescaler) starten, und das Counter-Register verfolgen). Das umsetzen der OCR solltest Du im Simulator verfolgen können, das eigentliche umsetzen des Pinzustandes (=PWM) möglicherweise nicht (siehe oben).
Anmerkung am Rande: Ich wollte beim Mega88 mal einen überlaufenden Timer (ohne Interrupt) automatisch zum Auslösen des ADC benutzen (der µC kann das). Im Simulator wurde (drotz gesetzten Überlauf-Flag) nie eine AD-Umsetzung getriggert, in der echten HW liefs praktisch auf Anhieb. Hier der Thread dazu.
 

Ü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)