Forum: Mikrocontroller und Digitale Elektronik AVR Lauflicht


von Marco G. (grmg2010)


Lesenswert?

Moin,

ich versuche gerade ein Lauflicht auf einem MEGA644 zu realisieren. Dazu 
zählt ein Timer und ruft eine ISR auf.

Wenn meine Variable gesetzt ist soll das Licht andersherum laufen als 
wenn sie null ist:
1
int r = 0x80;
2
int l = 0x00;
3
4
ISR(TIMER0_COMPA_vect)
5
{
6
  cli();
7
  
8
  if (s == 1)
9
  {
10
  
11
    if (d == 1)
12
    {
13
      
14
      PORTC = r;
15
      r = r >>1;
16
      if (r == 0)
17
      {
18
      r = 0x80;
19
      }
20
    }
21
    else
22
    {  
23
      
24
      PORTC = l;
25
      l = l <<1;
26
      if (l == 0x80)
27
      {
28
        l = 0x00;
29
      }
30
    }
31
    
32
  }
33
  
34
35
  sei();
36
}
Mein Problem ist der Teil in der else-Bedingung. Sie wird nicht 
ausgeführt; entweder das erste oder keine Aktion. Ich habe auch schon 
den nicht funktionierenden Teil in der ISR gehabt ohne das eine 
Bedingung erfüllt sein muss trotzdem funktioniert es nicht. Wo könnte 
der Fehler liegen?

von Max H. (hartl192)


Lesenswert?

Marco G. schrieb:
> PORTC = l;
>       l = l <<1;
>       if (l == 0x80)
>       {
>         l = 0x00;
>       }
Durch das l = 0x00; hast du dann wenig zum rumscheiben, versuchs mal mit 
l = 0x01;

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Marco G. schrieb:
> Mein Problem ist der Teil in der else-Bedingung. Sie wird nicht
> ausgeführt; entweder das erste oder keine Aktion.

Sie wird schon ausgeführt, aber sie tut nichts sinnvolles.

> int l = 0x00;
>
> // ...
>
>       PORTC = l;
>       l = l <<1;

0 << 1 ist immer noch 0.

Übrigens:

> int r = 0x80;
> int l = 0x00;
> if (s == 1)
> if (d == 1)

Variablennamen dürfen auch mehr als ein Zeichen lang sein.
Und cli() und sei() haben in einer ISR nichts verloren.

von Marco G. (grmg2010)


Lesenswert?

Ok, das ändern auf 0x01 hat den Fehler behoben. Gibt es eine Möglichkeit 
den Zähler weiter laufen zu lassen, als 255? Also einen 16-Bit Timer zu 
verwenden?

von Rolf M. (rmagnus)


Lesenswert?

Marco G. schrieb:
> Gibt es eine Möglichkeit den Zähler weiter laufen zu lassen, als 255? Also
> einen 16-Bit Timer zu verwenden?

Ja klar. Warum sollte es die nicht geben?

von Marco G. (grmg2010)


Lesenswert?

Ok, ich war mir nicht sicher, ob dieser die selben Funktionen hat wie 
der 8-Bit Timer.

von Marco G. (grmg2010)


Lesenswert?

Kann ich mir den im OCR1A eingetragen Wert auch über die UART ausgeben 
lassen? ich hatte es schon mit der itoa Funktion versucht, allerdings 
funktioniert dies nicht richtig. Wenn der Wert auf 1024 steht bekomme 
ich 0 ausgegeben.

von Max H. (hartl192)


Lesenswert?

Marco G. schrieb:
> Kann ich mir den im OCR1A eingetragen Wert auch über die UART
> ausgeben lassen? ich hatte es schon mit der itoa Funktion versucht,
> allerdings funktioniert dies nicht richtig. Wenn der Wert auf 1024 steht
> bekomme ich 0 ausgegeben.
Bist du dir sicher, dass OCR1A nicht nur 8bit breit ist? Die untersten 
8bit von 1024 wären genau 0x00

: Bearbeitet durch User
von Marco G. (grmg2010)


Lesenswert?

Nein ist 16-Bit, allerdings nur mit einem acht Bit Bus verbunden. Wie 
soll ich denn dort zahlen reinschreiben, die größer als 255 sind?

von spess53 (Gast)


Lesenswert?

HI

>Nein ist 16-Bit, allerdings nur mit einem acht Bit Bus verbunden. Wie
>soll ich denn dort zahlen reinschreiben, die größer als 255 sind?

Mit z.B. OCR1A = 65535;

oder einer beliebigen anderen Zahl im Bereich 0..65535?

MfG Spess

von Marco G. (grmg2010)


Lesenswert?

das hatte ich versucht, allerdings ist es unerheblich, welche zahl ich 
eingebe, das Lauflicht läuft immer gleich schnell (bei werten über 255)

von holger (Gast)


Lesenswert?

>das hatte ich versucht, allerdings ist es unerheblich, welche zahl ich
>eingebe, das Lauflicht läuft immer gleich schnell (bei werten über 255)

Poste den Sourcecode. Wie soll man dir denn sonst helfen?

von Marco G. (grmg2010)


Lesenswert?

1
/*Timer initialisieren*/
2
  TCCR1A  = (1<<WGM11);             // CTC Modus
3
  TCCR0B |= (1<<CS12)| (1<<CS10);   // Prescaler 1024
4
  // ((8000000/64)/1000) = 125
5
6
  OCR1A = 2000;                    // Load register
7
  // Compare Interrupt enable
8
  TIMSK1 |= (1<<OCIE1A);

von holger (Gast)


Lesenswert?

TCCR0B |= (1<<CS12)| (1<<CS10);   // Prescaler 1024

Meinst du das TCCR0B richtig ist?
                  ^
                  |
                  |

von Marco G. (grmg2010)


Lesenswert?

nein natürlich nicht. Hatte ich aber bereits in 1 geändert ohne 
Verbesserung

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.