Forum: Compiler & IDEs Problem mit Interupts


von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich möchte einen Interrupt auf einem Attini13 in C programmieren. Die 
Forensuche und Google haben mir als Anfänger nicht wirklich geholfen. 
Wäre es möglich das mir jemand einmal erklären kann, was ich da an Code 
brauche um den Interupt erstmal zu programieren und dann wie ich da ein 
Ereignis daran koppel kann? Da ich noch ein ziemlicher Anfäger bin würde 
ich mich über eine leicht verständliche Erklärung freuen.

Gruß Jannis

von Falk B. (falk)


Lesenswert?

Siehe Interrupt, wer hätte DAS gedacht?

von Jannis C. (kabelwurm)


Lesenswert?

Erstmal Danke, für die schnelle Antwort. Wie ich jedoch schon gesagt 
habe ich mir auch diesen Artikel bereits durchgelesen, werde daraus aber 
nicht schlau. Dazu muss gesagt werde, dass ich
1)Noch Schüler bin
2)Erst 15 bin
3)Und ich mit einigen Begriffen aus dem Artikel nichts Anfangen kann.
Meine aktuelle Frage bezieht sich nur auf ein paar Befehle die ich gerne 
wissen möchte weil ich sie nicht selber finde.
Gruß Jannis

von Falk B. (falk)


Lesenswert?

@  Jannis C. (kabelwurm)

>Erstmal Danke, für die schnelle Antwort. Wie ich jedoch schon gesagt
>habe ich mir auch diesen Artikel bereits durchgelesen,

Das hast du WO geschrieben . . .?

> werde daraus aber nicht schlau.

Schade.

> Dazu muss gesagt werde, dass ich
>1)Noch Schüler bin
>2)Erst 15 bin

Waren wir alle mal.

>3)Und ich mit einigen Begriffen aus dem Artikel nichts Anfangen kann.

Welchen?

>Meine aktuelle Frage bezieht sich nur auf ein paar Befehle die ich gerne
>wissen möchte weil ich sie nicht selber finde.

Lies mal was über Netiquette und stelle konkrete Fragen.

MfG
Falk

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
um deine Fragen eine nach der anderen zu beantworten:
In meine ersten Beitrag habe ich geschrieben, dass ich nach Netiquette 
erst die Forensuche benutzt habe. Dabei bin ich auch auf den 
Interuptartikel gestoßen und habe diesen auch studiert.
Die Wiki ist eine tolle Sache die ich auch nicht kritisieren möchte. 
Meiner Ansicht nach verlangt sie jedoch gewisse Grundtkentnisse, die ich 
leider noch nicht habe. Lernen möchte ich das jedoch.
Warum ich das mit meinem Alter und so geschrieben habe: Weil ich damit 
zeigen wollte das ich eben nicht über Kompetenzen verfüge, die mir beim 
Verstehen des Artikles helfen würden.
Bei den Begriffen geht es um dieverse Register und den Zusammenhang 
zwischen ihnen. Das wird sich sicher mit der Zeit von alleine klären, 
wenn ich damit zu tun habe.
ich kann dir mein Proket schildern:
Eine Taste wird gedrückt, daruf hin soll eine Aktion folgen.
Ich habe in der Wiki explizit danach gesucht, es kann auch sein das es 
dadrin steht, ich es aber nicht erkenne.
Ich hoffe ich werde hiermit deiner Frage nach konkreten Infortionen 
gerecht. Über Antworten freue ich mich weiterhin.
Gruß Jannis

von Peter (Gast)


Lesenswert?

Dann stell doch bitte eine Kronkrete Frage. In den wiki artikel sind 
ausreichend beispiele für programme mit Interupt.

Wenn du auf einen Taster reagieren willst dann willst du es vermutlich 
über den PIN-Change interrupt machen, also sucht du aus der doku den 
namen für den interupt und schreibst eine funktion nach der anleitung im 
Wiki.

(Zum üben ist es ok, aber ein großteil der leute werden dir eh empfehlen 
die tasten nicht im Interupt auszuwerten weil es probleme machen kann)

von g457 (Gast)


Lesenswert?

> Meiner Ansicht nach verlangt sie jedoch gewisse Grundtkentnisse, die ich
> leider noch nicht habe.

Bester Quell für Informationen wie der Tschipp überhaupt funktioniert: 
dessen Datenplatt [1]. Lies Dir das mal (vorzugsweise vollständig!) 
durch, dann wirst Du auch sehen dass..

> Bei den Begriffen geht es um dieverse Register und den Zusammenhang
> zwischen ihnen.

..ebendiese Register (und was sie tun) nicht vom Himmel gefallen sind - 
alles fein säuberlich dokumentiert. Wenn Du mit dem Datenplatt durch 
bist wirst Du auch sehen (wissen :-) dass es per Design mehrere 
Möglichkeiten gibt, um..

> Eine Taste wird gedrückt, daruf hin soll eine Aktion folgen.

..zu lösen. (Namentlich, ohne Anspruch auf Vollständigkeit: Interrupt 
INT0, Interrupts PCINT0-5, Pin-Abfrage PINx - was die Unterschiede sind 
und warum nicht jede (technisch mögliche) Lösung zu jedem Problem passt 
steht u.a. im Datenplatt).

So, ich hoffe ich konnte helfen. Viel Spaß beim lesen, ich freue mich 
schon auf ∗konkrete∗ Fragen :-)

HTH

[1] http://atmel.com/dyn/resources/prod_documents/doc2535.pdf

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich wusste nicht, das es noch andere Lösungen gibt. Welche wären das 
denn?
Ich bin auf nichts festgelegt, da ich mich erst einarbeite.
Gruß Jannis

von Peter (Gast)


Lesenswert?

Jannis C. schrieb:
> ich wusste nicht, das es noch andere Lösungen gibt. Welche wären das
> denn?
die extrem einfache. Du machst eine endlosschleife ( die du eh brauchst) 
und dort fragst du den Taster ab, wenn tester gedrückt dann LED an.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Sorry wenn ich sowas frage, aber wie mache ich das?
Mit if und dann?
Beispiel wäre super.
Danke im Voraus
Gruß Jannis

von Peter (Gast)


Lesenswert?

Jannis C. schrieb:
> Mit if und dann?

LED einschalten so wie im Wiki beschrieben.

du solltest erstmal etwas auf einem PC programmieren, damit du 
wenigstens die Grundlager der Programmierung kannst.

von Floh (Gast)


Lesenswert?


von g457 (Gast)


Lesenswert?

> ich wusste nicht, das es noch andere Lösungen gibt. Welche wären das
> denn?

Bitte bitte tu Dir selbst einen Gefallen und lies endlich das 
Datenplatt. Jetzt. Vollständig.

Und im Anschluss das bereits genannte avr-gcc-Tutorial. Ebenfalls 
vollständig. Vorne beginnend.

Glaubs mir, alle Deine (bisherigen) Fragen werden in den genannten 
Dokumenten ausführlich beantwortet. Und wenn Du durch beide durch bist, 
dann hast Du auch genug Grundlagenkenntnisse, auf die man aufbauen kann.

HTH und - nix für ungut - EOD

von Jannis C. (kabelwurm)


Lesenswert?

Ich habe mal im Toturial und im Datenblatt gestöbert und daraufhin 
folgenden Code geschrieben. Der macht beim Simulieren aber nicht das was 
ich will. Der Stil ist wahrscheinlich noch suboptimal. Der Großeil ist 
aus dem Toturial kopiert. Compilieren kann ich es auch ohne Warnungen 
oder Fehler. Letztenendlich soll das ein Test werden. Der Taster wird 
gedrückt (PORTB4) und daraufhin schalten sich PORTB0-3 nacheinander an.
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6
7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 if ( PINB & (1<<PINB4) ) 
11
 {
12
 PORTB =0b00000001;
13
 _delay_ms(1000);
14
 PORTB =0b00000011;
15
 _delay_ms(1000);
16
 PORTB =0b00000111;
17
 _delay_ms(1000);
18
 PORTB =0b00001111;
19
 _delay_ms(1000);
20
  
21
 PORTB =0b00000000;
22
23
   }
24
    
25
}
Gruß Jannis

von Sam .. (sam1994)


Lesenswert?

Mach noch eine While-Schleife darum, sonst wird das ganze nur einmal 
ausgeführt.

von Jannis C. (kabelwurm)


Lesenswert?

Danke für den Tip,
habe den auch gleich umgesetzt:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6
7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 while (1){
11
 if ( PINB &(1<<PINB4) ) 
12
 {
13
 PORTB =0b00000001;
14
 _delay_ms(1000);
15
 PORTB =0b00000011;
16
 _delay_ms(1000);
17
 PORTB =0b00000111;
18
 _delay_ms(1000);
19
 PORTB =0b00001111;
20
 _delay_ms(1000);
21
  
22
 PORTB =0b00000000;
23
 }
24
25
 }
26
   return(0);
27
}
im Simulator zeigt er aber die Angeschalteten Ausgänge nicht an. Ist das 
irgendwie relevant?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:

> im Simulator zeigt er aber die Angeschalteten Ausgänge nicht an. Ist das
> irgendwie relevant?

Das zeigt wahrscheinlich mehr als alles andere, dass du mit dem 
Simulator noch nicht richtig umgehen kannst.

Das macht aber nichts. Denn bei deinen ersten Übungen ist die reale 
Hardware sowieso durch nichts zu ersetzen.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Danke dann bin ich beruhigt. Ich werde das bald mal testen.
Aber mit Hardware. :D
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
das Programm um das es geht funktioniert nicht so wirklich so wie ich 
das will. Wenn ich den Chip in die Platiene setze und 5V anlege, 
schalten sich die Ports0-3 einfach so an, ohne das PORTB4 ein Signal 
erhalten hat. Es liegt weder Spannung an, noch sind irgendwelche 
Verbindungen vorhanden.
Mein Quelltext:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6
7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 while (1){
11
 if ( PINB &(1<<PINB4) ) 
12
 {
13
 PORTB =0b00000001;
14
 _delay_ms(1000);
15
 PORTB =0b00000011;
16
 _delay_ms(1000);
17
 PORTB =0b00000111;
18
 _delay_ms(1000);
19
 PORTB =0b00001111;
20
 _delay_ms(1000);
21
 PORTB =0b00000000;
22
 _delay_ms(1000);
23
 
24
 }
25
26
 }
27
   return(0);
28
    
29
}
Was feht oder ist ligisch falsch?
Gruß Jannis

von Floh (Gast)


Lesenswert?

Jannis C. schrieb:
> Wenn ich den Chip in die Platiene setze und 5V anlege,
> schalten sich die Ports0-3 einfach so an, ohne das PORTB4 ein Signal
> erhalten hat.

Wie ist dein Taster verschaltet? Der Eingang ist hochohmig, daher ist 
der Zustand des Pin4 ohne definierte Pegel (Pullup oder Pulldown) 
abhängig davon, ob Radio 7 grade Musik spielt oder nicht.
:-)

von Jannis C. (kabelwurm)


Lesenswert?

Ich habe in ersmal garnicht verschaltet und nur eine Prüfspitze an die 
Versorgunsspannung gehängt. Ich bin auch nicht festgelegt auf die 
Abfrage des Pins. Wenn es eine bessere und praktikanlere Lösung gibt 
freu ich mich darüber. In der dafür geplanten Schaltung sind auch nur 
dierekt Schalter angeschlossen
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Ich habe in ersmal garnicht verschaltet und nur eine Prüfspitze an die
> Versorgunsspannung gehängt.

Mit anderen Worten:
Die Eingänge sind offen und können sich jedes dahergelaufene 
elektromagnetische Feld wahlweise als 0 oder als 1 einfangen.

> Ich bin auch nicht festgelegt auf die
> Abfrage des Pins. Wenn es eine bessere und praktikanlere Lösung gibt
> freu ich mich darüber.

Pullup Widerstände einschalten
AVR-GCC-Tutorial
AVR-Tutorial

denn das ...
> schalten sich die Ports0-3 einfach so an, ohne das PORTB4
> ein Signal erhalten hat. Es liegt weder Spannung an
... ist ein Trugschluss.

Ein Eingang, an dem nichts angeschlossen ist, ist nicht zwangsläufig auf 
0.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
erstmal Danke für die scnelle Antwort.
Ich habe deinen Tip gleich angewendet. Dank des Tutorials ist das 
problemlos möglich. Nach der korrektur sieht der Code dann so aus:
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6
7
int main (void) 
8
 {
9
 DDRB = 0b00001111;
10
 PORTB |= (1<<PB4);
11
 while (1){
12
 if ( PINB &(1<<PINB4) ) 
13
 {
14
 PORTB =0b00000001;
15
 _delay_ms(1000);
16
 PORTB =0b00000011;
17
 _delay_ms(1000);
18
 PORTB =0b00000111;
19
 _delay_ms(1000);
20
 PORTB =0b00001111;
21
 _delay_ms(1000);
22
 PORTB =0b00000000;
23
 _delay_ms(1000);
24
 
25
 }
26
27
 }
28
   return(0);
29
    
30
}
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:

> problemlos möglich. Nach der korrektur sieht der Code dann so aus:
> #include <avr/io.h>
> #ifndef F_CPU
> #define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
> #endif
> #include <util/delay.h>
>
> int main (void)
>  {
>  DDRB = 0b00001111;
>  PORTB |= (1<<PB4);
>  while (1){
>  if ( PINB &(1<<PINB4) )

Nur musst du jetzt noch berücksichtigen, dass durch den zugeschalteten 
Pullup Widerstand der 'Ruhepegel' des Eingangs eine 1 ist.

UND: Du musst natürlich darauf achten, dass du dir bei weitren 
Zuweisungen an den PORTB den Pullup Widerstand nicht wieder ausschaltest 
:-)

Hier zb
     PORTB =0b00000001;
setzt du Bit 4 vom Port B wieder auf 0. Und damit ist danach der Pullup 
Widerstand wieder weg.

Und bitte: rück deinen Code entsprechend ein, damit man sieht, welche 
Code-Blöcke von welchen { } Klammern umschlossen sind und somit logisch 
zusammengehören. Wenn deine Programme komplizierter werden, ist eine 
derartige Einrückung ein unabdingabres Werkzeug um nicht den Überblick 
zu verlieren.
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */
4
#endif
5
#include <util/delay.h>
6
7
int main (void) 
8
{
9
  DDRB = 0b00001111;
10
  PORTB |= (1<<PB4);
11
12
  while (1) {
13
    if ( !(PINB &(1<<PINB4)) ) {
14
      PORTB =0b00000001;
15
      _delay_ms(1000);
16
      PORTB =0b00000011;
17
      _delay_ms(1000);
18
      PORTB =0b00000111;
19
      _delay_ms(1000);
20
      PORTB =0b00001111;
21
      _delay_ms(1000);
22
      PORTB =0b00000000;
23
      _delay_ms(1000);
24
    }
25
  }
26
27
  return 0;
28
}

von Jannis C. (kabelwurm)


Lesenswert?

Okay und was heißt das für mein Programm?
Desweiterem sind keine weiteren Zuweisungen geplant.
Ich versuche im Momment nur das Programm zum Laufen zu bekommen.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Okay und was heißt das für mein Programm?

Das du es ändern musst?

Wenn bei dir Bit 4 am Port B immer 1 sein muss, dann wirst du wohl das 
hier
1
        PORTB =0b00000001;
so nicht machen können.

Allerdings würde
1
        PORTB =0b00010001;
das Bit 4 auf 1 lassen :-)

genauso wie
1
        PORTB = 0b00000001 | ( 1 << PB4 );

oder aber, wie zb
1
        PORTB |= (1<<PB0);
nur das Bit 0 im Port B setzt und alle anderen Bits in Ruhe lässt.

Viele Wege führen nach Rom.

von Jannis C. (kabelwurm)


Lesenswert?

Wäre es eine Lösung, wenn ich meine Bedingung ändere und sage, dass das 
Ereignis eintreten soll wenn PORTB4 nicht 1 ist ?
Dann müsste es doch funktionieren, wenn ich am Ende der Schleife PORTB4 
wieder setze?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Wäre es eine Lösung, wenn ich meine Bedingung ändere und sage, dass das
> Ereignis eintreten soll wenn PORTB4 nicht 1 ist ?

Nein. Das würde gar nichts ändern.
Denn das du den Pullup brauchst, darüber sind wir uns ja einig.

> Dann müsste es doch funktionieren, wenn ich am Ende der Schleife PORTB4
> wieder setze?

Das würde funktionieren.
Lerne aber trotzdem wie man es richtig macht und greif nicht zu solchen 
Hacks zurück.
Du baust ja auch in ein Zimmer einen Lichtschalter ein und zerstörst 
nicht abends die Glühbirne um dann am nächsten Tag eine neue 
einzuschrauben. Auch wenn das im Prinzip funktionieren würde.


Bits unabhängig von anderen Bits setzen und löschen zu können ist eine 
der Grundfertigkeiten in der µC Programmierung.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich stehe jetzt etwas auf dem Schlauch! Was genau muss ich an meiner 
Schaltung und dem Programm ändern? Es muss keine komplet Lösung sein. 
Ein logischer Ansatz reicht aus.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

> Was genau muss ich an meiner Schaltung und dem Programm ändern?

Welche Schaltung? Es gibt zwei Stellen in denen du eine Schaltung 
erwähnst:

Beitrag "Re: Problem mit Interupts"
Beitrag "Re: Problem mit Interupts"

Beide Stellen zeigen keine Schaltung. Wie soll man ein Programm für eine 
fiktive Schaltung erklären?

von Jannis C. (kabelwurm)


Lesenswert?

Oh Sorry, das hatte ich vergessen.
Also ich möchte einfach einen Taster anschließen. Einen Schließer, der 
nur einen kurzen Kontakt ausgibt. Die weitere Verschaltung kann sowohls 
als Aktiv High, als auch Aktiv Low erfolgen. Da bin ich nicht 
festgelegt, da die Schaltung erst auf dem Papier existiert. Ich weiß 
leider nicht wie ich das Programmieren muss wenn ich eins davon 
verwende.
Gruß Jannis

von Peter (Gast)


Lesenswert?

Jannis C. schrieb:
> Ich weiß
> leider nicht wie ich das Programmieren muss wenn ich eins davon verwende.
das kann doch nicht so schwer sein. Einmal musst du abfrage ob der PIN = 
0 ist und einmal ob der PIN = 1 ist.

von Jannis C. (kabelwurm)


Lesenswert?

Und dann brauche ich nur bei Aktive High den Pull up zu aktievieren?
Gruß Jannis.
PS: Da ich noch zur Schule gehe und mich nur alle 45Min melden kann 
antworte ich frühestens um 11.15

von Helfer (Gast)


Lesenswert?

> da die Schaltung erst auf dem Papier existiert

Auf deinem Papier. Wir sehen hier noch nix.

von Helfer (Gast)


Lesenswert?

> Und dann brauche ich nur bei Aktive High den Pull up zu aktievieren?

Active high (rechtes Bild in 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter) 
und Pull-up schliessen sich aus.

von Jannis C. (kabelwurm)


Lesenswert?

Okay. Dann brauche ich also meinen Quelltext nur gerinfühgig änderen. 
Wie groß muss der Wiederstand den sein? Ungefähr so groß wie der Pull 
up?
Erstmal Danke für die Tips und Anregungen.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

Der Pull-Down für den active low Taster? Ja, von der Größenordnung her 
wie ein Pull Up, also so ca. 1 bis 50 kOhm. 10 kOhm werden gerne 
genommen.

von Helfer (Gast)


Lesenswert?

Selber reingefallen.

> Der Pull-Down für den active low Taster?
                               ^^^
                              high

von Jannis C. (kabelwurm)


Lesenswert?

Okay Danke. Das werde ich heute Nachmittag mal ausprobieren.
Ich gehe bei der guten Hilfe davon aus, dass es geht, aber wenn nicht 
melde ich mich einfach nochmal.
Gruß Jannis

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
mit eurer Hilfe hat es funktioniert.
Noch mal Danke an (fast) Alle.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jungs, das war kontraproduktiv.
Jetzt umgeht er sein Problem des 'Wie schaffe ich es, dass ich an einem 
Port nur die Bits ändere, die ich auch ändern will' mit einem externen 
Widerstand.

Dabei war er schon so dicht drann, dass er nachgefragt hätte, was 
eigentlich ganz genau

   PORTB |= (1<<P4);

macht und warum das jetzt für sein Problem hilfereich sein könnte, wenn 
er das begriffen hat.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
jetzt habt ihr mich neugierig gemacht. Also so viel ich weiß bewirkt 
PORTB |= (1<<P4); das im Controller ein definiertet Pelgel angelegt 
wird.
Wie das jetzt für mich relevant ist, weiß ich nicht.
Icxh freue mich auf Antworten.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

Zusammenfassung bisher: Du hast einen Pin als EINGANG konfiguriert 
(DDRB) und fragst dessen Zustand ab (PINB). Am Pin soll ein Taster 
hängen.

Welchen Logikpegel kannst du bei obigen Voraussetzungen durch die 
PORTB-Anweisung sicher einstellen und so als definierten Ruhepegel 
(Taster nicht gedückt) benutzen? Tipp: Datenblatt.

Und welchen gegensätzlichen Logikpegel muss dein Taster dann beim 
Drücken liefern?

Zu welcher Schaltungsvariante in 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter 
passen diese Pegel?

Braucht man dann den externen Widerstand, wenn die PORTB-Anweisung 
verwendet wird?

Wie sieht die if-Bedingung für die neue Schaltung aus?

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Ich würde sagen,dass der Ruhepegel bei Logisch 1 liegt.
Logisch 0.
Dann Aktiv Low
1
if (!(PINB&(PINB4))
Erstmal Danke, dass ihr euch die Mühe macht, mir bei dieser Sache zu 
Helfen
Gruß Jannis.

von Helfer (Gast)


Lesenswert?

60% richtig :)

> if (!(PINB&(PINB4))

Kontrollieren, welches Bit da abgefragt wird. Tipp: Bitmanipulation

>> Braucht man dann den externen Widerstand, wenn die PORTB-Anweisung
>> verwendet wird?

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
>Kontrollieren, welches Bit da abgefragt wird.
Ich würde sagen, das nach Tutorila mit PINx der Zustand des Pins 
abgefragt wird, und nicht der Pull up.
Ich bin mir bezüglich der Schaltung mit Pull-Up nicht sicher aber ich 
glaube nicht.
Gruß Jannis

von Rolf Magnus (Gast)


Lesenswert?

Jannis C. schrieb:
>>Kontrollieren, welches Bit da abgefragt wird.
> Ich würde sagen, das nach Tutorila mit PINx der Zustand des Pins
> abgefragt wird, und nicht der Pull up.

Das stimmt. Aber bist du dir sicher, daß es auch um den Pin handelt, den 
du abfragen willst?  (Tip:  Es ist nicht Pin B4)

von Helfer (Gast)


Lesenswert?

> Ich würde sagen, das nach Tutorila mit PINx der Zustand des Pins
> abgefragt wird, und nicht der Pull up.

Ja, aber welches Bit?

Bei
#define PINB4 4

kann
PINB & PINB4 = 0000 1000
oder
PINB & PINB4 = 0000 0000
sein

Willst du das oder eher
PINB & XXXXX = 0001 0000
oder
PINB & XXXXX = 0000 0000

Wie kann XXXXX aus PINB4 gebildet werden? Tipp: Bitmanipulation

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich glaube ich muss es mit 0001000 probieren.
Gruß Jannis

von Helfer (Gast)


Lesenswert?

> ich glaube ich muss es mit 0001000 probieren.

Experĭentia est optĭma rerum magistra.
Vergiss nicht ein Video zu machen^^

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
ich gehöre leider zu der Fraktion, die kein Latein hat.
Ich verstehe nicht ganz, worauf du hinaus willst. Also, was ist die 
Lösung?
Gruß Jannis

von Helfer (Gast)


Lesenswert?

> ich gehöre leider zu der Fraktion, die kein Latein hat.

Ich auch. Jannis, vor dir ist ein beleuchtetes rechteckiges Fenster zum 
Wissen einer ganzen Welt. Benutz das!

> Ich verstehe nicht ganz, worauf du hinaus willst. Also, was ist die
> Lösung?

Du hast noch Probleme beim Verständnis des Unterschieds zwischen

if (!(PINB&(PINB4))
und
if (!(PINB&(1<<PINB4))

Die beiden Schreibweisen haben nicht die gleiche Funktion.

Du willst Bit PINB4 (= Bit4) in PINB abfragen, weil das der Pin ist, an 
dem der Taster hängen soll (vgl. Pinout-Skizze im Datenblatt).

Aber die erste Schreibweise fragt das Bit3 ab. Wenn du dich fragst, 
"Wieso?", knobele das aus z.B. mit Hilfe des Artikels 
Bitmanipulation und den Bitoperatoren & und <<.

Um bei der AVR-Programmierung weiter zu kommen, musst du den Unterschied 
aus dem Effeff kennen und anwenden können.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
jetzt weiß ich, worauf du hinaus willst und ich glaube auch die Antwort 
zu Wissen.
if (!(PINB&(PINB4))= 5 Bit von PinB
und
if (!(PINB&(1<<PINB4))= 4 Bit von PinB
Ich hoffe das ist korrekt.
Gruß Jannis

von Falk B. (falk)


Lesenswert?

@Jannis C. (kabelwurm)

>Ich hoffe das ist korrekt.

Leider nein. Nochmal lesen und nachdenken. Steht alles im Artikel 
Bitmanipulation.

MfG
Falk

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
jetzt hab ichs.
Also
das mit(1<<Pinb1) bedeutet das eine 1 einmal nach links geschoben wird, 
während PinB4 das vierte Bit abfragt. Also den Anschluß Pinb3
Wenn das jetzt nicht richtig ist, fress ich einen Besen.
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Immer noch falsch.

PINB4  ist einfach nur eine (benannte) Zahl. Die 4 im Namen weißt darauf 
hin, dass es sich um die Zahl 4 handelt.

Die Zahl 4 hat das Bitmuster 00000100
(1<<PINB4) ist aber eine 1 um 4 Stellen nach links geschoben.
Das ergibt daher das Bitmuster  00001000

Noch auffälliger wird es, wenn man nicht eine Pinnummer nimmt, die 
selber eine 2-er Potenz ist.

PINB3  zb hat das Bitmuster  00000011   (für die Zahl 3)
1<<PINB3    ist aber         00000100   (eine 1 um 3 Stellen geschoben)


   PINB0  <=> 0      00000000
   PINB1  <=> 1      00000001
   PINB2  <=> 2      00000010
   PINB3  <=> 3      00000011
   PINB4  <=> 4      00000100
   PINB5  <=> 5      00000101
   PINB6  <=> 6      00000110
   PINB7  <=> 7      00000111


das ist aber ganz was anderes als

  1 << PINB0         00000001
  1 << PINB1         00000010
  1 << PINB2         00000100
  1 << PINB3         00001000
  1 << PINB4         00010000
  1 << PINB5         00100000
  1 << PINB6         01000000
  1 << PINB7         10000000

'zufällig' ist jetzt aber die Bitrepräsentierung von PINB4 identisch zu 
1<<PINB2. Das ist aber nur bei diesem Pärchen so, bei anderen Nummern 
versagt das völlig.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
1)Der Besen liegt mir im Magen.
2)Ich habe jetzt verstanden, wo der Unterschied liegt.=)
3)Kann ich für PinB3 auch PinB 0*b00000011 schreiben?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:

> 3)Kann ich für PinB3 auch PinB 0*b00000011 schreiben?

Was soll das für einen Sinn haben?
Auch ein Computer setzt die Rechengesetze nicht ausser Kraft. Jede 
beliebige Zahl multipliziert mit 0 ergibt wieder 0.

von Jannis C. (kabelwurm)


Lesenswert?

Hallo,
Sorry, da hab ich mich verschrieben.
ich meinte die Binärzuweisung
0b00000011.
Würde das auch gehen?
Gruß Jannis

von Karl H. (kbuchegg)


Lesenswert?

Jannis C. schrieb:
> Hallo,
> Sorry, da hab ich mich verschrieben.
> ich meinte die Binärzuweisung
> 0b00000011.
> Würde das auch gehen?

Klar.

Was dir noch fehlt.

Im Computer gibt es keine Unterscheidung zwischen dezimal, binär oder 
hexadezimal. Es ist alles dasselbe. Entweder eine Speicherzelle (=Bit) 
ist im aktiven Zustand oder im inaktiven Zustand. Ob wir das als 0 oder 
1, oder als * und o oder in Form einer Dezimalzahl oder .... darstellen, 
ist eine reine Frage der Anzeige.

0b0000011   IST die Zahl 3, genauso wie es 3 oder 0x03 wäre. Das sind 
alles nur verschiedene Schreibweisen desselben Sachverhaltes.

Manchmal ist die Binäre Schreibweise dem Problem besser angepasst, 
manchmal sind es Dezimalzahlen.

Wenn ich die Binärzahl 00000001  um 5 Stellen nach links schieben will, 
dann ist die dazu angebrachte Schreibweise nun mal

    0b00000001 << 5

denn da kann ich unmittelbar sehen, dass um 5 Stellen geschoben wird. 
Was ich bei

   0b00000001 << 0b00000101

nicht unmittelbar sehen würde (ausser ich kann gut Binärzahlen lesen, 
was die meisten Programmierer können).

Aber grundsätzlich sind beide Fassungen eins. Es besteht kein 
Unterschied zwischen ihnen. Sie sind nur andere Schreibweisen. Genauso 
wie

   1 << 5

auch nur eine andere Schreibweise ist.

Und genauso wie ich anstelle von 2 + 3 auch einfach 5 schreiben könnte, 
könnte ich natürlich auch vorgreifen, und selbst die Schiebeoperation 
durchführen und statt dessen einfach

   0b00100000

schreiben. Nur möchte man das nicht tun, denn im letzten Fall muss ich 
Bits abzählen um zu erkennen, an welcher Bitposition die 1 steht, 
während bei

   1 << 5

unmittelbar an der Schreibweise ablesbar ist, dass die 1 an der 
Bitposition 5 steht.

Und wenn ich dann noch in C vereinbare

#define LED_PIN   5

und schreibe

   PORTB |= (1<<LED_PIN);

dann brauch ich beim Lesen des Codes auch nicht mehr verinnerlichen, 
dass es sich beim Pin 5 um den Anchluss handelt an dem die LED hängt. 
Ich muss nur noch erkennen dass mittels

   x |= (1<<irgendwas);

ein Bit auf 1 gesetzt wird, im obigen Beispiel also der AUsgang an dem 
die LED hängt.
Bei
   PORTB |= ( 1 << LED_PIN );
interessiert mich daher gar nicht mehr, um welchen Pin es konkret geht. 
Das wichtige an dieser Stelle besteht darin, dass hier der Ausgang an 
dem die LED angeschlossen ist auf 1 gesetzt wird. Damit ist aber die 
ganze Anweisung aus dem Bereich von Binärzahlen in meinen Problembereich 
gehievt worden. Ich ärgere mich nicht mehr mit irgendwelchen Zahlen rum, 
sondern bei diesem Statement denke ich in Einheiten wie "LED 
einschalten" "LED ausschalten" etc.

von Jannis C. (kabelwurm)


Lesenswert?

Okay, ich denke, dass habe ich jetzt verstanden.
Gruß Jannis

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.