AVR-C Ein/Ausgabe

OP #5005805
Lesenswert?

Hallo,

ich habe einige Fragen zu diesem Programm.

1. Warum gehen die Leds an, wenn "PORTB = i;"
Welche Information beinhaltet "i"?

unsigned char i;
ist doch die Deklaration.
Aber wo wird das weiterverarbeitet??

2. Was bedeutet das Ausrufungszeichen in (!(PIND&0x04))  ??

Meine Kenntnisse in C sind begrenzt.
;(
#5005822
Lesenswert?

0. Welches Programm?

1.
i wird eine Variable sein, evtl sogar die, die du als nächstes 
Beschreibst.

O. A. schrieb:
> unsigned char i;
> ist doch die Deklaration.

Das ist sogar eine Definition (mit implizierter Deklaration)
Weiter Siehe 0.

2. Das ! ist der NICHT-Operator.
Der negiert einen logischen Wert. Er macht aus 0 eine 1 und aus allen 
Werten ungleich 0 eine 0

3. Bist du dir sicher, dass du im richtigen Unterforum bist?
OP #5005823
Lesenswert?

Frank L. schrieb:
> eher nicht vorhanden...
>
> Da ist weder ein Programm noch kann man erahnen welche LED in deiner
> Schaltung wie verschaltet sind.

Sorry. Habs vergessen.
1
// alle Lichter an
2
// Atmega8 mit 3,6864 MHz
3
// Sprache C
4
//------------------------------
5

6
#define F_CPU 3686400
7
#include <avr/io.h>
8
//#include <stdlib.h>
9

10

11

12
main () 
13
{
14

15
unsigned char i;
16

17
// hier Init-Code eingeben
18

19
DDRB = 0xFF;    // PortB = Ausgang
20
DDRD = 0x00;    // PortD = Eingang
21
PORTD = 0xFF;     // PortD = Pullup
22

23
while   (1)      // mainloop
24
    {
25
    // eine einfache Warteschleife
26
    for (int k=0; k<1000 ; k++) {};
27
    if (! (PIND & 0x04))        // Wenn Bit 2 = 0, dann Taster gedrückt
28
    PORTB = i;              // PortB wird geschaltet, Led an
29
    else
30
    PORTB = 0;              // Leds aus
31
    i++;
32
    }
33
}
Angehängte Dateien:
Beitrag #5005830 wurde von einem Moderator gelöscht.
OP #5005837
Lesenswert?

Hallo,

ich habe einige Fragen zu diesem Programm.

1. Warum gehen die Leds an, wenn "PORTB = i;"
Welche Information beinhaltet "i"?

unsigned char i;
ist doch die Deklaration.
Aber wo wird das weiterverarbeitet??

2. Was bedeutet das Ausrufungszeichen in (!(PIND&0x04))  ??

Meine Kenntnisse in C sind begrenzt.
;(
1
// alle Lichter an
2
// Atmega8 mit 3,6864 MHz
3
// Sprache C
4
//------------------------------
5

6
#define F_CPU 3686400
7
#include <avr/io.h>
8
//#include <stdlib.h>
9

10

11

12
main () 
13
{
14

15
unsigned char i;
16

17
// hier Init-Code eingeben
18

19
DDRB = 0xFF;    // PortB = Ausgang
20
DDRD = 0x00;    // PortD = Eingang
21
PORTD = 0xFF;     // PortD = Pullup
22

23
while   (1)      // mainloop
24
    {
25
    // eine einfache Warteschleife
26
    for (int k=0; k<1000 ; k++) {};
27
    if (! (PIND & 0x04))        // Wenn Bit 2 = 0, dann Taster gedrückt
28
    PORTB = i;              // PortB wird geschaltet, Led an
29
    else
30
    PORTB = 0;              // Leds aus
31
    i++;
32
    }
33
}
Gast #5005892
Lesenswert?

> 1. Warum gehen die Leds an, wenn "PORTB = i;"
> Welche Information beinhaltet "i"?


> unsigned char i;
> ist doch die Deklaration.
> Aber wo wird das weiterverarbeitet??

hier:
>     i++;
++ bedeutet das zur variable 1 hinzugezählt wird ist das gleiche wie 
i+=1; oder i=1+i; (geht übrigends mit -- auch)

> 2. Was bedeutet das Ausrufungszeichen in (!(PIND&0x04))  ??
ein ! wird in C immer verwendet um boolsche (1 oder 0) ausdrücke zu 
negieren also wenn das dahinter TRUE ist ist es danach FALSE und 
umgekehrt

> Meine Kenntnisse in C sind begrenzt.
> ;(

Trau dich ruhig zu fragen und ignorier die trolle hier im forum...
OP #5005977
Lesenswert?

Dirk B. schrieb:
> MisterD schrieb:
>> hier:
>>>     i++;
>> ++ bedeutet das zur variable 1 hinzugezählt wird ist das gleiche wie
>> i+=1; oder i=1+i; (geht übrigends mit -- auch)
>
> Allerdings sollte der Compiler an der Stelle eine Warnung geben.
> Etwa "Erstbenutzung einer Variablen ohne Initialisierung".
>
> Wenn nicht, dann muss der Warnlevel angeüasst werden.

Ja er gibt auch eine Warnmeldung.
Aber ich habe das Programm 1 zu 1 aus einem Buch übernommen.

Was müsste ich tun um es richtig zu machen?
#5006012
Lesenswert?

Ich kommentiere das mal...:-)

---------------------------------------------------------

// alle Lichter an
// Atmega8 mit 3,6864 MHz
// Sprache C    == unsinnig! das sieht man am Quelltext oder 
fileextension.
//------------------------------

#define F_CPU 3686400
#include <avr/io.h>
//#include <stdlib.h>



main ()
{

unsigned char i;   == initialisiere hier!! zB.: unsigned char i = 0;

// hier Init-Code eingeben  == und warum steht dann da nix?

DDRB = 0xFF;    // PortB = Ausgang
DDRD = 0x00;    // PortD = Eingang
PORTD = 0xFF;     // PortD = Pullup

while   (1)      // mainloop  == nicht erforderlich
    {
    // eine einfache Warteschleife  == nicht erforderlicher Kommentar, 
schreibe statt dessen: delay xyz ms
    for (int k=0; k<1000 ; k++) {};
    if (! (PIND & 0x04))        // Wenn Bit 2 = 0, dann Taster gedrückt
    PORTB = i;              // PortB wird geschaltet, Led an  == wenn 
richtig initialisiert. Tip zum Vermeiden von Missverständnissen: 
Schliesse hier den code mit {} ein, um dangling elses zu vermeiden.
    else
    PORTB = 0;wenn richtiginitialisiert.      // Leds aus
    i++; == wann hat i welchen Inhalt??
    }
}
OP #5006013
Lesenswert?

ich verstehe das schon nicht.

 if (! (PIND & 0x04))

das "!" ist eine Negation.

"&" ist ein ein bitweises UND, also werden zwei binärzahlen addiert.

also steht da wenn (4 und 4) was ja "8" ergibt, das wiederum negiert...

wird der nächste Befehl ausgeführt,.



was soll eine negierte "8" bedeuten?
#5006034
Lesenswert?

Hallo nochmal,


es sie PIND = '00000100'
und es gelte :   PIND & 04h

es folgt:   '00000100'
     &      '00000100'
--------------------------
            '00000100' als Ergebnis. Die 'UND'-Verknüpfung erfolgt 
bitweise.


Sei nuin PIND = 00h
            '00000000'
     &      '00000100'
--------------------------
            '00000000'

da ds bitweise 'UND' nicht erfüllt wird. Diesen Vorgang nennt man 
maskieren. In deinem Code ist 04h die Maske.

Das '!' bildet das Komplement: Es wird

'0000 0100'    zu
'1111 1011'     invertiert.

Gruss

Robert
Moderator Persönliche Seite #5006039
Lesenswert?

O. A. schrieb:
> "&" ist ein ein bitweises UND,

Ja.

> also werden zwei binärzahlen addiert.

Nein. Wieso reimst Du Dir so etwas zusammen?

Eine bitweise AND-Operation arbeitet für jedes Bit nach dieser 
Wahrheitstafel:
1
  A B  A&B
2
  0 0  0
3
  0 1  0
4
  1 0  0
5
  1 1  1

Also: A&B ist nur dann 1, wenn A und B gleich 1 sind.

> also steht da wenn (4 und 4) was ja "8" ergibt, das wiederum negiert...

Nein, da gibt überhaupt nichts 8.

Nehmen wir mal an, dass der Pin D4 high ist, also 1.

Dann ist

  PIND = 00001000

0x04 ist binär:

  0x04 = 00001000

Und nur dann(!) ist:

  (PIND & 0x04) identisch mit 0001000

Da in C alle Werte wahr sind, die nicht 0 sind, ist dieser Ausdruck 
wahr. Da der Programmierer aber das genau den negierten Wert haben will, 
stellt er dem Ausdruck (PIND & 0x04) noch ein Ausrufungszeichen um. Das 
dreht nach der AND-Operation den Wahrheitsgehalt des Ausdrucks um.
Moderator Persönliche Seite #5006049
Lesenswert?

R. F. schrieb:
> Das '!' bildet das Komplement: Es wird
>
> '0000 0100'    zu
> '1111 1011'     invertiert.

Falsch! Dafür ist der Operator '~'.

Das Ausrufungszeichen negiert nur den Wahrheitswert einer Zahl. Für 
Bit-Operationen ist er schlecht bis gar nicht brauchbar, siehe auch 
Bitmanipulation

 - Aus der Zahl 0 wird 1.
 - Aus allen anderen Zahlen wird 0.

Beispiel:
1
  a = !0      // a ist danach 1
2
  a = !1234   // a ist danach 0
#5006051
Lesenswert?

Wenn ich das Programm richtig verstehe, es heißt ja "alle Lichter an", 
dann wird bei jedem Tastendruck ein anderes Muster auf die Ports 
gegeben, so dass irgendwann "alle Lichter an" sind.

O. A. schrieb:
> Ich weiß leider nicht welcher Init-Code da reinkäme
> und richtig initialisieren wäre nur "unsigened char i=1" ?

Es wäre ein sinnvoller Wert, damit gleich die erste LED an Port B.0 
angeht,
#5006058
Lesenswert?

1
/* neue Version, by RFr  */
2
/* Programm Licht_an schaltet auf Tastendruck die LED um  */
3

4
#define F_CPU 3686400
5
#include <avr/io.h>
6
/* Atmega8 mit 3,6864 MHz */
7

8

9
main () {
10
  unsigned char i;
11
  
12
  DDRB = 0xFF;    // PortB = als Ausgang gesetzt, LED wird eingeschaltet wenn 'H'  
13
  DDRD = 0x00;    // PortD = als Eingang gesetzt  
14
  PORTD = 0xFF;     // PortD = Pullup eingeschaltet   Taste legt Eingang auf 'H' wenn nicht gedrückt  
15
  
16
  
17
  while   (1)  {
18
    for (int k=0; k<1000 ; k++) {};    /* delay xyz ms */
19
    
20
    if (! (PIND & 0x04)) {PORTB = i}
21
    else {PORTB = 0};              // Leds aus
22
    /*   i++;  erforderlich für Lauflicht?? Schaltplaninformation zufügen!!  */
23
  }

[Mod: Obigen Code in [ c ] ... [ /c ] eingeklammert, damit er lesbar 
wird]
#5006061
Lesenswert?

Was in den anderen Beispielen mit dem & etwas untergeht, ist der 
Augsangswert vom Port D.
Der kann auch andere Werte haben.
Mit dem & 0x04 maskierst du aber nur das eine Bit raus.

 0111 0110
&0000 0100
-----------
=0000 0100

Darauf wird das ! angewandt und dann kommt 0 raus. Also unwahr -> Taster 
nicht gedrückt

Oder:

 0111 0010
&0000 0100
-----------
=0000 0000

Darauf wird das ! angewandt und dann kommt 1 raus. Also wahr -> Taster 
gedrückt
#5006063
Lesenswert?

>  - Aus der Zahl 0 wird 1.
>  - Aus allen anderen Zahlen wird 0.

Aus dem Wahrheitswert TRUE wird FALSE.
Und umgekehrt.
Bezüglich des Operators hat FramkM recht.
>
> Beispiel:
>
1
>   a = !0      // a ist danach TRUE, also irgendeinen von NULL verschiedenen Wert
2
>   a = !1234   // a ist danach False, entsprechend NULL.
3
>
Moderator Persönliche Seite #5006078
Lesenswert?

R. F. schrieb:
> - Aus der Zahl 0 wird 1.
>  - Aus allen anderen Zahlen wird 0.
>
> Aus dem Wahrheitswert TRUE wird FALSE.

Das sind nur andere Namen für 0 oder 1.

>   a = !0      // a ist danach TRUE, also irgendeinen von NULL verschiedenen Wert

Falsch, es hat nicht "irgendeinen" von NULL verschiedenen Wert, a ist 
danach definitiv 1. Probiere es einfach aus. Jeder C-Compiler, der 
sich so nennt, wird dafür sorgen, dass nachher 1 in der Variablen steht.
Moderator Persönliche Seite #5006146
Lesenswert?

R. F. schrieb:
> Richtig ist, dass ddie negierte Null eine eins ergibt und TRUE
> ist.
> Allerdings ist jeder Wert ungleich Null TRUE.

Ich weiß, was Du meinst und Deine Aussage steht auch in keinem 
Widerspruch zu den meinen oben. Aber bitte vermeide es, den Eindruck zu 
vermitteln, man könnte schreiben:
1
    int a = 42;
2

3
    if (a == TRUE)
4
    {
5
        printf ("Der Ausdruck ist wahr\n");
6
    }
7
    else
8
    {
9
        printf ("Der Ausdruck ist falsch\n");
10
    }

Denn das geht so nicht. TRUE ist in C nicht definiert. Das musst Du 
schon selber machen. Wie willst Du das hintricksen, dass obige Bedingung 
(a == TRUE) für alle Zahlen != 0 funktioniert?

Ich kenne nur einen Weg:
1
#define TRUE  1    // jawohl, 1 und nichts anderes!
2
#define FALSE 0
3
#define TRUTH(x) (!!(x))

Dann kannst Du obige Bedingung folgendermaßen schreiben:
1
    if (TRUTH(a) == TRUE)

und es funktioniert für alle a != 0.

Oder Du hast einen C-Compiler, der etwas weniger verstaubt ist. Dann 
kannst Du oben auch einfügen:
1
#include <stdbool.h>

und die Bedingung folgendermaßen schreiben:
1
    if ((bool) a == true)

Auch hier wird es ohne den cast "(bool)" nicht gehen. Der Ausdruck:
1
    if (a == true)

fliegt für a = 42 auf die Nase.

Wenn man aber mal neugierig ist und herausfinden will, was denn nun 
dieses kleingeschriebene "true" aus stdbool.h denn wirklich ist, dann 
fügt man in sein C-Programm mal ein:
1
    printf ("%d\n", true);

und wird sich über die Ausgabe "1" überhaupt nicht mehr wundern.

Fazit:

Du wirst TRUE oder true (aus stdbool.h) nicht anders als 1 definieren, 
um damit arbeiten zu können. Am besten lässt man es und schreibt direkt:
1
    if (a)

Dann muss man über TRUE oder true überhaupt nicht nachdenken.
OP #5006293
Lesenswert?

Ich habe mal eine andere Frage.

Wie kann ich diesen Delay Code, mit einer Tasterabfrage wie in dem 
ersten Code am Anfang kombinieren?

Delay:
1
#include <avr/io.h>
2
#define F_CPU 1000000UL
3
#include <util/delay.h>
4

5
int main( void )
6
{
7
    DDRB |= (1 << PB0);
8

9
    while(1) {
10
        PORTB ^= (1 << PB0);
11
        _delay_ms(1000);
12
    }
13
    return 0;
14
}

Dieser Code bringt eine Led zum blinken. Wie könnte ich das aber per 
Taster starten?

D.h. ich drücke einen Taster und dann startet die LED zu blinken.

Ich habe es schon versucht, bekomme aber Fehler und Warnungen....

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