mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM mit ATtiny2313 an OCnx-Ausgang


Autor: FoxAlpha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin frischer Einsteiger in die µC-Technik und habe folgendes 
Problemchen:

Ich möchte mit dem ATtiny2313 eine Hardware-PWM erzeugen bzw. auf einem 
Ausgang ausgeben, bin bisher aber erfolglos. Ich habe den Timer zwar zum 
laufen gebracht, der Ablauf stimmt auch (OCRnx als TOP, Intterupt flag 
bei compare match, etc.), die Interrupt Flags tauchen auch alle auf 
(Simulation mit AVR-Studio 4), aber an meinem Ausgang am PORTB tut sich 
nix... Das Setzen von prescaler, COMnx, WGM und dergleichen krieg ich ja 
alles hin, aber der Ausgang macht keinen Mucks...

Wenn ich das Datenblatt vom ATtiny2313 richtig verstanden habe, müsste 
ich eigentlich alles richtig gemacht haben (auch wenn ich stellenweise 
den Eindruck habe, dass das Datenblatt manches nicht vollständig 
erklärt). Das ganze müsste doch ohne Interrupt handler funktionieren, 
oder?

Ich liefere heut abend mal meinen sourcecode, vielleicht weiß jemand nen 
typischen Anfänger-Fallstrick?

Grüße

FoxAlpha

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das geht ohne ISR.
Hast du daran gedacht mit DDRx den Pin auf Ausgang zu setzen?

Hier ist ein Beispiel mit LED Fading:
http://www.mikrocontroller.net/articles/Pollin_Fun...
Mode 5 non-inverted PWM on OC1A, 8 Bit Fast PWM

Autor: FoxAlpha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hier bin ich nochmal mit code... unschwer zu erkennen, möchte ich 
erstmal assemblerprogrammierung lernen/üben.
.include "tn2313def.inc"

init:
  ldi r16, RAMEND    ;stackinit (128byte RAM--> 8bit SP)
  out SPL, r16
  ldi r16, 0b11111111  ;portb als output
  out DDRB, r16
  ldi r16, 0      ;portb aus
  out PORTB, r16
  ldi r16, (1<<WGM00) | (1<<WGM01) | (1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) 
            ;fast PWM ;set OC0A at top, clear on compare match fuer A und B
  out TCCR0A, r16
  ldi r16, 156    ;zwei werte fuer OCR0x
  out OCR0A, r16
  ldi r16, 12
  out OCR0B, r16
  ldi r16, (1<<CS00) | (0<<CS01) | (0<<CS02) | (1<<WGM02)  ;teiler 1, timer obergrenze OCR0A
  out TCCR0B, r16
  ldi r16, (1<<OCIE0A) | (1<<OCIE0B)  ;interrupt ein (braucht man das ueberhaupt?)
  out TIMSK, r16

main:
  ; einfach nixtun und den Timer arbeiten lassen ;)
  rjmp main

Portb setze ich als Ausgang und nulle den erstmal. Dann kommt der 
waveform generation mode als fast PWM mit OCR0A als TOP dran (und weil 
OCR0A = TOP, ist bei dem WGM OC0A immer gesetzt, OC0B dient als 
eigentliches Signal). OCR0x werden mit Zahlenwerten gefüttert, dann der 
Prescaler und der "Rest" vom WGM. Die Interrupts hab ich mal 
eingeschaltet, weiß der Geier, ob das notwendig ist...

Ziel des ganzen ist die Ansteuerung eines Modellbauservos. Zum 
Simulieren steht der Prescaler noch auf 1, später mit prescaler 1024 
kommt eine Frequenz von ca. 50Hz raus, an PB4 (OC0B) sollte dann ein 
PWM-Signal mit einem 20ms-Takt und rund 1,5ms "Ein"-Zeit rauskommen 
(Mittenstellung Servo). Mit dem 16bit Timer wäre das ganze etwas 
genauer, aber darauf kommts mir noch nicht an, ich muss erstmal lernen, 
mit dem Timer umzugehen.

Wenn jetzt jemandem was auffällt, was ich besser machen kann, kann er 
sich gerne dazu äußern.

Grüße

FoxAlpha

Autor: FoxAlpha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(irgendwie hat das mit dem posten das erste mal nicht geklappt, deswegen 
nochmal...)

So, hier bin ich nochmal mit code... unschwer zu erkennen, möchte ich 
erstmal assemblerprogrammierung lernen/üben.
.include "tn2313def.inc"

init:
  ldi r16, RAMEND    ;stackinit (128byte RAM--> 8bit SP)
  out SPL, r16
  ldi r16, 0b11111111  ;portb als output
  out DDRB, r16
  ldi r16, 0      ;portb aus
  out PORTB, r16
  ldi r16, (1<<WGM00) | (1<<WGM01) | (1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0) 
            ;fast PWM ;set OC0A at top, clear on compare match fuer A und B
  out TCCR0A, r16
  ldi r16, 156    ;zwei werte fuer OCR0x
  out OCR0A, r16
  ldi r16, 12
  out OCR0B, r16
  ldi r16, (1<<CS00) | (0<<CS01) | (0<<CS02) | (1<<WGM02)  ;teiler 1, timer obergrenze OCR0A
  out TCCR0B, r16
  ldi r16, (1<<OCIE0A) | (1<<OCIE0B)  ;interrupt ein (braucht man das ueberhaupt?)
  out TIMSK, r16

main:
  ; einfach nixtun und den Timer arbeiten lassen ;)
  rjmp main

Portb setze ich als Ausgang und nulle den erstmal. Dann kommt der 
waveform generation mode als fast PWM mit OCR0A als TOP dran (und weil 
OCR0A = TOP, ist bei dem WGM OC0A immer gesetzt, OC0B dient als 
eigentliches Signal). OCR0x werden mit Zahlenwerten gefüttert, dann der 
Prescaler und der "Rest" vom WGM. Die Interrupts hab ich mal 
eingeschaltet, weiß der Geier, ob das notwendig ist...

Ziel des ganzen ist die Ansteuerung eines Modellbauservos. Zum 
Simulieren steht der Prescaler noch auf 1, später mit prescaler 1024 
kommt eine Frequenz von ca. 50Hz raus, an PB4 (OC0B) sollte dann ein 
PWM-Signal mit einem 20ms-Takt und rund 1,5ms "Ein"-Zeit rauskommen 
(Mittenstellung Servo). Mit dem 16bit Timer wäre das ganze etwas 
genauer, aber darauf kommts mir noch nicht an, ich muss erstmal lernen, 
mit dem Timer umzugehen.

Wenn jetzt jemandem was auffällt, was ich besser machen kann, kann er 
sich gerne dazu äußern.

Grüße

FoxAlpha

Autor: FoxAlpha (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, hier bin ich nochmal mit code... unschwer zu erkennen, möchte ich 
erstmal assemblerprogrammierung lernen/üben.

Portb setze ich als Ausgang und nulle den erstmal. Dann kommt der 
waveform generation mode als fast PWM mit OCR0A als TOP dran (und weil 
OCR0A = TOP, ist bei dem WGM OC0A immer gesetzt, OC0B dient als 
eigentliches Signal). OCR0x werden mit Zahlenwerten gefüttert, dann der 
Prescaler und der "Rest" vom WGM. Die Interrupts hab ich mal 
eingeschaltet, weiß der Geier, ob das notwendig ist...

Ziel des ganzen ist die Ansteuerung eines Modellbauservos. Zum 
Simulieren steht der Prescaler noch auf 1, später mit prescaler 1024 
kommt eine Frequenz von ca. 50Hz raus, an PB4 (OC0B) sollte dann ein 
PWM-Signal mit einem 20ms-Takt und rund 1,5ms "Ein"-Zeit rauskommen 
(Mittenstellung Servo). Mit dem 16bit Timer wäre das ganze etwas 
genauer, aber darauf kommts mir noch nicht an, ich muss erstmal lernen, 
mit dem Timer umzugehen.

Wenn jetzt jemandem was auffällt, was ich besser machen kann, kann er 
sich gerne dazu äußern.

Grüße

FoxAlpha

Autor: Stephan Siegel (foxalpha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...mist, jetzt ist doch alles gepostet worden... die zwei überflüssigen 
posts (und den hier) darf jemand löschen, wer kann...

Autor: Heiko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doofe Frage: Hast du schon Hardware oder schaust du im AVRStudio auf die 
Bits in PORTB? In PORTB tut sich nämlich nichts, der Pin wird "an PORTB 
vorbei" gesetzt bzw. gelöscht.

Siehe auch http://atmel.com/dyn/resources/prod_documents/doc8246.pdf 
Bild 11-4.

Zu deiner Frage bezüglich Interrupts: Braucht man nicht. Würde ich auch 
dafür nicht aktivieren, ist eine zusätzliche Fehlerquelle - denn ohne 
ISR macht der Controller unter Umständen dumme Sachen ;)

In deinem Programm ist das aber egal, denn du setzt das globale IRQ-Flag 
nicht.

MfG, Heiko

Autor: Stephan Siegel (foxalpha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen allerseits,

die richtige Frage wäre gewesen: "Schaust du auch auf die richtigen 
Ports?" Ich habe erst späääät festgestellt, dass OC0B ja in PORTD steckt 
und nicht in PortB... /*aua/*

Plötzlich funktioniert alles wie es soll. ;) Sorry für die blöden 
Fragen.

Grüße

FoxAlpha

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.