Forum: Compiler & IDEs Flankenerknnung C


von D. K. (kirsche)


Lesenswert?

hallo,

habe vor kurzem mit dem programmieren angefangen und habe jz ein prob.
1
#include <avr/io.h>
2
#include <inttypes.h>
3
4
unsigned char output_value;
5
6
int main ()
7
8
{
9
  DDRB = 0xFF;
10
  PORTB = 0x00;
11
12
  DDRC = 0x00;
13
  PORTC = 0x04;
14
15
  do
16
  {
17
    if (!(PIND & 0x04))
18
19
     {
20
      output_value = !output_value;
21
     }
22
23
    PORTB = output_value; 
24
  }
25
while(1);
26
}

habe einen atmega8 (ohne externen takt)

und das will nicht so richtig funk. =(

ich bekomme die LED nicht zum leuchten. habs schon mal mit entprellen 
versucht aber dadurch wirds auch nicht besser...

glg

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>   DDRC = 0x00;
>   PORTC = 0x04;
>    if (!(PIND & 0x04))
              ^

>       output_value = !output_value;
Bitmanipulation und Unterschied ! vs. ~

von Fer T. (fer_t)


Lesenswert?

Was soll das bringen?:
PORTB = output_value;

Davor wurde output_value KEIN Wert zugewiesen, unbestimmter Inhalt, wie 
soll das funktionieren?

von Karl H. (kbuchegg)


Lesenswert?

Doch.
output_value hat als globale Variable einen definierten Wert

von Paul (Gast)


Lesenswert?

1. Der Pull-Up in Port D ist nicht aktiv.

2. Ich seh da keine Flankenauswertung.
   Der Pin in Port D wird statisch abgefragt.

von 900ss (900ss)


Lesenswert?

Prüfe mal,  ob du die richtigen Ports initialisierst und ob du genau die 
auch nutzt.
Weiter: ist deine Initialisierung richtig?

Eine Flankenerkennung fehlt dir aber trotzdem. Solange der Eingang aktiv 
ist, wird der Teilung in "if" ausgeführt. Für eine Flankenerkennung 
musst du dir den vorher eingelesen Zustand in einer statischen Variable 
merken.

von Peter D. (peda)


Lesenswert?

Dav Kirschner schrieb:
> habs schon mal mit entprellen
> versucht aber dadurch wirds auch nicht besser

Dann war das auch kein richtiges Entprellen.
Es soll sogar Leute geben, die denken Entprellen und Delay wäre 
dasselbe.

Idealer Weise nimmt man ne Entprellroutine, die gleich die Drück-Flanke 
mit erkennt (fällt quasi beim Entprellen mit ab).
Die Flanke wird ja fast immer benötigt und nicht so sehr der entprellte 
Zustand.
Das spart fürderhin ne Menge Programmierarbeit und man kann sich besser 
auf die eigentliche Aufgabe konzentrieren.


Peter

von D. K. (kirsche)


Lesenswert?

@ stefan,

danke mit "~" hats geklapt =) und bei DDRC hab ich nur probiert ob mein 
PORT defekt ist...und habs vergessen umzusreiben xD

und wie macht man so eine entprellung ohne delay?

glg

von Rolf M. (rmagnus)


Lesenswert?


von D. K. (kirsche)


Lesenswert?

ok danke =)

von Keine Ahnung (Gast)


Lesenswert?

Guten Abend

Kann ich so eine Steigende und Fallende Flanke abfragen?

attiny13a in C.

•
1
#include <avr/io.h>
2
#include <stdint.h>
3
#define F_CPU 1000000UL
4
#include <util/delay.h> 
5
6
uint8_t APortD, BPortD;
7
8
int main(void){
9
  
10
  DDRB |=(0<<PB0)|(1<<PB1)|(1<<PB2);  //PB0 auf ausgang PB1, PB2 auf eingang//
11
  
12
  PORTB |=(0<<PB0);  //Pull-Up Aktiv//
13
  
14
APortD = PINB0;
15
BPortD = PINB1;
16
17
    while(1)
18
    {
19
        if (APortD || APortD < PINB0)
20
        {
21
            PINB |=(1<<PB1);
22
        } 
23
        if (APortD || APortD > PINB0)
24
        {
25
            PINB |=(1<<PB2);  
26
        }
27
      
28
        
29
    }
30
  return 0;
31
}

von Martin N. (Gast)


Lesenswert?

So ist es richtig:
1
#include <avr/io.h>
2
3
#define F_CPU 1000000UL
4
#include <util/delay.h> 
5
6
uint8_t APortD;
7
8
int main(void)
9
{
10
  DDRB |= ((1<<PB1)|(1<<PB2));        //PB1 und PB2 auf Ausgang!
11
  DDRB &= ~(1<<PB0);                  //PB0 auf Eingang
12
    
13
  PORTB |=(1<<PB0);                   //Pull-Up Aktiv
14
  
15
  APortD = PINB0;
16
17
  while(1)
18
  {
19
     if (!(PINB&(1<<APortD)))         //Wenn auf Masse gezogen(also Logisch LOW)
20
     {
21
       PORTB |=(1<<PB1);              //dann PORTB1 "einschalten"
22
     } 
23
     if (PINB&(1<<APortD))            //Wenn Spannung anliegt(also Logisch HIGH)        
24
     {
25
       PORTB &= ~(1<<PB1);            //dann PORTB1 "ausschalten"
26
     }
27
  }
28
  return 0;
29
}

So als Beispiel... ich wüsste sonst nicht was du mit deinem Code 
anstellen wolltest?!?!

von Martin N. (Gast)


Lesenswert?

Ich würde mir aber auch die Variablen sparen:
1
#include <avr/io.h>
2
3
#define F_CPU 1000000UL
4
5
int main(void)
6
{
7
  DDRB |=  (1<<PB1);                  //PB1 auf Ausgang!
8
  DDRB &= ~(1<<PB0);                  //PB0 auf Eingang
9
    
10
  PORTB |=(1<<PB0);                   //Pull-Up Aktiv
11
12
  while(1)
13
  {
14
     if (!(PINB&(1<<PINB0)))          //Wenn auf Masse gezogen(also Logisch LOW)
15
     {
16
       PORTB |=(1<<PB1);              //dann PORTB1 "einschalten"
17
     } 
18
     if (PINB&(1<<PINB0))             //Wenn Spannung anliegt(also Logisch HIGH)        
19
     {
20
       PORTB &= ~(1<<PB1);            //dann PORTB1 "ausschalten"
21
     }
22
  }
23
  return 0;
24
}

von Keine Ahnung (Gast)


Lesenswert?

Guten Tag

Ich wollte an PINB0 ein Signal anschliessen das Steigende und Fallende 
Flanke ausgibt, der attiny13a sollte dann das Signal in einer Variabel 
speichern und wieder mit PINB0 vergleichen ob es sich verändert hat.

Oder kann man so nur High und Low auswerten. Weill das Signal nur die 
Spannung verändert und nicht High auf Low schaltet??

Vielen Dank für die Hilfe.


•
1
#include <avr/io.h>
2
#include <stdint.h>
3
#define F_CPU 1000000UL
4
#include <util/delay.h> 
5
6
uint8_t APortD, BPortD, CPortD;
7
8
int main(void){
9
  
10
  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
11
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
12
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//
13
  
14
APortD = PINB0; //Variable Speichern//
15
BPortD = PINB1;
16
CPortD = PINB2;
17
18
    while(1)
19
    {
20
        if (APortD || APortD < PINB0) 
21
        {
22
      
23
      PINB |=(1<<PB1);
24
        } 
25
        if (APortD || APortD > PINB0)
26
        {
27
      PINB |=(1<<PB2);  
28
        }
29
      
30
        
31
    }
32
  return 0;
33
}

von Justus S. (jussa)


Lesenswert?

wie willst du denn eine Flanke erkennen, wenn du in deinem ganzen Code 
keinen Eingang abfragst? Und überleg doch bitte mal, was in deinen 
If-Abfragen steht...

von Peter D. (peda)


Lesenswert?

Oooch nöö.

Ne 3 Jahre alte Leiche hijacken, warum?

von Malte S. (maltest)


Lesenswert?

Zumal wenn der richtige Artikel bereits verlinkt war.
Und sieh die mal die Definitionen von PINB0 etc. an. Und versuche mal, 
die if-Bedingungen en detail zu erklären, vielleicht merkst du ja dann 
selber, dass die abstrus sind.

von Bischen Ahnung (Gast)


Lesenswert?

Guten Tag

Vielen Dank für die Hilfe.

Habe noch einmal überlegt hoffe man versteht was ich gerne machen würde.

•
1
#include <avr/io.h>
2
#include <stdint.h>
3
#define F_CPU 1000000UL
4
#include <util/delay.h>
5
6
uint8_t APortD, BPortD, CPortD;
7
int Wahr;
8
9
10
int main(void){
11
12
  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
13
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
14
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//
15
16
  APortD = PINB0; //Variable Speichern//
17
  BPortD = PINB1;
18
  CPortD = PINB2;
19
20
  Wahr =  1;  //erkennt if abfrage als wahr//
21
  
22
23
    while(1){
24
      
25
    if (PINB & (1<<PINB0)) //Fragt PINB0 ab//
26
    {
27
      if (APortD || APortD < PINB0) //vergleicht variabel APortD mit PINB0 ob kleiner geworden ist = fallende Flanke// 
28
      {
29
        if (Wahr) //Ist das wahr//
30
        {
31
          PINB |=(1<<PB1); //Schaltet PINB1 auf High//
32
        }  
33
        else //Wenn nicht//
34
        {
35
          PINB |=(0<<PB1); //Schaltet PINB1 auf Low//
36
        }       
37
      }  
38
    }
39
              
40
    
41
    if (PINB & (1<<PINB0)) //Fragt PINB0 ab//
42
    {
43
      if (APortD || APortD > PINB0) //vergleicht variabel APortD mit PINB0 ob grösser geworden ist = Steigende Flanke// 
44
      {
45
        if (Wahr) //Ist das wahr//
46
        {
47
          PINB |=(1<<PB2); //Schaltet PINB2 auf High//
48
        }  
49
        else //Wenn nicht//
50
        {
51
          PINB |=(0<<PB2); //Schaltet PINB2 auf Low//
52
        }      
53
      }            
54
    }
55
    
56
  }
57
    return 0;
58
  }

von Justus S. (jussa)


Lesenswert?

mein Gott, das wird ja immer schlimmer...

Bischen Ahnung schrieb:

1
 if (Wahr)

Was soll das denn werden?

Bischen Ahnung schrieb:
1
if (APortD || APortD > PINB0) //vergleicht variabel APortD mit PINB0

und das ist immer noch totaler Schwachsinn!

tu dir selbst einen Gefallen, nehm dir ein C-Buch und lern erstmal die 
Grundlagen, unabhängig von einem µC...

von Bischen Ahnung (Gast)


Lesenswert?

Guten Tag

Würde es so gehen??

 APortD = PINB0; //Variable Speichern//
 APortD1 = PINB0;

Und dann variable APortD und APortD1 miteinander vergleichen??
Oder muss ich einen anderen Pin dazu ziehen??

Vielen DANK

P.S welches C Buch würdest Du mir empfehlen.

von Malte S. (maltest)


Lesenswert?

Bischen Ahnung schrieb:
> APortD = PINB0; //Variable Speichern//
>   BPortD = PINB1;
>   CPortD = PINB2;

Was meinst du mit "Variable Speichern"?
Was erwartest du, welche Werte diese Variablen nach diesen Zuweisungen 
haben und was bedeuten diese Werte deiner Meinung nach?

>   Wahr =  1;  //erkennt if abfrage als wahr//

Der Kommentar lässt schon Schlimmes vermuten...

> if (PINB & (1<<PINB0)) //Fragt PINB0 ab//

Und dies ist genau die einzige Stelle, an der du tatsächlich den Pin 
abfragst!

>     {
>       if (APortD || APortD < PINB0) //vergleicht variabel APortD mit
> PINB0 ob kleiner geworden ist = fallende Flanke//

Hint: PINB0 ist ein Präprozessor-Makro, das konkret zu 0 ersetzt wird. 
Da verändert sich niemals nichts.

>       {
>         if (Wahr) //Ist das wahr//

Und hier bestätigt sich die Befürchtung. Du kannst noch so oft eine 
Variable für "Wahr" verwenden, de facto ist es eine Konstante und es 
würde mich sehr wundern, wenn die nicht wegoptimiert würde. Auch wenn 
sie erstmalig mit 0 initialisiert wird, gibt es nur eine einzige 
Zuweisung am Beginn deines Programms. Wahr ist immer 1, diese Bedingung 
also immer wahr...

>         {
>           PINB |=(1<<PB1); //Schaltet PINB1 auf High//

Bist du sicher, dass du PINB zuweisen möchtest. Dieses SFR hat zwar die 
spezielle Eigenschaft, den Pin zu toggeln, wenn du 1 zuweist, aber 
irgendwie bezweifel ich, dass das deine Intention war.

>         }
>         else //Wenn nicht//

...und der else-Zweig kann nie ausgeführt werden.

>         {
>           PINB |=(0<<PB1); //Schaltet PINB1 auf Low//

s. oben. und

PINB |= (0 << PB1);

ist funktional äquivalent zu

PINB = PINB;

Also: zusätzlich zu Entprellung guckst du hier: Bitmanipulation 
und befasst dich mit den Grundlagen der Sprache C.

von Justus S. (jussa)


Lesenswert?

Bischen Ahnung schrieb:
> Und dann variable APortD und APortD1 miteinander vergleichen??

und was soll es bringen, '0' und '0' zu vergleichen?

PINB0 ist '0' und bleibt '0', dennso ist PINB0 definiert, eine simple 
'0' und mehr nicht. Damit ist auch APortD einfach '0' und ändert sich 
auch nie, da du ja nie auch nur versuchst, einen neuen Wert 
zuzuweisen...

von Justus S. (jussa)


Lesenswert?

Malte S. schrieb:
> Was meinst du mit "Variable Speichern"?

ich vermute/befürchte, er würde damit APortD auf irgendeine magische 
Weise mit PINB0 'verknüpfen'... und dass er die Bedeutung von PINB0 
überhaupt nicht versteht hast du ja auch verstanden...

von Bischen Ahnung (Gast)


Lesenswert?

Guten Tag

Bin ich so auf dem richtigen Weg??

Danke für die Hilfe.



•
1
//attiny13a//
2
//C//
3
4
#include <avr/io.h>
5
#include <stdint.h>
6
#define F_CPU 1000000UL
7
#include <util/delay.h>
8
9
uint8_t APortD, APortD1;
10
11
12
13
int main(void){
14
15
  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
16
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
17
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//
18
19
  //APortD =  //Variable//
20
  //APortD1 = 
21
  
22
23
  while(1){
24
    
25
    if (PINB & (1<<PINB0)) //Abfragen//
26
    {
27
      APortD = 1; //Zuweissen//
28
      
29
    }
30
  
31
    if (PINB & (1<<PINB0)) //Abfragen//
32
    {
33
      APortD1 = 2; //Zuweissen//
34
    }
35
    
36
    if (APortD || APortD < APortD1) //vergleichen//
37
    {
38
      PINB |=(1<<PB1); //Ausführen//
39
    }
40
    
41
    
42
      {
43
  return 0;
44
}

von Bischen Ahnung (Gast)


Lesenswert?

Guten Tag

Ich bin jetzt am C-Tutorial von NR-Wissen am lernen.

Könnte mir jemand die Flankenerkennung von der seite 
mikrocontroller/Entprellung erklären??

von Karl H. (kbuchegg)


Lesenswert?

Bischen Ahnung schrieb:
> Guten Tag
>
> Ich bin jetzt am C-Tutorial von NR-Wissen am lernen.
>
> Könnte mir jemand die Flankenerkennung von der seite
> mikrocontroller/Entprellung erklären??

Was ist denn eine Flanke?

Eine Flanke ist der Wechsel eines Zustands.

Wenn du zum Nachbarn schaust, dann merkst du dir, dass dort das Licht 
nicht brennt.
Beim nächsten mal hinsehen brennt das Licht immer noch nicht. D.h. du 
weißt, das sich nichts getan hat.
Gleich darauf schaust du nochmal hin. Das Licht brennt immer noch nicht.
Ein paar Sekunden später fällt dein Blick wieder rüber (du kontrollierst 
den Status des Lichtes). Aha! Diesmal brennt das Licht! D.h durch den 
Vergleich "vorhin hat es noch nicht gebrannt, jetzt aber brennt es" hast 
du die 'Flanke' "Das Licht wurde eingeschaltet" erkannt.
1
   ...
2
3
   alter_Licht_Status = wie ist das Licht jetzt;
4
5
   while( 1 ) {
6
     
7
     neuer_Licht_Status = wie ist das Licht jetzt;
8
9
     if( alter_Licht_Status != neuer_Licht_Status )
10
     {
11
        if( neuer_Licht_Status == brennt )
12
          Heureka! Jemand hat jetzt gerade das Licht aufgedreht
13
        else
14
          Damn! Jemand hat jetzt gerade das Licht aus gemacht
15
16
        alter_Licht_Status = neuer_Licht_Status;
17
     }
18
   }

denk darüber nach, wende das Kochrezept auf deine Taste an.
Und kapere keine 3 Jahre alten Threads mehr.

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.