Interruptroutine LED

OP #3548810
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
Gast #3548829
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.
Gast #3548863
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ß
#3549156
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 ?
#3549883
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.
#3549958
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.
Gast #3550096
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;
> }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren