Forum: Mikrocontroller und Digitale Elektronik ATtiny13 LED-blinken an PB2 und PWM-Mode 7 nicht möglich


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

möchte den ATtiny13 im Fast PWM-Mode (7) betreiben und zwar so das 
OC0A-PB0(Pin5) und OC0B-PB1(Pin6) parallel geschaltet werden können.

Zusätzlich möchte ich an PB2 (Pin7) mittels Timer0 Overflow eine LED als 
Programmlaufanzeige (PLA) blinken lassen.
Das blinken der LED an PB2 (Pin7) funktioniert auch, allerdings nur 
solange
bis ich im Timer/Counter0 Control Register B (TCCR0B) das Bit 3 (WGM02)
und nur dieses zusätzlich setze, dann blinkt die LED an PB2 nicht mehr 
Sichtbar bzw. ist ständig an.

in   A,TCCR0A          ;...Timer/Counter0 Control Register A laden...
ori  A,0b10100011  ;...clear on Match, set at Top...
out  TCCR0A,A    ;...fuer OC0A und OC0B einstellen.


in   A,TCCR0B
ori  A,0b00001010
out  TCCR0B,A

ldi  A,0b00000010  ;Timer/Counter0 Overflow Interrupt...
out  TIMSK0,A    ;...enablen (TOIE0)

Habe keine FUSE oder LOCK-Bits geändert.
Habe im AVR-Simulator die Bits nochmals geprüft und das Datenblatt 
öfters zu Rate gezogen, kann den Fehler jedoch nicht entdecken.
Hoffe jemand von euch tut es.

Habe das komplette Programm als Dateianhang hinzugefügt.

Bis dann
Bernd_Stein

von Peter D. (peda)


Lesenswert?

Es ist ne blöde Idee, im Main und Interrupt die gleichen Register (A,B) 
zu verwenden.

Der Interrupt zerstört die Werte des Main oder man muß die Register 
extra push-/popen.

Du hast 32 Register, da ist übertriebenes Sparen unnötig.


Peter

von spess53 (Gast)


Lesenswert?

Hi

>möchte den ATtiny13 im Fast PWM-Mode (7) betreiben und zwar so das
>OC0A-PB0(Pin5) und OC0B-PB1(Pin6) parallel geschaltet werden können.

Im PWM-Mode7 ist OCR0A Das Register für Top. Damit steht es nicht mehr 
als PWM-Kanal zur Verfügung.

Die Initialisierung der OC-Register fehlt auch.

MfG Spess

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Peter Dannegger schrieb:
> Es ist ne blöde Idee, im Main und Interrupt die gleichen Register (A,B)
> zu verwenden.
>
> Der Interrupt zerstört die Werte des Main oder man muß die Register
> extra push-/popen.
>
> Du hast 32 Register, da ist übertriebenes Sparen unnötig.

Oh ja Danke,

eigentlich weiß ich so etwas,
habe aber wohl vor lauter Bäumen den Wald nicht gesehen.
Habe dies korrigiert und weiß dadurch und durch spess53,
das es nicht am Bit3 (WGM02) im TCCR0B liegt,
sondern daran das ich die OC0RA & OCR0B Register nicht initialisiert 
habe.

Somit kommen zwei Dinge zum Tragen.

Zum einen Note 1. auf den Datenblattseiten 68 & 69

" A special case occurs when OCR0A equals TOP and COM0A1 is set.
In this case, the Compare Match is ignored,
but the set or clear is done at TOP.
See “Fast PWM Mode” on page 63 for more details. "

Was bedeutet das im Fast PWM-Mode 7 wo TOP = OCR0A ist und die
Bits COM0A1 & COM0B1 bei mir gesetzt sind - das die Ausgänge immer auf 
eins sind.

Zum anderen der Ausschnitt aus dem Datenblatt Seite 64

..." The extreme values for the OCR0A Register represents special cases 
when generating a PWM waveform output in the fast PWM mode.
If the OCR0A is set equal to BOTTOM, the output will be a
narrow spike for each MAX+1 timer clock cycle. "...

Was meinem Fehlerbild sehr entspricht, da die LED,
wenn sie nach GND (0) geschaltet wird leuchtet.
Und ich habe ja durch nicht initialisieren der OCR0A & OCR0B Register 
diese bei dem Wert Null belassen was ja BOTTOM entspricht.
Also habe ich nur ein paar Spikes erzeugt und andauernd einen 
Timer/Conunter0 Overflow erzeugt, da das TOV0-Flag bei TOP
( in diesem Fall TOP = OCR0A = 0 ) gesetzt wird.

Bis demnächst
Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

spess53 schrieb:
> Im PWM-Mode7 ist OCR0A Das Register für Top. Damit steht es nicht mehr
> als PWM-Kanal zur Verfügung.
>
> Die Initialisierung der OC-Register fehlt auch.
>
> MfG Spess

Herzlichen Dank,

die Initialisierung der OCR0x-Register war genau die Ursache.

Die Erklärung hierzu habe ich bei Peter Dannegger geschrieben.

Bis demnächst
Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

1
#define SM1_DDR            DDRE
2
#define SM1_PORT          PORTE
3
#define SM1_TAKT        ( 1<<PE3 ) //5  //( 1<<PE3 )  // OC3A-Pin
4
5
void setup() 
6
{
7
  SM1_DDR  |=  SM1_TAKT;         // PE3 bzw. OC3A als Compare Match A Ausgang
8
  SM1_PORT &= ~SM1_TAKT;         // Zunaechst Low-Pegel
9
10
  
11
  TCCR3A = 0; // Weil Arduino
12
  TCCR3B = 0; //
13
  TCCR3C = 0; //
14
 
15
//  TCCR3A |=  0b01<< COM3A0; // OC3A-Pin Toggeln
16
  TCCR3A &= ~0b11<< WGM30;  // CTC-MODE 4 Low  Bits
17
  OCR3A   =  32768;  //minSpeed;      // Niedrige Frequenz
18
  TCCR3B |=  0b01<< WGM32;  // CTC-MODE 4 High Bits
19
  TCCR3B |=  0b001<< CS30;  // Vorteiler = 1 und Timer3 starten
20
  TCCR3B &= ~0b110<< CS30;  // Vorteiler = 1 und Timer3 starten
21
  TIMSK3 |=  1<<OCIE3A;     // Output Compare Interrupt freigeben    
22
}
23
24
void loop() 
25
{
26
  // put your main code here, to run repeatedly:
27
}
28
29
ISR( TIMER3_COMPA_vect ) 
30
{ 
31
  SM1_PORT &= ~SM1_TAKT; // Schrittimpuls vorbereiten
32
  SM1_PORT |=  SM1_TAKT; // Schrittimpuls vollenden
33
}
Mein DSO sagt Impulsdauer 132ns. Könnt gut hinhauen bei 16MHz CPU-Takt.
Logik-Analyser sagt 250ns - Hm.
Da war doch früher mal was. Ach ja Mega-Sample pro Sekunde unzureichend.
Jo, mit 8 MS/s kommt es schon eher hin.

Problem ist nur, dass wenn im OCR3A-Register der Wert 32768 steht, der 
Interrupt ca, alle 4,096ms auftreten sollte. Der LA sagt aber 2,063ms.

Wo ist der Fehler?


Bernd_Stein

von Fenton G. (fenton_g)


Lesenswert?

Bernd S. schrieb:
> Wo ist der Fehler?
>
> wenn im OCR3A-Register der Wert 32768 steht, der
> Interrupt ca, alle 4,096ms auftreten sollte.


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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Dieser Programmabschnitt kann doch keine 5µs, bei 16MHz ( 62,5ns ) 
CPU-Takt dauern.

Erlaubt diese Arduino-Klamotte, dass ein Interrupt durch einen anderen 
unterbrochen werden darf ?
1
ISR( TIMER3_COMPA_vect ) 
2
{ 
3
  //-------------------------------------------------------------------------------
4
  //
5
  // CTC3 MODE 4 Normaler Ausgang
6
  // SM-Sinusrampe abfahren, Schrittmotorschritte runterzaehlen und
7
  // Schrittimpuls erzeugen.
8
  //
9
  //-------------------------------------------------------------------------------
10
  ///////////////////////////////////////////////////////////////////////////////
11
  // Hin und her fahren und am Startpunkt wird eine kurze Pause einlegt
12
  //
13
  if( stepCount != 0 )  {
14
    OCR3A = rampeArray[ rampeArrayZeiger ]; // 
15
    SM1_PORT &= ~SM1_TAKT; // Schrittimpuls vorbereiten
16
    
17
    // Geschwindigkeit verlangsamen und begrenzen
18
    if( stepCount <= rampenLaenge ) {
19
      rampeArrayZeiger ++;
20
      
21
      if( rampeArrayZeiger > rampenLaenge -1 ) rampeArrayZeiger = rampenLaenge -1;
22
    }
23
    // Geschwindigkeit erhoehen und begrenzen
24
    else if( stepCount > rampenLaenge )  {      
25
      rampeArrayZeiger --;
26
      
27
      if( rampeArrayZeiger <= 0 ) rampeArrayZeiger = 0;
28
    }
29
    stepCount --;             // Schrittmotor Schrittanzahl runterzaehlen
30
31
    // Nur jedes 2te mal ist dieses Bit gesetzt bzw. geloescht
32
    if( stepCount == 0 ) flagRegister  ^= EINS;  
33
   
34
    SM1_PORT  |=  SM1_TAKT; // Schrittimpuls vollenden
35
  } 
36
} // Ende ISR( TIMER3_COMPA_vect )


Bernd_Stein

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Bernd S. schrieb:
> Erlaubt diese Arduino-Klamotte, dass ein Interrupt durch einen anderen
> unterbrochen werden darf ?

Darauf hat Arduino keinen Einfluss. Das steuerst du über deinen 
Quelltext. Wenn innerhalb deiner ISR ein sei() steht, dann ermöglichst 
du eine Unterbrechung. Sonst nicht.

Falls du damit experimentieren willst: Verschachtelte Interrupts bringen 
einen Rattenschwanz von Fallstricken mit sich. Der offensichtlichste: 
Erhöhter Speicherbedarf auf dem Stack. Die weniger offensichtlichen 
führen manchmal zu zeitraubender Fehlersuche mit losen Haaren auf dem 
Tisch und Kratzern am Hinterkopf. Also lass das besser sein.

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
Noch kein Account? Hier anmelden.