Forum: Mikrocontroller und Digitale Elektronik Interruptroutine LED


von Jan M. (pietus3)


Lesenswert?

Guten Abend.

Ich wende mich an euch nach 2 Tagen Kopfschmerzen und ich hoffe ihr 
könnt mir helfen. Ich versuche mich an Interruptroutinen heranzuwagen 
und möchte dafür eine LED blinken lassen erstmal egal, welches 
Intervall. Ich programmiere unter der Arduino IDE. Der Mikroprozessor 
ist ein ATmega328.
1
#define F_CPU 1000000UL
2
 
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
boolean test;
8
9
ISR( TIMER1_COMPA_vect)                // Interruptbehandlungsroutine
10
{
11
  if (test ==true){
12
  
13
    test = false;
14
    
15
  }
16
  
17
  else{
18
  
19
    test= true;
20
  
21
  }    
22
}
23
24
void setup() {
25
  DDRB = 0b00000000;
26
  PORTB |= (1<<PORTB5);           // Pullup für PB0 und PB1
27
 
28
  TCCR1A = (1<<COM1A0);                 // Togglen bei Compare Match
29
  TCCR1B = (1<<WGM12) | (1<<CS11);      // CTC-Mode; Prescaler 8
30
  TIMSK1  = (1<<OCIE1A);                 // Timer-Compare Interrupt an
31
  test = false;
32
 
33
  OCR1A = 1000;                         // Neutralposition ((2500-2312)*0.008ms)=1,5ms)
34
 
35
  sei();                                // Interrupts global an
36
37
}
38
39
void loop() {
40
  if (test == true ) {       // Impuls-Zeit verlängern
41
      PORTB |= (1<<PORTB5); 
42
    }
43
 
44
    else{       // Impuls-Zeit verkürzen
45
      PORTB &= ~(1<<PORTB5); 
46
    }
47
    
48
  
49
}

Ich danke euch für eure Tipps und Vorschläge.

MFG Pietus3

von TH (Gast)


Lesenswert?

Ist das alles? Wo ist deine Main Funktion?

Jan Meyer schrieb:
> Ich versuche mich an Interruptroutinen heranzuwagen

Dafür sieht dein Programm aber schon ganzschön komplex aus!

von holger (Gast)


Lesenswert?

>  DDRB = 0b00000000;

Kein Ausgang für die LED definiert.

>boolean test;

volatile boolean test;

>  OCR1A = 1000;                         // Neutralposition 
>((2500-2312)*0.008ms)=1,5ms)

Die "blinkt" dann mit 333Hz. Das kann man nicht sehen.

von Jan Peter Meyer (Gast)


Lesenswert?

Meine main function besteht aus Loop und Setup, weil ich eben unter der 
Arduino IDE programmiere.

von Jan Peter Meyer (Gast)


Lesenswert?

Danke teste ich sofort morgen Holger

von TH (Gast)


Lesenswert?

Jan Peter Meyer schrieb:
> Meine main function besteht aus Loop und Setup, weil ich eben unter der
> Arduino IDE programmiere.

Achso sorry... mit arduino habe ich noch nichts am hut gehabt.

Jan Meyer schrieb:
> TCCR1A = (1<<COM1A0);                 // Togglen bei Compare Match

Du könntest deine LED übrigends auch an PB1 anschließen (vorher aber im 
DDRB auf Ausgang stellen) da der hardwareseitig bei jedem Compare-Match 
schon getoggelt wird. Den Code im loop bräuchtest du also erstmal gar 
nicht.


Gruß

von tommy (Gast)


Lesenswert?

Jan Meyer schrieb:
> #define F_CPU 1000000UL

1 MHz ?
Die laufen eigentlich mit 16 MHz (einige auch mit 8 MHz).
Welchen Arduino benutzt Du?

von Jan Peter Meyer (Gast)


Lesenswert?

Arduino Uno.

von Ralph S. (jjflash)


Lesenswert?

... hmmmmmm grübel... Wenn du schon die Interrupts so deklarierst wie du 
sie deklarierst ... und die DDR Register (müßte das dann nicht 
DD-Register richtigerweise heißen) von Hand setzt (wenn auch wie oben 
genannt falsch: eine 1 definiert am Anschluß einen Ausgang, eine 0 einen 
Eingang)...

Warum ... benutzt man dann noch Arduino wenn das FAST schon reines C 
(nicht C++) ist ?

Wäre das dann nicht einfach einfacher zu handhaben ?

von Jan M. (pietus3)


Lesenswert?

Danke jetzt blickt die LED.

Wenn man mal richtig überlegt waren das pure Anfängerfehler. 
Entschuldigung nochmal.

MFG Pietus3

von Karl H. (kbuchegg)


Lesenswert?

Exakt.

So was
1
  DDRB = 0b00000000;

ist fast immer schlecht. Wozu Binärzahlen? Da sieht man so schön - gar 
nichts.

So was
1
  if (test ==true){
ist auch ein typischer Fall fürs selber ins Knie schiessen.

test ist schon offensichtlich ein boolscher Wert (mit einem bescheuerten 
Namen). Den muss man nicht auf true oder false abfragen.
1
  if (test)

oder noch besser: die Variable auf einen ordentlichen Namen umnennen
1
  if (LightOn)
und die Sache ist geritzt.
1
#define F_CPU 1000000UL
2
 
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
boolean LightOn;
8
9
#define LED_DDR   DDRB
10
#define LED_PORT  PORTB
11
#define LED       PB5
12
13
ISR( TIMER1_COMPA_vect)                // Interruptbehandlungsroutine
14
{
15
  LightOn = !LightOn;
16
}
17
18
void setup()
19
{
20
  LightOn = false;
21
  LED_DDR |= ( 1 << LED );
22
  LED_PORT |= ( 1 << LED );
23
 
24
  TCCR1A = (1<<COM1A0);                 // Togglen bei Compare Match
25
  TCCR1B = (1<<WGM12) | (1<<CS11);      // CTC-Mode; Prescaler 8
26
  TIMSK1  = (1<<OCIE1A);                 // Timer-Compare Interrupt an
27
  OCR1A = 1000;                         // Neutralposition ((25002312)*0.008ms)=1,5ms)
28
29
  sei();                                // Interrupts global an
30
}
31
32
void loop()
33
{
34
  if (LightOn)
35
    LED_PORT |= ( 1 << LED );
36
  else
37
    LED_PORT &= ~( 1 << LED );
38
}

Ein Schimmel ist per Definition ein weißes Pferd. Das muss man nicht 
extra abfragen, ob er weiß ist. Eine boolsche Variable ist per 
Definition schon bool. Die muss man nicht extra abfragen, ob sie true 
ist.

: Bearbeitet durch User
von Svenska (Gast)


Lesenswert?

Und wenn man die Variablen, die in einer ISR und im Hauptprogramm 
benutzt werden, dann auch noch als "volatile" deklariert, könnte das 
sogar funktionieren... :-)

von Quack (Gast)


Lesenswert?

Karl Heinz schrieb:
> ist auch ein typischer Fall fürs selber ins Knie schiessen.

Das schiesst in gar kein Knie. Explizit ausgeschriebene Vergleiche sind 
guter Stil, da lesbarer. Nachteile gibt es gar keine, ausser, dass es 
kein cooles C ist.

von Karl H. (kbuchegg)


Lesenswert?

Quack schrieb:
> Karl Heinz schrieb:
>> ist auch ein typischer Fall fürs selber ins Knie schiessen.
>
> Das schiesst in gar kein Knie. Explizit ausgeschriebene Vergleiche sind
> guter Stil, da lesbarer. Nachteile gibt es gar keine, ausser, dass es
> kein cooles C ist.

ACh
Du schreibst wohl auch
1
  if( ( i == 5 ) == true )

i == 5 ist ein boolscher Wert. Genauso wie LightOn im obigen Beispiel.


Du schreibst auch
1
  if( ( PINB & ( 1 << PB4 ) ) == ( 1 << PB4 ) )
weil es doch guter Stil ist, einen expliziten Vergleich zu schreiben, 
obwohl er nicht nötig ist (und nur Fehlerpotential bietet)?

Was bitte ist an
1
  if( isKeyPressed() )
nicht lesbar und warum wird es durch
1
  if( isKeyPressed() == true )
lesbarer?
Wie sagst du in Deutsch?
Sagst du: Wenn die Taste gedrückt ist
1
   if( isKeyPressed() ) )
oder sagst du:
Wenn es wahr ist, dass die Taste gedrückt ist
1
   if( isKeyPressed() == true )

Die Fragestellung "Ist die Taste gedrückt?" ist für sich alleine schon 
eine perfekte boolsche Abfrage. Die muss man nicht noch mal explizit auf 
true oder false testen. Man gewinnt nichts dadurch, wenn man es tut. Man 
kann es natürlich tun, aber in der Realität ist das einfach nur 
zusätzliche Tipparbeit mit der Gefahr in diesem Zusatz Fehler einbauen 
zu können.
Selbiges hier: Der Inhalt der Variablen LightOn ist die Antwort auf die 
Fragestellung "Soll das Licht eingeschaltet sein?". Der Wert in der 
Variablen (true oder false, wobei der Variablenname so gewählt wird, 
dass er mit den möglichen 2 Werten in der Fragestellung korreliert) ist 
bereits die perfekte boolsche Aussage. Ich seh wirklich keinen Grund, 
warum man einen bereits boolschen Wert nochmal darauf überprüfen soll, 
ob er true ist.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Karl Heinz (kbuchegg) (Moderator)

>oder sagst du:
>Wenn es wahr ist, dass die Taste gedrückt ist

>   if( isKeyPressed() == true )

Es ist wahr, dass das recht umständlich ist ;-)

von Oliver S. (oliverso)


Lesenswert?

In dem o.a. Fall geht es auch kurz und knapp so:
1
 test = !test;

Oliver

von ich (Gast)


Lesenswert?

Oliver S. schrieb:
> In dem o.a. Fall geht es auch kurz und knapp so:
>  test = !test;
> Oliver

Hi Oliver,

was ist da jetzt anders als die Version von Karlheinz?
Der Variablenname...
Er hat einen aussagekräftigen Namen benutzt und nicht "test", was ja 
alles und nichts aussagen kann.

Karl Heinz schrieb:
> ISR( TIMER1_COMPA_vect)                // Interruptbehandlungsroutine
> {
>   LightOn = !LightOn;
> }

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.