www.mikrocontroller.net

Forum: Compiler & IDEs Flankenerknnung C


Autor: D. Kirschner (kirsche)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

habe vor kurzem mit dem programmieren angefangen und habe jz ein prob.
#include <avr/io.h>
#include <inttypes.h>

unsigned char output_value;

int main ()

{
  DDRB = 0xFF;
  PORTB = 0x00;

  DDRC = 0x00;
  PORTC = 0x04;

  do
  {
    if (!(PIND & 0x04))

     {
      output_value = !output_value;
     }

    PORTB = output_value; 
  }
while(1);
}

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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

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

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

Autor: Fer T. (fer_t)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll das bringen?:
PORTB = output_value;

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch.
output_value hat als globale Variable einen definierten Wert

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: D. Kirschner (kirsche)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: D. Kirschner (kirsche)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke =)

Autor: Keine Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend

Kann ich so eine Steigende und Fallende Flanke abfragen?

attiny13a in C.

•
#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL
#include <util/delay.h> 

uint8_t APortD, BPortD;

int main(void){
  
  DDRB |=(0<<PB0)|(1<<PB1)|(1<<PB2);  //PB0 auf ausgang PB1, PB2 auf eingang//
  
  PORTB |=(0<<PB0);  //Pull-Up Aktiv//
  
APortD = PINB0;
BPortD = PINB1;

    while(1)
    {
        if (APortD || APortD < PINB0)
        {
            PINB |=(1<<PB1);
        } 
        if (APortD || APortD > PINB0)
        {
            PINB |=(1<<PB2);  
        }
      
        
    }
  return 0;
}

Autor: Martin N. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist es richtig:
#include <avr/io.h>

#define F_CPU 1000000UL
#include <util/delay.h> 

uint8_t APortD;

int main(void)
{
  DDRB |= ((1<<PB1)|(1<<PB2));        //PB1 und PB2 auf Ausgang!
  DDRB &= ~(1<<PB0);                  //PB0 auf Eingang
    
  PORTB |=(1<<PB0);                   //Pull-Up Aktiv
  
  APortD = PINB0;

  while(1)
  {
     if (!(PINB&(1<<APortD)))         //Wenn auf Masse gezogen(also Logisch LOW)
     {
       PORTB |=(1<<PB1);              //dann PORTB1 "einschalten"
     } 
     if (PINB&(1<<APortD))            //Wenn Spannung anliegt(also Logisch HIGH)        
     {
       PORTB &= ~(1<<PB1);            //dann PORTB1 "ausschalten"
     }
  }
  return 0;
}

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

Autor: Martin N. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde mir aber auch die Variablen sparen:
#include <avr/io.h>

#define F_CPU 1000000UL

int main(void)
{
  DDRB |=  (1<<PB1);                  //PB1 auf Ausgang!
  DDRB &= ~(1<<PB0);                  //PB0 auf Eingang
    
  PORTB |=(1<<PB0);                   //Pull-Up Aktiv

  while(1)
  {
     if (!(PINB&(1<<PINB0)))          //Wenn auf Masse gezogen(also Logisch LOW)
     {
       PORTB |=(1<<PB1);              //dann PORTB1 "einschalten"
     } 
     if (PINB&(1<<PINB0))             //Wenn Spannung anliegt(also Logisch HIGH)        
     {
       PORTB &= ~(1<<PB1);            //dann PORTB1 "ausschalten"
     }
  }
  return 0;
}

Autor: Keine Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.


•
#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL
#include <util/delay.h> 

uint8_t APortD, BPortD, CPortD;

int main(void){
  
  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//
  
APortD = PINB0; //Variable Speichern//
BPortD = PINB1;
CPortD = PINB2;

    while(1)
    {
        if (APortD || APortD < PINB0) 
        {
      
      PINB |=(1<<PB1);
        } 
        if (APortD || APortD > PINB0)
        {
      PINB |=(1<<PB2);  
        }
      
        
    }
  return 0;
}


Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oooch nöö.

Ne 3 Jahre alte Leiche hijacken, warum?

Autor: Malte S. (maltest)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bischen Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Vielen Dank für die Hilfe.

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

•

#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL
#include <util/delay.h>

uint8_t APortD, BPortD, CPortD;
int Wahr;


int main(void){

  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//

  APortD = PINB0; //Variable Speichern//
  BPortD = PINB1;
  CPortD = PINB2;

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

    while(1){
      
    if (PINB & (1<<PINB0)) //Fragt PINB0 ab//
    {
      if (APortD || APortD < PINB0) //vergleicht variabel APortD mit PINB0 ob kleiner geworden ist = fallende Flanke// 
      {
        if (Wahr) //Ist das wahr//
        {
          PINB |=(1<<PB1); //Schaltet PINB1 auf High//
        }  
        else //Wenn nicht//
        {
          PINB |=(0<<PB1); //Schaltet PINB1 auf Low//
        }       
      }  
    }
              
    
    if (PINB & (1<<PINB0)) //Fragt PINB0 ab//
    {
      if (APortD || APortD > PINB0) //vergleicht variabel APortD mit PINB0 ob grösser geworden ist = Steigende Flanke// 
      {
        if (Wahr) //Ist das wahr//
        {
          PINB |=(1<<PB2); //Schaltet PINB2 auf High//
        }  
        else //Wenn nicht//
        {
          PINB |=(0<<PB2); //Schaltet PINB2 auf Low//
        }      
      }            
    }
    
  }
    return 0;
  }


Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mein Gott, das wird ja immer schlimmer...

Bischen Ahnung schrieb:

 if (Wahr)

Was soll das denn werden?

Bischen Ahnung schrieb:
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...

Autor: Bischen Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Malte S. (maltest)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Bischen Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Bin ich so auf dem richtigen Weg??

Danke für die Hilfe.



•
//attiny13a//
//C//

#include <avr/io.h>
#include <stdint.h>
#define F_CPU 1000000UL
#include <util/delay.h>

uint8_t APortD, APortD1;



int main(void){

  DDRB |=  (1<<PB1)|(1<<PB2);  // PB1, PB2, auf ausgang//
  DDRB &= ~(1<<PB0);      // PB0 auf eingang//
  PORTB |= (1<<PB0);      //Pull-Down Aktiv//

  //APortD =  //Variable//
  //APortD1 = 
  

  while(1){
    
    if (PINB & (1<<PINB0)) //Abfragen//
    {
      APortD = 1; //Zuweissen//
      
    }
  
    if (PINB & (1<<PINB0)) //Abfragen//
    {
      APortD1 = 2; //Zuweissen//
    }
    
    if (APortD || APortD < APortD1) //vergleichen//
    {
      PINB |=(1<<PB1); //Ausführen//
    }
    
    
      {
  return 0;
}

Autor: Bischen Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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??

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

   ...

   alter_Licht_Status = wie ist das Licht jetzt;

   while( 1 ) {
     
     neuer_Licht_Status = wie ist das Licht jetzt;

     if( alter_Licht_Status != neuer_Licht_Status )
     {
        if( neuer_Licht_Status == brennt )
          Heureka! Jemand hat jetzt gerade das Licht aufgedreht
        else
          Damn! Jemand hat jetzt gerade das Licht aus gemacht

        alter_Licht_Status = neuer_Licht_Status;
     }
   }

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.