mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfänger Frage zu variable hochzählen


Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte während ich den taster an PA0 drücke die variable a immer um 
+1 hochzählen. wenn ich ihn erneut drücke soll die Variable a wieder um 
+1 hoch gezählt werden. also drücken a=1 ,erneut drücken a=2, erneut 
drücken a=3 usw...


aber was habe ich hier nicht beachtet es scheint so als würde er mir 
nicht richtig hochzählen (willkürlich). Taster mit kondensator 
entprellt.

grüsse huber

/*
 * GccApplication5.c
 *
 * Created: 17.09.2016 09:47:49
 *  Author: Daniela Weinhart
 */ 
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>

int main(void)
{ // EIN und Ausgänge konfigurieren
  PORTA = (1<<PA0);
  DDRA = (1<<PA1);
  
    while(1)
    {   // Taster 1
    int a = 0;
    
    while( a <=5)
    {
      if (!(PINA & (1<<PA0)))
      {  
        a = a+1;
      } 
      
      
      if (a == 2)
      {
        PORTA |= (1<<PA1);
      }
      
      if (a == 3)
      {
       PORTA &= ~(1<<PA1);
          
      }
        
      if (a == 5)
      {
        a = 0;
      }
      
    }
    
        
    }
}

: Verschoben durch Moderator
Autor: Thomas E. (picalic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus Hubert,

Du darfst die Variable nicht hochzählen, solange der Taster sich im 
gedrückten Zustand befindet, sondern nur, wenn er vom nicht-gedrückten 
in den gedrückten übergeht!

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> Taster mit kondensator entprellt.

Taster mit Software entprellen. (s. Artikel Entprellung)

Für nicht genutzten Flash-Speicher gibt es kein Geld zurück.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Taster mit Software entprellen. (s. Artikel Entprellung)
>
> Für nicht genutzten Flash-Speicher gibt es kein Geld zurück.

Software Entprellung benötigt auch Ram.
Oder es wird Zeit in delays verplempert.

: Bearbeitet durch User
Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bin ich hier auf dem richtigen weg?
denn es macht nicht was es soll.

-ich drücke, lasse los, dann zählt er um eins hoch, also a = 1 ? noch 
keine Funktion?
-ich drücke erneut. lasse los,zählt wieder um eins hoch, also a = 2? 
jetzt müsste er mir doch PA1 Einschlten?
/*
 * GccApplication5.c
 *
 * Created: 17.09.2016 09:47:49
 *  Author: Daniela Weinhart
 */ 
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>

int main(void)
{ // EIN und Ausgänge konfigurieren
  PORTA = (1<<PA0);
  DDRA = (1<<PA1);
  
    while(1)
    {   // Taster 1
    int a = 0;
    
    while( a <=5)
    {
      if (!(PINA & (1<<PA0))==0)
      {  
         a++;
      } 
      
      
      if (a == 2)
      {
        PORTA |= (1<<PA1);
      }
      
      if (a == 3)
      {
       PORTA &= ~(1<<PA1);
          
      }
        
      if (a == 5)
      {
        a = 0;
      }
      
    }
    
        
    }
}

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Software Entprellung benötigt auch Ram.
> Oder es wird Zeit in delays verplempert.

Die wenigen RAM-Bytes werden wohl noch irgendwo zu finden sein.

Wer sein Timing auf solchen Zeitskalen mit delay() macht, hat allerdings 
schnell verloren, wenn sich der µC auch noch um andere Dinge kümmern 
soll. Falls die einzige Aufgabe allerdings ist, auf eine Taste 
aufzupassen, ist es egal, womit er die Zeit verplempert. Irgendwie muss 
er sie rum kriegen ;-)

Autor: Top S. (topsoft)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst dir den alten Tastenzustand merken. Hier ein Beispiel. Mal 
schnell nebenbei und ungetestet. Allerdings solltest du das Konzept 
überdenken. So macht man das nicht.

int main(void){
    PORTA = (1 << PA0);
    DDRA = (1 << PA1);   
    uint8_t a = 0, taste_old = PINA & (1<<PA0);
    while(1){
        if(!(PINA & (1<<PA0))){
            if(taste_old){
                if(a < 6)
                    a++;
                else
                    a = 0;
                if(a==2)
                    PORTA |= (1 <<PA1);
                else if(a==3)
                    PORTA &= ~(1 << PA1);
                taste_old = 0;
            }
        }
        else
            taste_old = (1 << PA0);
    }
}

: Bearbeitet durch User
Autor: Holger L. (max5v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als ganz einfachen Test könntest du in dem If- Block der Tasterabfrage 
gegen das Prellen _delay_ms() einsetzen.
Tasterabfrage Taster gedrückt, kurz warten.
Schleife,
Tasterabfrage Taster nicht gedrückt, kurz warten.

Um die Ergebnisse zu überprüfen würde ich an deiner Stelle mit einer Led 
einen Blinkcode ausgeben, damit ist die ganze Geschichte deutlich besser 
überschaubar.
// Blinken
void blink_led_x(uint8_t anzahl)
{
  for (; anzahl > 0; anzahl--)
  {
    PORTA &=~ (1 << PA1); // Ausschalten
    _delay_ms(150);
    
    PORTA  |= (1 << PA1); // Einschlten
    _delay_ms(350);
  }
  PORTA &=~ (1 << PA1); // Ausschalten
}

Autor: c-hater (Gast)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Arduino F. schrieb:

> Software Entprellung benötigt auch Ram.

Das stimmt. Ein ganzes sattes Byte für bis zu acht Tasten. Wer zum 
Teufel kann sich solcherart Verschwendung heutzutage denn noch leisten?

Autor: W.S. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> bin ich hier auf dem richtigen weg?
> denn es macht nicht was es soll.

Geh mal ganz systematisch und ohne Programmiersprache an das Problem 
heran. Stell dir dazu einen Beamten vor, der in seinem Amt alle Arbeiten 
machen muß. (jaja im Gedankenexperiment gibt es sowas...)

Dieser Beamte kommt in das Zimmer für die Taste, setzt sich an den 
Schreibtisch und guckt auf das Arbeitsbuch auf dem Tisch, wo draufsteht, 
was er zuletzt gemacht hat.

Also:
Fall 1: auf dem Zettel steht: kein aktueller Vorgang am Laufen, die 
Taste war zuletzt aus.
Jetzt guckt er nach der Taste und stellt fest:
a) die ist immer noch aus. Also steht er auf und geht an seine nächste 
Arbeit.

b) die Taste ist jetzt gedrückt. Also schreibt er auf nen Zettel: "Taste 
wurde gedrückt, bitte Vorgang bearbeiten" und steckt ihn in die 
amtsinterne Post. Anschließend schreibt er in das Arbeitsbuch: "Vorgang 
ist am Laufen" und "Entprellzeit = 100 Bewertungen". Danach geht er an 
seine nächste Arbeit.

Fall 2: auf dem Zettel steht:"Vorgang ist am Laufen".
Jetzt guckt er nach der Taste und stellt fest:
a) die Taste ist ungedrückt. Jetzt liest er im Arbeitsbuch: 
"Entprellzeit = xxx Bewertungen". (xxx steht für eine Zahl) Er radiert 
die Zahl aus und schreibt Zahl-1 hinein. Wenn das nun Null ergibt, dann 
radiert er den gesamten Vorgang aus und schreibt "kein aktueller Vorgang 
am laufen". Danach geht er an seine nächste Arbeit.

b) die Taste ist immer noch gedrückt. Also radiert er die Zahl für die 
Entprellzeit aus und schreibt "100" hinein. Danach geht er an seine 
nächste Arbeit.

So. Ist dir jetzt klar, wie man an solche Dinge herangehen kann? Die 
Story dürfte sich selbst für einen ungeübten Programmierer ohne Probleme 
in eine beliebige Programmiersprache übersetzen lassen.

Und nochwas: Eigentlich reicht es dem Beamten ja aus, zu sehen, ob die 
Zahl auf dem Arbeitsbuch Null ist oder nicht.

W.S.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also, jetzt habe ich es mal so geschrieben, aber was mir einfach nicht 
einleuchtet, warum er mir den druckzaehler nicht um eins höher zählt. 
liegt das hier an der while schleife.

mir geht es hauptsächlich jetzt mal darum, das mir das mit dem zählen 
endlich mal einleuchtet.

/*
 * GccApplication6.c
 *
 * Created: 17.09.2016 14:55:12
 *  Author: Daniela Weinhart
 */ 
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>

int main(void)
{   // Aus und Eingänge konfigurieren
  DDRA = (1<<PA1);
  PORTA = (1<<PA0);
  
    while(1)
    {
    int tasterstatus = 0;
    int druckzaehler = 0;
    
    if (!(PINA &(1<<PA0)))
    {  _delay_ms(15);
      tasterstatus = 1 ;
    }
    if (tasterstatus ==1)
    {
      druckzaehler++;
    } 
    else
    {
      if (druckzaehler == 1)
      {
        PORTA |= (1<<PA1);
        _delay_ms(250);
        PORTA &= ~(1<<PA1);
        _delay_ms(250);
        PORTA |= (1<<PA1);
        _delay_ms(250);
        PORTA &= ~(1<<PA1);
        _delay_ms(250);
        PORTA |= (1<<PA1);
        
      }
      if (druckzaehler == 2)
      {
        PORTA |= (1<<PA1);
        
      }
      else
      {
        if (druckzaehler==3)
        {
          PORTA &= ~(1<<PA1);
        }
        
        if(druckzaehler == 4)
        {
          druckzaehler = 0;
        }
      }
    }
    
  }
}

Autor: Tippgeber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Ablauf von Deinem Programm sollte etwa folgender sein:

  - Variablen und Hardware vorbereiten und einstellen
  - Wiederhole für immer:
    - Warte auf "Taste nicht gedrückt"
    - Warte auf "Taste gedrückt"
    - Zähle um Eins hoch


Wie Du siehst, kommt zweimal "Warte auf irgendwas" vor. So ein Warte 
könnte man folgendermaßen programmieren:

  - Weil "irgendwas" nicht wahr ist, wiederhole:
    - Mache nichts


Verstanden?

Autor: ASDFGHJKL (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ueberleg, was passiert, wenn der Taster gedrueckt und nicht wieder 
losgelassen wird.

ASDFGHJKL

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann ist das signal 1 also wahr Boolsche regel. mein problem ist nicht 
das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum 
hochzählen.

int tasterstatus = 0;
int zähler = 0;

if (tastergedrückt)

setze mir den tasterstatus auf 1

wenn der tasterstatus 1 ist


zähle mir den zähler um eins rauf

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> if (!(PINA &(1<<PA0)))
>     {  _delay_ms(15);

Das kann bestenfalls ein Gamer oder der Sieger im Schnellschreiben.
Ein typischer Nutzer benötigt 300ms zum Drücken und 300ms zum Loslassen.
Die universelle Lösung ist daher ein Timerinterrupt, der das Entprellen 
und die Flankenerkennung im Hintergrund erledigt. Die Mainloop liest 
dann einfach nur das Drück-Flag und löscht es.

Autor: Holger L. (max5v)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.c-howto.de/tutorial-verzweigungen-if-else.html

Die Variable "druckzaehler" wird nach jedem Durchlauf wider auf 0 
gesetzt, kann dementsprechend niemals größer als 1 werden.

Die "else if (druckzaehler == 1)" kann nicht ausgeführt werden solange 
"if (tasterstatus ==1)" wahr ist.

Wenn "if (tasterstatus ==1)" unwahr ist wurde "druckzaehler" bereits 
wider auf 0 gesetzt.

Autor: Thomas E. (picalic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> dann ist das signal 1 also wahr Boolsche regel. mein problem ist nicht
> das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum
> hochzählen.

Du hast Dich verrant und suchst an der falschen Stelle!
Benutze den Debugger und führe damit das Programm Schritt für Schritt 
aus! Damit kannst Du es genau verfolgen und wirst sehen, wo das Programm 
etwas anderes tut, als Du Dir vorstellst.

: Bearbeitet durch User
Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> mein problem ist nicht
> das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum
> hochzählen.

Ich würde das etwas anders formulieren: Du hast Schwierigkeiten, die 
ganze Sache rein logisch zu verstehen und dir eine geeignete Lösung dazu 
zu erarbeiten. Und verstehendes Lesen ist dir auch nicht wirklich 
genehm.

Vielleicht dazu noch ein Rat: Programmierer sein, heißt nicht, in irgend 
einer Programmiersprache etwas syntaktisch richtiges hinschreiben zu 
können, sondern es heißt, gute Algorithmen zum Lösen von Problemen 
erarbeiten und formulieren zu können.

W.S.

Autor: Aufpasser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
~~~~~~~~

>  *  Author: Daniela Weinhart
              ~~~~~~~~~~~~~~~~


Ja mei, abgekupfert ist es auch noch...

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das ist nicht abgekupfert sondern der laptop meiner freundin.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
           start
             |
             +<-------,
             |        |
          taster      |
         gedrückt?    |
         ja   nein    |
          |     |     |
          |     '-->--+
          +<-------,  |
          |        |  |
       taster      |  |
      gedrückt?    |  |
      nein  ja     |  |
       |     |     |  |
       |     '-----'  |
      N++             |
       |              |
       '------->------'



Gruß

Jobst

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:
> start

Nun ja, geht, aber das ist blockierend konstruiert. Außerdem vertraut es 
auf hardwaremäßige Entprellung.

So langsam müßte unser TO endlich in die Puschen kommen.

W.S.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Nun ja, geht, aber das ist blockierend konstruiert.

Außerdem läuft die gewünschte Aktion erst nach Loslassen ab.
Man möchte aber die Reaktion schon beim Drücken haben.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Nun ja, geht, aber das ist blockierend konstruiert.

War nicht gefordert, dass es nicht so ist.


Peter D. schrieb:
> Man möchte aber die Reaktion schon beim Drücken haben.

Huber M. schrieb:
> -ich drücke, lasse los, dann zählt er um eins hoch


Gruß

Jobst

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> So langsam müßte unser TO endlich in die Puschen kommen.

Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand 
zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...

Er lässt sich das wohl lieber erklären / vormachen ...

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand
> zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...




Ich muss mir erst noch eines für C99  bestellen, denn ich habe zwei, 
aber aus meiner unwissenheit sind diese für arduino und arduino und C 
gewesen, denn ich will nicht mit forgefertigten platinen arbeiten, 
sondern ich will mir selbst welche bauen. Deshalb dachte ich mir das der 
arduino nicht das richtige für mich ist,Und habe in bei seite gelegt. 
Und habe mir attiny24a, atmega8 zugelegt. und einen isp mk2 programmer 
original.Und ja das grundprinzip ist das gleiche, aber dann für mich 
auch irgendwie doch nicht.

Dieter F. schrieb:
> Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand
> zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...


>
> Er lässt sich das wohl lieber erklären / vormachen ...

das stimmt nicht, ich frage nur wenn ich etwas nicht weiss oder 
verstehe.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jetzt habe ich schon mal ein buch, aber ich bin immer noch nicht 
gescheiter.
#define F_CPU 1000000UL
#include <util/delay.h>
#include <stdbool.h>
#include <avr/io.h>
#define led (1<<PC0)
#define ein PORTC |=
#define aus PORTC &= ~

bool tastergedrueckt = true;

int main(void)
{ DDRC = (1<<PC0);
  PORTD =(1<<PD0);
  
  
  void ledblink()
  {
   PORTC |= (1<<PC0);
   _delay_ms(400);
   PORTC &= ~(1<<PC0);
   _delay_ms(400); 
   PORTC |= (1<<PC0);
   _delay_ms(400);
   PORTC &= ~(1<<PC0);
   _delay_ms(400);
  }
  
  
  
    while(1)
    {
    
    
    
   if (!(PIND&(1<<PD0)))
   {   _delay_ms(300);
     tastergedrueckt = true;
   } 
   else
   {
     tastergedrueckt = false;
   }
      
   if (tastergedrueckt == true)
   {
     PORTC |= (1<<PC0);
    
     
   }
   int a = 0;
   if (tastergedrueckt == false)
   {
     PORTC &= ~(1<<PC0);
     a=a+1;
   }
   if (a >= 5)
   {
     ledblink();
   }
   
   
   
    }
}

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> jetzt habe ich schon mal ein buch, aber ich bin immer noch nicht
> gescheiter.

Es reicht nicht, es zu haben.


Gruß

Jobst

Autor: Manfred (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:

>            start
>              |
>              +<-------,
>              |        |
>           taster      |
>          gedrückt?    |
>          ja   nein    |
>           |     |     |
>          N++    '-->--+
>           +<-------,  |
>           |        |  |
>        taster      |  |
>       gedrückt?    |  |
>       nein  ja     |  |
>        |     |     |  |
>        |     '-----'  |
>        |              |
>        |              |
>        '------->------'

So zählt er schon beim drücken hoch. ;-)

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manfred schrieb:
> So zählt er schon beim drücken hoch. ;-)

Super, kam schon jemand anders drauf. Ist aber genau das, was der TO 
nicht möchte:

Huber M. schrieb:
> -ich drücke, lasse los, dann zählt er um eins hoch


Gruß

Jobst

Autor: Manfred (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:


Das stimmt so aber nicht. Das war der erste Satz des TO

> Hallo,
>
> ich möchte während ich den taster an PA0 drücke die variable a immer um
> +1 hochzählen.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann soll er sich das aussuchen ...

Autor: Murmelchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,

würdest Du dein Programm Schritt für Schritt durchgehen und zudem auch 
noch zumindest halbwegs verstehen, was Du da geschrieben hast, dann 
solltest Du eigentlich auch erkennen, was mit deinem Zähler, also der 
Variablen a, innerhalb deiner Endlosschleife passiert und warum es nicht 
gut ist, eine Variable, die ja innerhalb dieser Endlosschleife nur 
aufgrund eines bestimmten Ereignisses inkrementiert werden soll, auch 
gleichzeitig (immer wieder) in dieser Schleife zu initialisieren.

Schau, wo deine Endlosschleife beginnt und wie weit sie geht und 
überlege Dir dann einfach mal, was durch den Ausdruck  int a = 0; 
innerhalb dieser Endlosschleife bewirkt wird.

Apropos, auch das
#define led (1<<PC0)
#define ein PORTC |=
#define aus PORTC &= ~

ist zwar ein ganz netter Ansatz bezüglich besserer Lesbarkeit, aber so 
auch noch ziemlich verdreht, zumal es bisher ja auch noch gar keine 
Verwendung in deinem Programm findet. Das aber auch nur so am Rande. Auf 
dein Zählerproblem hat es keinen Einfluss.


Mit besten Grüßen

Murmelchen

Autor: Thomas E. (picalic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Murmelchen schrieb:
> würdest Du dein Programm Schritt für Schritt durchgehen

am Besten mit einem Debugger - @Michael: warum benutzt Du den nicht?

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Murmelchen schrieb:
>> würdest Du dein Programm Schritt für Schritt durchgehen
>
> am Besten mit einem Debugger - @Michael: warum benutzt Du den nicht?

so wie bei emmbedded workbench (MSP430) die locals dann ansehen. Das 
wäre ein Traum!!!!!. Da komme ich seit Wochen nicht drauf, wie man das 
(bei ATMEl Studio 6.2) einstellt, das er mir dann die int Werte im 
(local fenster) anzeigt und die berechneten ergebnisse.

das Inkrmentieren ist ja eigentlich so einfach das es schon wieder 
kompliziert ist.

ich glaube mein Hauptproblem ist ganz einfach, und zwar verwirrt mich 
irgendwie das, wie ich dem Taster an Port D0 (PD0) einer int variable 
zuweise die halt dann eben 0 oder 1 ist.


im embedded workbench ist das ganz easy P1IN der Variable taster 
zuweisen, schon ist die Variable im gedrückten Zustand bei 1.
 

int taster =P1IN; // so funktionierts bei MSP430 embedded workbench
int druckzaehler = 0;
 while(1)
 {
   if(taster == 0)
   {
   druckzaehler++;
   }

 }
  return 0;
 
}


und da ich es mir bei Atmel studio 6.2 im debugger nicht anschauen kann. 
sind wohl meine Gedanken komplett aus den ruder gelaufen und dann kamen 
solche Code beispiele wie oben raus, weil ich nicht mehr wusste was ich 
tun soll.

wie weisst man jetzt eigentlich richtig den PD0 einer int Variable 
namens taster zu, das sie dann eben 0 oder 1 ist.

grüsse huber

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> wie weisst man jetzt eigentlich richtig den PD0 einer int Variable
> namens taster zu, das sie dann eben 0 oder 1 ist.

Du fragst den betreffenden Port ab (lesen), damit hast du
8 Bit. Aus diesen 8 Bit maskierst du das Bit aus das deinen
Tastenzustand beinhaltet und prüfst ob es 1 oder 0 ist.
Wenn es 1 ist weist du deiner Zustandsvariablen 1 zu, wenn
es Null ist weist du deiner Zustandsvariablen 0 zu. Oder
genau umgekehrt, je nachdem ob dein Taster eine aktive 1
oder eine aktive Null generiert.

Merke: das entsprechende Maskierte Bit der Taste ist nicht
gleich dem Wert der Zustandsvariable deiner Taste.

Huber M. schrieb:
> Taster mit kondensator entprellt.

Das funktioniert nur bedingt. Eine vernünftige Entprell-
Schaltung braucht einen Kondensator und zwei Widerstände.
Bei deinem Herumexperimentieren fällst du evtl schon wegen
dem Prellen auf die Schnauze.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> int taster =P1IN; // so funktionierts bei MSP430 embedded workbench

warum funtioniert das dann bei mir nicht mit atmel, ich dachte man macht 
das so:

//
PORTD = (1<<PD0); // oder 0b00000001; // oder 0x0x

wenn ich das so mache:
int taster = (1<<PD0);

da ich mir den debugger bei Atmel Studio noch nicht so einstellen kann, 
das ich mir die locals ansehen kann, kann ich es auch nicht kontrolieren 
ob er 1 oder null macht. Und da ich mir nicht sicher bin ob die 
zuweisung in diesem fall so korrekt ist. macht mir das riesige probleme.

Autor: M.A. S. (mse2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
W.S. schrieb:
> Nun ja, geht, aber das ist blockierend konstruiert.
Wenn der Mikrocontroller nur ganz einfache Dinge tun muss, ist das 
völlig ok.
Kompliziertere Dinge wird der TO zur Zeit noch nicht hinkriegen, wenn er 
mit so einfacher Programmierlogik schon Probleme hat.

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> da ich mir den debugger bei Atmel Studio noch nicht so einstellen kann,
> das ich mir die locals ansehen kann, kann ich es auch nicht kontrolieren
> ob er 1 oder null macht.

Eine Tasten-Variable lokal zu deklarieren macht ja auch wenig
Sinn da die Taste ja für die ganze Software gültig sein soll.
Also deklariere sie global. Im übrigen macht es auch wenig Sinn
diese als Integer zu deklarieren. uint8_t reicht aus und macht
die Operationen damit übersichtlicher, durchsichtiger.

Lokale Variablen sind übrigens dann nicht sichtbar wenn sie
durch eine Optimierungsstufe des Compilers weg-optimert werden.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit,
ich verstehe nicht warum das ganze nicht Funktioniert das kann nur am 
tasterpin einlesen liegen? Nur mal zum verständnis, wenn ich das ganze 
so(nachfolgend) schreibe, macht es ja auch was es soll. oder bin ich da 
komplett verkehrt
 

  int anton = 1;
  int berta = 0;
 
  while(1)
 {
   if(anton > 0)
   {
   berta++;
   }
   if (berta == 5)
   {
   berta = 0;
    }
 }

und hier mein Aktueller Code
[]/*
 * GccApplication27.c
 *
 * Created: 20.09.2016 16:33:10
 *  Author: Huber
 */

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



int main(void)
{
  // EIN u. AUSGÄNGE konfigurieren

  PORTD = (1<<PD0); // Eingang
  DDRC = (1<<PC0);// Ausgang

 // eigen funktion erstellen

 void blinkled()
 {
   PORTC|= (1<<PC0);
   _delay_ms(300);
   PORTC&= ~(1<<PC0);
   _delay_ms(300);
 }
    int taster = PIND0; // Lese an PIND0 ob high or low
    int druckzaehler = 0;
    while(1)
    {
      if(taster > 0 )
      {
        druckzaehler++;
      }
      if (druckzaehler == 5)
      {

        PORTC |= (1<<PC0);
      }

    }

  }

[]

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduinoquäler schrieb:
> Lokale Variablen sind übrigens dann nicht sichtbar wenn sie
> durch eine Optimierungsstufe des Compilers weg-optimert werden.

den habe ich unter optimize auf none -O0 gestellt

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> int main(void)

Das sind soviele Macken drin dass man dir wirklich nur
raten kann die Sprache C von Grund auf zu lernen.

Autor: lalala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielleicht 'taster=PIND0;' in die while(1) -Schleife hineinpacken? 
Ansonsten muss die Taste beim Starten gedrückt sein.
Schreib doch mal auf was genau passieren soll; das Anton-Berta Ding 
sieht auch ganz schön verkehrt aus. (Da kannst Du Anton auch weglassen).

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduinoquäler schrieb:
> Huber M. schrieb:
>> int main(void)
>
> Das sind soviele Macken drin dass man dir wirklich nur
> raten kann die Sprache C von Grund auf zu lernen.

das setzt das atmel studio schon als standard automatisch hin.

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> das setzt das atmel studio schon als standard automatisch hin.

Man versteht ja schon deine Ausdrucksweise nicht. Sorry.
Und dass sich meine Aussage auf den ganze geposteten Code
bezieht hast du wohl auch nicht verstanden.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich wollte eigentlich einfach nur per Tasterdruck (ohne dass, das die 
Standard mässige vorgehensweise ist) eine Variable hochzählen ohne  das 
es einen grossen Sinn macht, denn ich bin jetzt einfach noch mal an den 
Anfang gegangen, wo Rechnen mit

int a + int b und int c = c / a+b usw...und

if ( a <= b)
{
 d= d+1;

}
if( d == 5)
{

d = 0;
}

zur übung steht.

das kann man auch mit nem texas instrument board machen. und dort wenn 
ich zb. int a = P1IN; hinschreibe dann liest er den pin ein. zeigt halt 
im debugger 0 oder 1 an.

ich dachte mir das muss doch mit dem im Atmelstudio mit dem Atmega8a 
auch gehen, da lag ich wohl falsch. da sollte mir halt wenn d == keine 
ahnung halt 5 ,ist die led an pc4 anschalten.

Autor: lalala (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> zb. int a = P1IN;

aber in der while(1) Schleife drin, und nicht draußen.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> zb. int a = P1IN;

aber in der while(1) Schleife drin, und nicht draußen.

Ja, das habe ich schon gemacht, das ändert aber nichts. In
IDE ATMEL STUDIO 6.0 und Atmega8a muesste es ja dann so heissen oder?
>int a = PIND;
>int a = (1<<PD0);

das > zb. int a = P1IN; ist eine andere IDE embedded workbench

Autor: LostInMusic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du den Unterschied zwischen
int main(void)
  {
  int taster = PIND;
 
  while(1)
    {
    ...
    <irgendwas mit taster anstellen>
    ...
    }
  }
und
int main(void)
  {
  int taster;
 
  while(1)
    {
    taster = PIND;
    ...
    <irgendwas mit taster anstellen>
    ...
    }
  }
verstanden hast, bist Du schon ein großes Stück weitergekommen.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> IDE ATMEL STUDIO 6.0 und Atmega8a muesste es ja dann so heissen oder?
>>int a = PIND;
>>int a = (1<<PD0);

Nein.
Eher so:
>uint8_t a =  PIND|(1<<PD0);

: Bearbeitet durch User
Autor: Ralf G. (ralg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
>>uint8_t a =  PIND|(1<<PD0);
was soll das jetzt bewirken?

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Arduinoquäler schrieb:
> Man versteht ja schon deine Ausdrucksweise nicht. Sorry.

Du gehst davon aus, dass er Deinen Satz verstanden hat. Hat er nicht!
Er geht davon aus, dass Du rätselst, ob es sich um C handelt.
Auch einige andere Sätze scheint er nicht verstanden zu haben.

@TO:
Verkauf den Krempel. Du kannst damit nichts anfangen, es überfordert 
Dich!
Und die Aufgaben werden bei weiteren Projekten wesentlich (!) komplexer.


Gruß

Jobst

: Bearbeitet durch User
Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Arduino F. schrieb:
>>>uint8_t a =  PIND | (1<<PD0);
> was soll das jetzt bewirken?

Naja...
Ich dachte mir so...

Huber M. schrieb:
>>int a = PIND;
>>int a = (1<<PD0);
Das wäre ein unbeholfener Versuch einen Taster einzulesen....
Vielleicht habe ich mich ja auch getäuscht.
Dann bin ich jetzt ent- täuscht.

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Jobst M. schrieb:
> Hat er nicht!

Ja.

Jobst M. schrieb:
> Auch einige andere Sätze scheint er nicht verstanden zu haben.

Ja.

Autor: Peter D. (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anbei mal Entprellung mit Timerinterrupt (ungetestet).

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter D. schrieb:
> ungetestet

:-) witzig ...


Da sind wir aber einige Sphären außerhalb "Huber M."-s aktuellem 
Kenntnisstands.

Er (der TO) hat sich wohl ein C-Buch gekauft (welches auch immer) aber 
die Verwendung ist fraglich. Hinweise auf das GCC-Tutorial fallen 
scheinbar nicht auf fruchtbaren Boden.

Ich habe mir div. Threads des TO angeschaut und finde überall die 
gleiche Unsicherheit. Aus meiner Sicht fehlen die Grundlagen, die sich 
jeder halt beibringen muss oder via Volkshochschule oder wie auch immer 
erlangen muss.

Karl-Heinz ist ja wohl nicht mehr aktiv ( was mich wirklich sehr 
"bedrückt" - ich finde keinen anderen Ausdruck) und ich habe weder die 
Geduld noch die Leidensfähigkeit ähnlich aktiv einzugreifen. Auch fehlen 
mir die tiefgreifenden Kenntnisse.

@Hubert: Lese Dein Buch und vollziehe alles nach. Gehe das GCC-Tutorial 
Schritt für Schritt durch und probiere alles aus. Setze Dich mit dem 
Debugger des Atmel-Studios auseinander (das ist nicht allzu schwer - das 
weiß ich aus eigener Erfahrung).

Autor: PfostenStecker (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Dieter F. schrieb:
> ...und ich habe weder die
> Geduld noch die Leidensfähigkeit ähnlich aktiv einzugreifen. Auch fehlen
> mir die tiefgreifenden Kenntnisse.

Aber was willst Du dann in diesem Thread? Nutzlose Nebenschauplätze 
eröffnen, oder was sonst?

PfostenStecker

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PfostenStecker schrieb:
> Aber was willst Du dann in diesem Thread? Nutzlose Nebenschauplätze
> eröffnen, oder was sonst?

Auf die Sinnlosigkeit (welche Dir wohl entgangen ist) hinweisen.

Wobei Dein Beitrag mehr als nutzlos ist. Typisch Gast, eigentlich wollte 
ich solche Beiträge ignorieren. Ich gelobe Besserung!

: Bearbeitet durch User
Autor: Geduldiger (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> ich wollte eigentlich einfach nur per Tasterdruck (ohne dass, das die
> Standard mässige vorgehensweise ist) eine Variable hochzählen ohne  das
> es einen grossen Sinn macht,


Du willst bei einem bestimmten Ereignis, bei einem Tastendruck 
hochzählen. Ein Ereignis passiert zu einem bestimmten Zeitpunkt.

Wenn Du aber mit dem Finger eine Taste drückst, drückst Du aber für eine 
bestimmte Zeitdauer auf die Taste.

Während Du mit dem Finger auf der Taste bist, führt der Mikrocontroller 
locker ein paar Millionen mal Deine Schleife aus. Der ist rasend 
schnell.

Mache Dir den Unterschied zwischen einem Zeitpunkt und einer 
Zeitdauer klar.

Eine kleine Grafik:



      Zeitdauer Taster                Zeitdauer Taster
      nicht gedrückt                      gedrückt
  <-------------------------> <----------------------->

  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1

                              |
                              |

              Zeitpunkt, hier hat sich der Taster
              von "nicht gedrückt" auf "gedrückt"
              geändert!



Verstehst Du, was ich Dir erklären will?

Autor: Arduinoquäler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geduldiger schrieb:
> Verstehst Du, was ich Dir erklären will?

Dieser Mensch gibt keine Rückmeldungen auf Fragen oder
Erklärungen.

Mit anderen Worten:

Vergebene Liebesmüh, du redest an eine Wand.

Autor: Huber M. (michael_h784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit,

Erstmal danke für die Mühe, und die vielen Erklärungen. ich glaube ich 
habe es jetzt..... da es beim taster eigentlich nur vier Zustände gibt

-wenn er gedrückt wird
-wenn er gedrückt ist
-wenn er losgelassen wird
-wenn er nicht gedrückt ist

diese Zustände kann ich dann mit rückgabe jeweils auswerten

grüsse huber

: Bearbeitet durch User
Autor: Murmelchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> ich glaube ich habe es jetzt.....

Das glaube ich wiederum nicht. ;-)

Vielleicht solltest Du Dir erst mal klar machen, wie diese Art von 
Programmierung überhaupt so abläuft.

Diese Programme bestehen in der Regel aus zwei Teilen. Im ersten Teil 
wird der Controller für seine Aufgabe konfiguriert und die für den 
weiteren Teil des Programms nötigen Variablen deklariert und 
initialisiert. Dieser Teil des Programms wird nach dem Start oder einem 
Reset nur einmal durchlaufen, sprich, die Anweisungen werden nur einmal 
ausgeführt. Hier wird z. Bsp. festgelegt, ob und welche Port(pin)s als 
Eingang oder als Ausgang fungieren und hier wird z. Bsp. deine 
Zählervariable initialisiert.

Der zweite Teil des Programms, bei den es ja darum geht, dass der 
Controller auf bestimmte Ereignisse reagiert, wird dann in der Regel in 
Form einer Endlosschleife ausgelegt. Da so ein Controller so eine 
Endlosschleife aber recht fix durchläuft, ein menschlicher Tastendruck 
aber immer eine gewisse Zeit dauert und Taster und Schalter zudem auch 
noch prellen, also bei Betätigung den Kontakt oft noch mehrmals ändern, 
bevor sich der vom Betätiger gewünschte Zustand stabil einstellt, muss 
im einfachsten Fall nach Erkennen des Tastendrucks eine gewisse Zeit 
gewartet werden, bevor die Taste erneut abgefragt und bei Betätigung 
erneut gezählt wird.

Dein Programm könnte also folgenden Aufbau haben:

// nötige Bibliotheken einbinden

int main(void)
{
  // Controller konfigurieren
  
  // Variablen deklarieren und initialisieren

  int zaehler = 0;


  while(1)  // Beginn der Endlosschleife, durch den Wert 1
  {         // immer gültig, wird also endlos ausgeführt

    if (taste_gedrueckt)    // Abfrage, ob Taste gedrückt
    {  // Ausdruck 'taste_gedrueckt' wahr
       // es folgen Anweisungen, die nur dann ausgeführt werden, 
       // wenn Taste bei Abfrage gedrückt war

       zaehler = zaehler + 1;

       // zaehler z. Bspl. zur Visualisierung über einen Port ausgeben
      
       delay(300ms);  // oder länger warten - Funktionsaufruf 
                      // einer Zählschleife

    }  // Ende der Anweisungen, die nur abgearbeitet werden, 
       // wenn bei Abfrage die Taste gedrückt war

  }  // Ende der Endlosschleife - es folgt der nächste while(1) Durchlauf
     // die Taste wird dabei erneut abgefragt 

}  // Programmende - wird durch die Endlosschleife nie erreicht


Die Sache mit dem Entprellen könnte man natürlich noch stark verfeinern, 
z. Bsp. kurze Störungen filtern, die Verzögerungszeit soweit verkürzen, 
dass der Einfluss des Prellen zwar eliminiert wird, dabei aber trotzdem 
keine unnötigen Verzögerungen entstehen. Sicherstellen, dass nach 
drücken der Taste diese auch erst wieder losgelassen werden muss, bevor 
erneutes drücken als gültig betrachtet wird usw. Auch wäre eine 
Auswertung über einen Interrupt möglich. Aber all das dürfte deine 
Fähigkeiten und deinen Kenntnisstand zur Zeit noch überfordern. Deshalb 
versuche erst mal anhand der obigen Beschreibung ein lauffähiges 
Programm zu erstellen.


Mit besten Grüßen

Murmelchen

Autor: W.S. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Huber M. schrieb:
> da es beim taster eigentlich nur vier Zustände gibt
>
> -wenn er gedrückt wird
> -wenn er gedrückt ist
> -wenn er losgelassen wird
> -wenn er nicht gedrückt ist

Du schreibst und denkst noch immer unlogisch und wirr.

Also: Es gibt bei einem Taster nur exakt 2 Zustände:
1. gedrückt
2. ungedrückt.

Das "gedrückt _werden_" ist kein Zustand, sondern ein Übergang, nämlich 
von einem Zustand in einen anderen. Ebenso das "ungedrückt werden" bzw. 
losgelassen werden.

An einem Übergang muß man ein Ereignis generieren, das zu einer Reaktion 
führen soll (beispielsweise zum Hochzählen eines Zählers): entweder beim 
Übergang von ungedrückt zu gedrückt oder bei dem anderen Übergang.

Ich hab dir weiter oben mit der Fabel vom fleißigen Beamten quasi eine 
Bauanleitung für deine Software geschrieben, aber du scheinst sie 
überhaupt nicht gelesen zu haben, weswegen du immer noch 
orientierungslos dahintaumelst.

W.S.

Autor: Geduldiger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huber M. schrieb:
> -wenn er gedrückt wird
> -wenn er gedrückt ist
> -wenn er losgelassen wird
> -wenn er nicht gedrückt ist

Ja, das kommt in etwa hin. Der Taster hat entweder den Zustand 
"gedrückt" oder "nicht gedrückt".

Aber Dein Programm muss unterscheiden, zwischen:

- Taster jetzt nicht gedrückt, vorher war er auch nicht gedrückt
- Taster jetzt gedrückt, aber vorher eben war er noch nicht gedrückt
- Taster jetzt gedrückt, und vorher war er auch gedrückt
- Taster jetzt nicht gedrückt, aber vorher eben war er gedrückt

Genau das sind die Fälle, die dein Programm unterscheiden muss. Und in 
genau einem Fall der vier möglichen Fälle, soll dein Programm zählen 
oder etwas anderes machen. Der Hauptteil des Programms könnte so 
aussehen:

  int taster_vorher = 0;
  int taster_jetzt = 0;

  // Endlosschleife
  while(1)
  {
    // Nachschauen, wie der Taster jetzt steht
    if ( (PINA & (1<<PA0)) )
      taster_jetzt = 1;
    else
      taster_jetzt = 0;

    // Prüfen, ob der Taster sich gegenüber vorher verändert hat
    if ( taster_vorher == 0  &&  taster_jetzt == 1 )
    {
      // Bingo, Taster wurde gerade eben gedrückt, hier also Zählen etc.
      ...
    }

    // Endlosschleife springt gleich an den Anfang zurück: Was jetzt aktuell ist, ist nachher alt  
    taster_vorher = taster_jetzt;
  }



Versuch mal, das Programm zu vervollständigen.

Viel Erfolg! Du bekommst das bestimmt hin!

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.