Forum: Mikrocontroller und Digitale Elektronik Funktioniert diese Schleife?


von jan (Gast)


Lesenswert?

Hay habe mal vor einiger Zeit mich heir erkundigt wegen einem 4*4 keypad 
und dessen abfrage, dieses keypad hat 16 tasten 4 eingänge und 4 
ausgänge.
Habe hier mal ein Beispiel mit 2*2 Tasten gemacht wobei die PORT und PIN 
belegung hier irelevant sind.
also:
x1-|----|-
x2-|----|-
  y1    y2

so habe ich jetzt 4 schalter, habe versucht x1 und 2 also PORTC 0x01 & 
0x02
über eine while schleife immer abwechselnd auf HIGH zu setzen.
Sobald y1 oder 2 ein signal bekommt soll die schleife stoppen und einen 
Wert auf den integer Ergebnis addieren.
hier ist mal der code :)
hoffe er klappt so wie ich es mir vorgestellt habe.
MFG und besten Dank für jeden Ratschlag :)

int main()
{
int ergebnis;

while((PINB == 0x01) || (PINB == 0x02))
{
PORTc = 0x01;
_delay_ms(2);
PORTC = 0x02;
_delay_ms(2);
}

if ((PINB == 0x01) && (PORTC == 0x01))
{
ergebnis+= 1;
main();
}

if ((PINB == 0x01) && (PORTC == 0x02))
{
ergebnis+= 10;
main();
}

if ((PINB == 0x02) && (PORTC == 0x01))
{
ergebnis+= 100;
mein();
}

if ((PINB == 0x02) && (PORTC == 0x02))
{
ergebnis+= 1000;
main();
}

return 0;

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

Dabei schmiert dir erst mal glatt dein Controller ab, da du rekursiv 
deine main(); aufrufst, du musst dein programm komplett 
umstrukturieiren, so macht as nicht so viel sinn.

Du musst immer abwechseln deine Spalten addressieren und die 
entsprechenden Zeilen dazu lesen. Sowas in der art hast du denke ich 
versucht, aber so funktioniert das nicht.

von jan (Gast)


Lesenswert?

naja das mit dem main(); kann man weglassen, war ein denkfehler.
kann man das dann so machen?
Ich meine ist die schreibweise richtig?
zuerst wird ja eine while schleife ausgeführt bis ein Pin ein Signal 
empfängt.
dann prüft der in welcher komination der Pin ein signal empfängt hierbei 
wußte ich nicht wie ich es richtig schreibe.
 also:
if ((PINB == 0x01) && (PORTC == 0x01))
oder
if ((PINB = 0x01) && (PORTC = 0x01))
oder
if ((PINB & 0x01) && (PORTC & 0x01))

und dann addiert er dementsprechen einen Wert auf den integer ergebnis

von Thomas E. (thomase)


Lesenswert?

jan schrieb:
> PORTc = 0x01;
> _delay_ms(2);
> PORTC = 0x02;
> _delay_ms(2);
Das ist der falsche Ansatz. Du toggelst zwar abwechselnd Pin0 und Pin1, 
aber die Schleifenbedingung wird nur einmal geprüft, nämlich wenn Pin1 
auf high ist.

Deshalb:
while(1)
{
  PORTC = 0x01;
  If(PINB & (1 << 0) ...
  If(PINB & ( 1<< 1) ...
  PORTC = 0x02;
  If(PINB & (1 << 0) ...
  If(PINB & ( 1<< 1) ...
}

Warum so
>>If(PINB & (1 << 0) ...
und nicht so
>>if (PINB == 0x01) ?

Bei der zweiten Abfrage passiert nichts, wenn beide Tasten gedrückt 
sind.


mfg.

von jan (Gast)


Lesenswert?

ah okay danke :)
so nun stell dir bitte vor das ich 3 schleifen brauche:)
einmal für die 100er stelle die 2. für 10er und 3. für die einser 
stelle.
da ich gerne Zahlen bis 255 eingeben würde.
wie muss ich die while schleife deklarieren das ich nach der ersten 
eingabe zur nächsten while schleife wander.
würde es so gehen
while((eingabe >= 1) || (x >= 1))
wobei wenn ich 0 eingebe der intenger x um 1 addiert wird, und dieser 
für die eigentlihe Rechnung uninteressant ist.
:)
Schonmal besten dank du hast mir sehr geholfen :)

von Karl H. (kbuchegg)


Lesenswert?

jan schrieb:
> ah okay danke :)
> so nun stell dir bitte vor das ich 3 schleifen brauche:)
> einmal für die 100er stelle die 2. für 10er und 3. für die einser
> stelle.
> da ich gerne Zahlen bis 255 eingeben würde.

Der ganze Ansatz ist nicht sehr geeignet.

In einem vernünftigen Ansatz brauchst du gar keine Schleife zur 
Tastenerkennung.

Was du haben willst, ist eine Funktion, die du aufrufst und die dir 
mitteilt, ob jetzt gerade eine Taste gedrückt ist und wenn ja, welche.
Der ganze Ansatz mit Schleifen zur Tastenerkennung ist nicht tragfähig.

Und verwenden willst du das zb so
1
int main()
2
{
3
  ....
4
5
  while( 1 ) {
6
7
    do {
8
      taste = get_keyboard();
9
    } while( taste == -1 )    // -1 ist der Code, den get_keyboard liefert
10
                              // wenn keine Taste gedrückt ist
11
12
    // taste enthält jetzt den Code für den ersten Tastendruck
13
    // warte darauf, dass die Taste losgelassen wird
14
15
    while( get_keyboard() != -1 )
16
      ;
17
  }
18
}

wie muss jetzt die FUnktion get_keyboard aussehen, so dass sie -1 
liefert, wenn keine Taste gedrückt ist und ansonsten einen bestimmten 
Code für jede der vorhandenen Tasten?

Du musst die Erkennung der Tastendrücke und die Zuordnung zu den 
einzelnen Tasten von der Verwendung der Tastendrücke trennen. Alles 
andere führt ins Prorammchaos und zu Spaghetticode.

von jan (Gast)


Lesenswert?

Karl heinz
danke, ich weiß das du ne menge Ahnung hast aber das ist einfach noch 
eine Nr zu groß für mich ich weiß wie ich vorgehen muss aber d fehlt mir 
einfach die Erfahrung in der Anwendung.
Ich weiß das ich eine schleife aufbauen muss die PORTB 0-3 abwechselnd 
auf HIGH setzen muss und durch den tastendruck dann erkennen muss 
welcher Port garde auf HIGH gesetzt wurde, dies im zusammenhang mit den 
PINS 0-3.
Dies versuche ich garde natürlich so gut wie möglich zu lösen.
Und den Ansatz von Thomas kann ich sehr gut nachvollziehen.
Diesen würde ich auch bei deiner lösung einbeziehen

heißt:
void get_keyboard()
{while(1)
{
  PORTC = 0x01;
  If(PINB & (1 << 0)
{
taste = 1;
}
  If(PINB & ( 1<< 1)
{
taste = 2;
}
  PORTC = 0x02;
  If(PINB & (1 << 0)
{
taste = 3;
}
  If(PINB & ( 1<< 1)
{
taste = 4;
}
else
{
taste = -1;
}
}

ist das so halbwegs richtig?

von jan (Gast)


Lesenswert?

sry meinte natürlich
int get_keyboard (int taste)
{
.......

return(taste);
}

von Karl H. (kbuchegg)


Lesenswert?

jan schrieb:
> Karl heinz
> danke, ich weiß das du ne menge Ahnung hast aber das ist einfach noch
> eine Nr zu groß für mich

Nicht böse sein:
Aber dann frage ich mich, warum du dich an solchen Dingen versuchst, 
anstatt erst mal die Grundlagen durchzugehen und zu üben, wie man 
Tastenabfragen macht und wie man einen µC programmiert.

> Ich weiß das ich eine schleife aufbauen muss

Musst du eben nicht.
Du Funktion hat NICHT die Aufgabe auf einen Tastendruck zu warten! Sie 
soll nur feststellen OB eine Taste gedrückt ist und wenn ja WELCHE.
Mehr soll sie nicht tun. Auf einen Tastendruck zu warten, das macht der 
Aufrufer der Funktion. Er macht dies deshalb, weil der aufrufende COde 
weiß, ob es ok ist zu warten oder nicht. Aber das ist etwas was diese 
Funktion nicht entscheiden kann und auch nicht entscheiden soll.

Die Funktion schaltet nur die entsprechenden PORT Bits durch, sieht sich 
an, was an den PIN Bits passiert und entscheidet auf Grund dessen, was 
sie da sieht, OB eine Taste gedrückt ist (Aussage 1) und wenn ja welche 
(Aussage 2).

Und diese Erkentnis meldet sie mit ihrem Rückgabecode an den AUfrufer 
zurück, der dann damit weiterarbeitet.

Und die erste Frage, die man sich stellen muss, lautet:
Wie meldet die Funktion was?
Eng damit zusammen hängt die Fragestellung: Wie ist das, wenn mehr als 1 
Taste auf einmal gedrückt wurde? Ist das ein Fehler, sollen die 
Tastendrücke auseinander gehalten werden können, darf der Benutzer das 
ganz einfach nicht tun oder wie soll sowas gehandhabt werden?
Die einfachste Antwort darauf lautet: Es ist nicht definiert was dann 
passieren soll. Was immer aus der Logik herauskommt ist richtig und der 
Benutzer darf das ganz einfach nicht machen.

Abhängig davon überlegt man sich, wie der Returncode der Funktion 
aussehen soll und dann arbeitet man die Funktion aus, so dass sie desen 
Code auch erzeugt.

von jan (Gast)


Lesenswert?

Quatsch ich bin nicht böse :)
Ich bin dir dankbar für jeden Tipp,
Also nun um es zu evrstehen soll ich etws in der form machen:
Alle PORTS auf HIGH wenn eine Taste gedrückt wird,
sollen alles PORTS duchgehend auf low gesetzt werden und wenn und durch 
den der auch auf low geht weiß der mikrocontroler dann auch welchen 
Schalter ich gedrückt habe.
Dann soll er mir einen wert ausgeben.
habe ich das richtig verstanden?

von Karl H. (kbuchegg)


Lesenswert?

jan schrieb:

> Alle PORTS auf HIGH wenn eine Taste gedrückt wird,

Nein.
Du weißt nicht, ob überhaupt eine Taste gedrückt ist oder nicht.
Genau das willst du doch rausfinden!

  x1 auf Ausgang und auf High
  ist y1 auf High?
    Ja: Taste "links oben" ist gedrückt

  ist y2 auf High?
    Ja: Taste "rechts oben" ist gedrückt

  x1 wieder auf Eingang und Low (damit Pullup ausgeschaltet)
  x2 auf Ausgang und auf High

  ist y1 auf High?
    Ja: Taste "links unten" ist gedrückt

  ist y2 auf High?
    Ja: Taste "rechts unten" ist gedrückt

  x2 wieder auf Eingang und auf Low (damit Pullup ausgeschaltet)

Da kommt keine Schleife vor.

von jan (Gast)


Lesenswert?

Ah dann war ich ja schon nahe dranne also
DDRB = 0x01;  // x1 auf ausgang
PORTC = 0x01; //x1 auf High
  If(PINB & (1 << 0) // ist y1 auf High
{taste = 1;}
  If(PINB & ( 1<< 1) // ist y2 auf High
{taste = 2;}

  DDRB = 0x02; // x1 auf eingang und x2 als ausgang
  PORTC = 0x02; //x2 auf high
  If(PINB & (1 << 0)  // ist y1 auf high
{taste = 3;}
  If(PINB & ( 1<< 1) // ist y2 auf high
{taste = 4;}
else
{taste = -1;} // gebe ansonsten den wert -1 zurück

von Karl H. (kbuchegg)


Lesenswert?

jan schrieb:
> Ah dann war ich ja schon nahe dranne also
> DDRB = 0x01;  // x1 auf ausgang
> PORTC = 0x01; //x1 auf High
>   If(PINB & (1 << 0) // ist y1 auf High
> {taste = 1;}
>   If(PINB & ( 1<< 1) // ist y2 auf High
> {taste = 2;}
>
>   DDRB = 0x02; // x1 auf eingang und x2 als ausgang
>   PORTC = 0x02; //x2 auf high
>   If(PINB & (1 << 0)  // ist y1 auf high
> {taste = 3;}
>   If(PINB & ( 1<< 1) // ist y2 auf high
> {taste = 4;}
> else
> {taste = -1;} // gebe ansonsten den wert -1 zurück

rück das doch endlich mal vernünftig ein
1
  DDRB = 0x01;  // x1 auf ausgang
2
  PORTC = 0x01; //x1 auf High
3
4
  If(PINB & (1 << 0) // ist y1 auf High
5
    taste = 1;
6
7
  If(PINB & ( 1<< 1) // ist y2 auf High
8
    taste = 2;
9
 
10
  DDRB = 0x02; // x1 auf eingang und x2 als ausgang
11
  PORTC = 0x02; //x2 auf high
12
13
  If(PINB & (1 << 0)  // ist y1 auf high
14
    taste = 3;
15
16
  If(PINB & ( 1<< 1) // ist y2 auf high
17
    taste = 4;
18
  else
19
    taste = -1; // gebe ansonsten den wert -1 zurück

Frage: zu welchem if gehört das letzte else und was bedeutet das jetzt 
dafür, dass du taste auf -1 setzt?


Setze taste vor dem ganzen Klimbimm auf -1 und wenn du eine gedrückte 
Taste erkennst (weil das entsprechende y auf high ist), dann 
überschreibst du taste mit dem entsprechenden Code.

von Karl H. (kbuchegg)


Lesenswert?

Apropos HIgh/low

Wie sorgst du eigentlich dafür, dass die Spaltenleitungen bei nicht 
gedrückter Taste auf Low sind? Hast du externe Pulldown Widerstände?

von Jan (Gast)


Lesenswert?

so bin wieder zuhause :)
vergiss das mit dem else das war ein denkfehler von mir :)
da du sagtest das es bei nicht gedrückter taste -1 ausgeben soll.
Und ich das ganze noch verstehen musste.

Das mit den Pulldown widerständen wäre das nächste gewesen was ich 
wissen wollte :)
Habe mir das tutorial ja durchgelesen mit den tastern, dort wird gesagt 
das ich einen 10k widerstand pro taster benötige.
siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter
In einem alten Thread von mir wurde mir aber gesagt ich soll blos
470ohm nehmen und die an allen 8 leitungen klemmen, diese kommen dann 
direkt an den atmega8.
Eine led über taster blinken zu lassen habe ich schon geschaft, ich wiß 
nur nicht wie ich es bei diesem keypad anwenden kann bzw. darf.

Tut mir wirklich leid das ich euch mit so viel unwissenheit bestrafen 
muss aber ich kann besser durch praktix lernen zudem amcht es mehr spaß 
habe nie etwas mit technik am Hut gehabt außer kleinere Private sachen 
und muss es mir eben inkl. der Sprache C++ alles selber beibringen.

Ich danke euch nochmals für die Hilfe :)
MfG Jan

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:


> Tut mir wirklich leid das ich euch mit so viel unwissenheit bestrafen
> muss aber ich kann besser durch praktix lernen

Echt?
Dann bist du der erste von 10000, bei dem es funktioniert, die ersten 
grundlegenden Schritte zu überspringen.

von Jan S. (simpson1991)


Lesenswert?

ach ich überspringe die doch nicht,
stell dir doch mal bitte vor du fängst in einem neuen Themenberreich an 
welches dich stark interessiert,
du liest tutorials fängst mit kleineren prjekten an und versuchst dich 
immer zu steigern.
Das man hier und da dann mal Wissenlücken bekommt ist vorprogrammiert 
schon alleine durch die Tatsache das viele Tutorials in Fachbahnhof 
geschrieben sind und man nicht wirklich alles nachvollziehen kann.
Und ich denke da ist ein Forum wirklich toll für Leute die anderen 
leuten helfen.
Ich komme selber aus dem Berreich der gigitalen Gestalltung, ich kann 
fast jedes Adobe Produkt blind bedienen, und helfe selber gerne in Foren 
mit dem Wissen aus :).
Möchte jetzt gerne aber einen anderen Weg einschlagen und gebe wirklich 
mein bestes Informationen aufzusammeln, zu verstehen und anzuwenden.
Es klappt halt nicht immer also bitte ich um ein bisschen nachsicht.
Wenn es dir/euch zu anstrengend ist mit einem Anfänger und Wissenslücken 
unter die Arme zu greifen dann braucht man ja nicht antworten.
Trotzdem bin ich dankbar für jede Hilfe.

Also wie mache ich das jetzt mit den Widerständen? :)

PS: habe mir jetzt extra das Buch "Elektro T" mit dem lösungsbuch 
bestellt für 48€ und naja war bis vor kurzem noch Schüler billig ist es 
nicht gewesen, hofe das es mich viel weiter bringt :)

von Jan S. (simpson1991)


Lesenswert?

So ahbe das programm geschrieben.
könnt Ihr mir sagen ob das jetzt so klappt?
Compilieren konnte ich es ohne Probleme.
die Daten:
PORT 2-5
PINB 0-3

wenn es okay ist wie mache ich es nun mit den widerständen :)?

#include <avr/io.h>
#include "lcd-routines.h"
#include <stdio.h>
#include <util/delay.h>

int main(void)
{
int i, Zahl, ergebnis = 0;
int keyboard();
char Result[9], text[16], texxt[16];


ergebnis += 100 * keyboard();
ergebnis += 10 * keyboard();
ergebnis += keyboard();
Zahl = ergebnis;
if (Zahl > 255)
{ lcd_init();
lcd_setcursor(0, 1);
lcd_string("Zahl zu gross");
}
else
{
lcd_init();
lcd_setcursor(0, 1);
lcd_string("Hex: ");
lcd_setcursor(8, 1);
sprintf(text,"%X",Zahl);
lcd_string(text);

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
 Result[8] = '\0';
lcd_setcursor( 0, 2);
lcd_string("Bin: ");
lcd_setcursor( 8, 2);
sprintf(texxt,"%s",Result);
lcd_string(texxt);
return 0;
  return 0;
  }
}

int keyboard()
{
int taste, x;

for (x=0; x<1; x)
{
  DDRC = 0x08;  // x1 auf ausgang
  PORTC = 0x08; //x1 auf High

  if(PINB & (1 << 0))
 // ist y1 auf High
    {taste = 1;
  x++;}

  if(PINB & ( 1<< 1))
    {taste = 2;
  x++;}

  if(PINB & ( 1<< 2))
    {taste = 3;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
     x++;}

  DDRC = 0x10;
  PORTC = 0x10;

  if(PINB & (1 << 0))
    {taste = 4;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 5;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 6;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
     x++;}

  DDRC = 0x20;
  PORTC = 0x20;

  if(PINB & (1 << 0))
    {taste = 7;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 8;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 9;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
     x++;}

  DDRC = 0x40;
  PORTC = 0x40;

  if(PINB & (1 << 0))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
  x++;}
}


return (taste);
}



MFG und besten Dank :)

von David P. (chavotronic)


Lesenswert?

Jan Schmitz schrieb:
> könnt Ihr mir sagen ob das jetzt so klappt?

Warum probierst du es nicht einfach selber und lernst aus deinen 
Fehlern? Damit kommt man meistens schneller voran.

von Jan S. (simpson1991)


Lesenswert?

weil ich noch die passenden widerstände kaufen muss :)
Und da es noch nciht für mich geklärt ist wie ich das mit den pullups 
nun mache, dachte ich schreibe ich schon mal den code und veröffentliche 
ihn hier :)

ah sehe schon vergessen den den PIN 0-3 als eingang zu deklarieren.
ist bearbeitet :)

von M. J. (manfred-64)


Lesenswert?

Dir ist nicht wirklich zu helfen, da Du die Arbeit Anderen überlassen 
willst, was weder Dir noch andre weiter bringt. Mach Deine Hausaufgaben 
und melde Dich wen Du echte Probleme hast!!!

von Jan S. (simpson1991)


Lesenswert?

warum will ich meine Arbeit anderen überlassen?
Den code habe ich jetzt mit hilfe selbst erstellt.

Ich brauche halt nur ne erklärung wegen den pullups mehr nicht!
wie gesagt im tutorial sind angegeben 10k siehe geposteten link,
und in nem anderen thread wurde mir gesagt das ich an jeden der 8 
leitungen einen 470ohm widerstand hängen soll.
Ich würde nur gerne wissen was nun und vor allem wieso.
Da es ein einzelfall ist finde ich nicht viel in Google.
Und wenn ich es wüsste würde die keymap längst dran hängen.
Habe nur kb was kaputt zu machen 5€ für einen kontroller sind für einen 
nicht verdiener sehr viel :(
Tut mir leid Herr schlaumeier!
Bisschen freundlichkeit schadet nicht ;)

von David P. (chavotronic)


Lesenswert?

Jan Schmitz schrieb:
> Habe nur kb was kaputt zu machen 5€ für einen kontroller sind für einen
> nicht verdiener sehr viel

Ich hab bis jetzt nur einen Controller kaputtbekommen, und das lag an 
einem defekten Schaltnetzteil. Ich habe die Atmegas teilweise bis zur 
Vergasung gequält und bis jetzt ist nichts passiert. Probieren geht in 
diesem Falle über Studieren.. Ausprobieren, debuggen, Fehler machen, 
Lernen. Ist für die meisten hier wohl der Alltag.

von Jan S. (simpson1991)


Lesenswert?

sind die so hartnäckig?
gut werde dann morgen zum elektroladen wandern und mir die widerstände 
kaufen die ich für beide varianten benötige.
Hatte nur große angst das der durch die falschen bausteine kaputt geht.

von David P. (chavotronic)


Lesenswert?

Also wenn du PullUp vergisst kannst du nichts kaputtmachen. Denke daran 
die Ausgänge nicht direkt kurzzuschliessen, den Controller nicht zu 
verpolen, usw..dann darfst du dich in der Programmierung richtig 
austoben (Solange du nicht mit den Fuse spielst kann da im Prinip nichts 
kaputtgehen)

von Jan S. (simpson1991)


Lesenswert?

ah okay danke, aber was heißt die ausgänge nicht direkt kurzschließen?
dürfte ich dann das machen?

PORTB0--|==|-x-|==|--PINC2
         r1  t1 r2

wobei r1 der widerstand an x1 anliegt und r2 an y2 (siehe ganz oben)

von David P. (chavotronic)


Lesenswert?

Naja das heisst, nicht den Ausgangsport auf High setzen und direkt auf 
GND schalten.
Wenn du Ausgänge mit Eingängen verbindest ist das Gefahrenlos, sollte 
auch ohne externe Pullups gehen (Eingänge sind hochohmig).

von M. J. (manfred-64)


Lesenswert?

Jan Schmitz schrieb:
> ah okay danke, aber was heißt die ausgänge nicht direkt kurzschließen?

was ist daran miss zu verstehen ????
MACH DEINE HAUSAUFGABEN !!!!

man(n) solle schon wissen was man unter einem "kurtzschluss" zu 
verstehen ist, bevor man sich an einen µC setzt!

ein paar euronen in Bücher sollte man(n) auch als "nicht Verdiener" 
investieren !!!
um SEINE Hausaufgaben machen zu können !

mfg
der schlaubeier

von Jan S. (simpson1991)


Lesenswert?

achso ne okay :) gut zu wissen werde mich dann morgen wieder melden :)
werde dann ein bisschen rum experimentieren :)
Vielen dank und bis morgen :)

von MagIO (Gast)


Lesenswert?

Boa ... ich weiß nicht, was so manch ein Troll in einem Forum zu suchen 
hat. Und damit meine ich Beiträge, wie den von Manfred John. Intolerant 
... einfach assozial ist das.

Es gibt nun mal Menschen, die nicht sonderlich gut aus Büchern lernen 
können und besser damit klar kommen ihre eigenen Fragen zu stellen. In 
einem Forum wird man weder dazu gezwungen einen Beitrag zu 
lesen/verfolgen, noch darauf zu antworten. Also ... warum lassen solche 
Trolle nicht einfach solche Threads links liegen und sparen sich die 
Zeit und den Strom auch noch dumme Kommentare dazu abzugeben?

Wer helfen will tut es, wer nicht helfen will lacht mal darüber (weil er 
selbst ja nie klein angefangen hat) und zieht weiter.

@Jan:
Was hier mit Kurzschluss gemeint ist: Durch einen Fehler im Programm 
könnte man die Pins von X und Y beide auf Ausgang schalten. Wenn dann 
noch unterschiedliche Level ausgegeben werden, dann hat man einen 
Kurzschluss und einer oder beide PINs verabschieden sich.

Was die Widerstände betrifft: Für die Funktion würde es reichen, wenn am 
Eingangs-Port die Pulldown-Widerstände angeschlossen sind.
Allerdings macht es aus einem anderen Grund auch Sinn die Ausgäng mit 
Pulldown-Widerständen zu versehen. Die Zeilen werden ja immer nur kurz 
auf Ausgang geschaltet. Das heißt aber auch, dass die gerade nicht 
benutzten wie eine Antenne wirken.

Den Tipp, dass du keine Schleife brauchst finde ich auch nicht 
sonderlich gelungen! Bei sich wiederholenden Tätigkeiten macht eine 
Schleife schon Sinn! Also hier konkret in deiner keyboard-Funktion.

int keyboard()
{
   int taste, x, outVal, offset;

   outVal = 0x08;
   offset = 0;
   taste = -1;

   for (x=0; x<4; x++)
   {
     DDRC = outVal;
     PORTC = outVal;
     outVal = outVal<<1;

     if(PINB & (1 << 0))
       { taste = 1 + offset; }

     if(PINB & ( 1<< 1))
       { taste = 2 + offset; }

     if(PINB & ( 1<< 2))
       { taste = 3 + offset; }

     if(PINB & ( 1<< 3))
       { taste = 0 + offset; }

     offset += 3;

     if( taste>9 )
       { taste = 0 }
   }

   return (taste);
}

Bitte bedenken, diese Implementierung macht (fast) genau das, was Deine 
Funktion vorher gemacht hat. Ich finde es allerdings nicht besonders 
clever für die nicht-Zahlen-Tasten 0 auszugeben. Die Auswertung -also 
welche Tasten will ich auswerten und welche nicht- sollte das aufrufende 
Programm machen. Dann lässt sich nämlich keyboard in allen Programmen 
nutzen, die du in Zukunft schreibst und die ein solches Keyboard nutzen.

Das hier
ergebnis += 100 * keyboard();
ergebnis += 10 * keyboard();
ergebnis += keyboard();

Hier gibt es 2 Probleme!
1. Da die Funktion keyboard keine loop hat, die auf eine Eingabe wartet 
musst Du das hier machen. Ansonsten ist die Chance hoch die -1 zu lesen 
(oder 0 in Deiner alten Version).
2. da ein uC ein wenig schneller reagiert als Du, wird er hier einen 
glatten Durchmarsch machen und 3 mal das selbe erkennen.

int key;

while( (key=keyboard()) == -1 ) ergebnis+=100*key;
do { waitms(2) } while( (key!=keyboard()) != -1 );

while( (key=keyboard()) == -1 ) ergebnis+=1*key;
do { waitms(2) } while( (key!=keyboard()) != -1 );

while( (key=keyboard()) == -1 ) ergebnis+=key;
do { waitms(2) } while( (key!=keyboard()) != -1 );

Macht durchaus Sinn auch das in eine Funktion zu packen .. sowas wie 
keyboardWait() ....

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

MagIO schrieb:
> Bei sich wiederholenden Tätigkeiten macht eine
> Schleife schon Sinn! Also hier konkret in deiner keyboard-Funktion.

trotz scharfem hingucken sehe ich nicht, wo du in deiner Schleife deine 
Schleifen-Laufvariable x verwendet hast.

Wozu war also noch mal in deiner for-schleife die Verschleifung gut 
?????

von Karl H. (kbuchegg)


Lesenswert?

MagIO schrieb:

> Es gibt nun mal Menschen, die nicht sonderlich gut aus Büchern lernen
> können und besser damit klar kommen ihre eigenen Fragen zu stellen.

Dann sollen sie fragen.

"Macht das mal für mich" ist keine Frage.

Und im übrigen ist die Ansicht Unsinn. Sie hat noch nie funktioniert, 
funktioniert heute nicht und wird auch nie funktionieren. Ein gewisser 
angelesener Grundstock an Grundlagen muss nun mal sein. Wer nach den 
ersten Seiten Tutorien nicht kapiert hat, wie das mit den Pullup 
Pulldown Widerständen läuft und wozu man sie braucht, hat kein 
Verständnisproblem, sondern einfach zumindest die Tutorien nicht 
gelesen. Warum soll man jemanden hier im Forum die ganze Sache noch 
einmal lang und breit auseinandersetzen, wenn das alles ausführlichst in 
den Tutorien beschrieben ist? Wenn konkrete Fragem dazu auftauchen: ok, 
kein Problem. Aber "Also wie ist das mit den Pulldown" ist keine 
zugelassene Frage, denn das STEHT in den Tutorien.

Und wer das Tutorium gelesen hat, weiß, dass der AVR Pullup Widerstände 
eingebaut hat und er daher keine externen Pulldown kaufen muss. Er muss 
halt einfach nur mit dem arbeiten, was er hat. Darauf hätt ich nämlich 
schon die ganze Zeit gewartet - Auf die Frage: Wenn ich keine Pulldown 
habe, wie mach ich das mit den eingebauten Pullup.
Aber diese Frage ist nicht gekommen.

von MagIO (Gast)


Lesenswert?

""Macht das mal für mich" ist keine Frage."
Der OP ist doch direkt mit seinem eigenen Code eingestiegen! Da kann ich 
kein "mach das mal für mich" erkennen!

Auch der Hinweis auf ein Tutorial ist eine valide Antwort. Und wie 
gesagt ... man muss ja nicht antworten!

Mit dem Hinweis sich das Grundwissen doch per Bücher etc. anzueignen 
kann man sich die ganze Schule sparen! Ist doch auch alles nur 
Grundwissen! Also .. hier hast Du nen Packen Bücher ... lies mal und 
komm in 10 Jahren wieder.

"Wer nach den
ersten Seiten Tutorien nicht kapiert hat, wie das mit den Pullup
Pulldown Widerständen läuft und wozu man sie braucht, hat kein
Verständnisproblem, sondern einfach zumindest die Tutorien nicht
gelesen."
Das ist genau die Engstirnigkeit, die ich angeprangert habe! Lies Du 
erst mal was über Gehrin und Lernen, vielleicht kommst Du dann auch 
dahinter, dass eben nicht alle Gehirne gleich ticken!

Das so ne Antwort nun von einem Moderator kommt spricht nun nicht gerade 
für dieses Forum.

Ich denke es sollte Ziel eines Moderators sein im Forum eine Stimmung 
aufzubauen, wo man sich gerne gegenseitig hilft und wo solche 
anmach-posts nicht nötig sind.

@Wegstaben Verbuchsler:
x wird nur zum zählen benötigt. Ich hatte erst statt dem offset da 
stehen

 taste = 1 + x*3;

Habe dann aber die Multiplikation durch ein Aufaddieren von offset 
ersetzt. Sicherlich kann man dann auch gleich offset als Schleifenzähler 
benutzen und mit +=3 hochzählen. Sagen wir mal das ist eine Hausübung 
;o)

von Karl H. (kbuchegg)


Lesenswert?

MagIO schrieb:
> ""Macht das mal für mich" ist keine Frage."
> Der OP ist doch direkt mit seinem eigenen Code eingestiegen! Da kann ich
> kein "mach das mal für mich" erkennen!

Sorry.
Hingerotzer Code ohne Sinn und Verstand kann man nicht wirklich als 
Vorarbeit werten.

> Mit dem Hinweis sich das Grundwissen doch per Bücher etc. anzueignen
> kann man sich die ganze Schule sparen!

Auch das zieht nicht.
Es ist nun mal ein Unterschied, ob ich einen Menschen aus Fleisch und 
Blut vor mir habe, der mir die Dinge erklärt oder ob ich mit den Mitteln 
eines Forums auskommen muss. Natürlich funktioniert Ersters besser. Aber 
den Luxus haben wir hier nun mal nicht. Daher haben sich Leute gefunden, 
die Tutorien geschrieben haben. Nur lesen und durcharbeiten müsste man 
sie halt.

Wenn er das Notwendige dort nicht lesen kann, warum kann er dann genau 
dasselbe auf einmal hier lesen?

> Mit dem Hinweis sich das Grundwissen doch per Bücher etc.
> anzueignen kann man sich die ganze Schule sparen!

Du willst es nicht verstehen, oder?
Da ist jemand, der schafft es alleine nicht einen simplen Taster an 
einem Portpin sauber abzufragen. Und den willst du durch eine 
Tastenmatrix durchtragen? Wie soll das gehen?


Aber mach mal.
Ich kümmere mich in der Zwischenzeit gerne um die vielen andere Frager, 
die ihre Hausaufgaben gemacht haben und bei denen man nicht bei Adam und 
Eva anfangen muss, weil sie die Basics aus den Tutorien schon gelernt 
haben.

von Peter D. (peda)


Lesenswert?

Du brauchst keine Widerstände zu kaufen.
Machs wie alle, nimm die internen Pullups und lese ein, welcher Pin auf 
low gezogen wird.
Hier ein Beispiel:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=519870#519870

Die Funktion ist ganz einfach.
Zuerst werden alle Zeilen auf low gesetzt und die low-Spalte gesucht.
Und dann umgekehrt, d.h. alle Spalten auf low und die low-Zeile suchen.
Das NOP ist wichtig, da die Eingänge des AVR einen Zyklus früher 
gelatcht werden.


Peter

von MagIO (Gast)


Lesenswert?

@Karl Heinz Buchegger:
Aus meiner Sicht willst Du es nicht verstehen!

"Da ist jemand, der schafft es alleine nicht einen simplen Taster an
einem Portpin sauber abzufragen. Und den willst du durch eine
Tastenmatrix durchtragen? Wie soll das gehen?"

Ganz richtig ... er hat Probleme. Aber helfen die blöden anmach-posts 
weiter? NEIN! Der Anmacher verschwendet seine Zeit und der Fragesteller 
wird vergrault. Zudem sinkt das Niveu des Forums mit der Zeit ins 
Bodenlose.

Vergrault man die Anfänger nicht gleich, dann können die, die schon 
einen Tick weiter sind den blutigen Anfängern auch weiterhelfen.

"Aber mach mal.
Ich kümmere mich in der Zwischenzeit gerne um die vielen andere Frager,
die ihre Hausaufgaben gemacht haben und bei denen man nicht bei Adam und
Eva anfangen muss, weil sie die Basics aus den Tutorien schon gelernt
haben."

Genau das sag ich doch! Kümmere Dich um die Fälle, die dich 
interessieren. Die, die dir zu einfach sind oder unnütz erscheinen lass 
VON ANFANG AN links liegen! Mit dem Genörgel hier ist wie gesagt 
niemandem geholfen - dir nicht, dem OP nicht und dem Forum generell auch 
nicht!


"Wenn er das Notwendige dort nicht lesen kann, warum kann er dann genau
dasselbe auf einmal hier lesen?"

Weil man hier konkret auf Seine Fragen antworten kann und auf die 
Gedankengänge eingehen kann. Mit etwas Einfühlungsvermögen kann man 
evtl. erkennen wo der Denkfehler liegt und die Antwort entsprechend 
formulieren. Du hast natürlich recht ... wenn einem im Forum nur 1 zu 1 
wiedergekäut wird, was im Tutorial steht dann macht es keinen 
Unterschied. Wenn man aber auf den Fragenden eingeht, dann ist das wie 
Unterricht.

"Es ist nun mal ein Unterschied, ob ich einen Menschen aus Fleisch und
Blut vor mir habe, der mir die Dinge erklärt oder ob ich mit den Mitteln
eines Forums auskommen muss."
Einfühlungsvermögen kann man auch im Forum an den Tag bringen! Und wie 
Du ja weißt gibt es auch hervorragende Beiträge - sogar von Dir:
siehe Beitrag "Re: Index vom Maxwert eines Array ermitteln und umsortieren"

"Hingerotzer Code ohne Sinn und Verstand" ... und wieder so ne asoziale 
Anmache ... wie gut, dass es Leute wie Dich gibt, die alles Wissen schon 
mit der Muttermilch aufgenommen haben.

Was mich jetzt an diesem Thread wirklich am meisten stört ist, dass 
solche Posts von einem Moderator kommen. Überarbeitet? Oder einfach nur 
Fehl am Platz?

Natürlich kann man die Stimmung in einem Forum nicht von jetzt auf 
gleich ändern. Aber dass ein Forum auch mit solchen Fragen/Threads gut 
umgehen kann, das weiß ich ganz sicher, weil ich in einem solchen Forum 
schon seit Jahren angemeldet bin! Nur, was will man schon erwarten wenn 
nichteinmal der Moderator mit gutem Beispiel voran geht.

von Jan S. (simpson1991)


Lesenswert?

Wow vielen herzlichen Dank MagIO,
meiner Ansicht nach geht es hier wirklich sehr engstirnig zu, sobald ich 
hier ein Programm abliefere was nicht zu 95% fertig ist wird einem 
gesagt ich lass die andern für mich arbeiten.
Wobei ich ja nicht mal die Lösung such nur eben Ansätze sonst würde ich 
ja nicht fragen wenn ich nicht auf die Lösung komme :/.

Naja trotzdem vielen dank an alle bisherigen Helfer :)
Ich glaube ich hätte es nicht geschaft ohne die Tipps :)

@MagIO
Daran das der einfach durchrennt habe ich nicht gedacht.
leider habe ich eine Frage zu deinem code

while( (key=keyboard()) == -1 ) ergebnis+=key;
do { waitms(2) } while( (key!=keyboard()) != -1 );

wenn key das gleiche ist wie keyboard und das es dem wert von -1 
entspricht.
addiere zu dem Ergebnis den key wert.
Warum? ich meine der wert wird ja in der keyboard funktion direkt auf -1 
gestellt, wieso soll dann das ergebnis direkt mit dem key wert addiert 
werden?

Reicht es den nicht einfach hinter jeder keyboard funktion die do 
schleife auszuführen dort wird ja gewartet bis ein neuer wert eingegeben 
wird?

PS: knabber mitlerweile 20 min an deiner Lösung kann den obrigen Teil 
aber immer noch nicht nach vollziehen :/
Wenn ich zuhause bin werde ich den code mal für eine konsolenanwendung 
verwenden evtl. erkenne ich es ja dann :)

Und achja kennst du evtl. weitere große Foren für mikrocontroler?
Ich habe hier sehr stark das Gefühl das einsteiger die nicht sofort 
alles wissen hier nicht erwünscht sind.



MfG und ebsten Dank :)

von MagIO (Gast)


Lesenswert?

Oh ... da hab ich Dir auch einen Bug eingebaut ;o)

So sieht es besser aus:
while( (key=keyboard()) == -1 );
ergebnis+=key;
do { waitms(2) } while( keyboard() != -1 );

Sorry, da hat wohl der Kaffee noch nicht gewirkt.
Die Idee war, dass keyboard im dem Fall, dass keine Taste gedrückt ist 
-1 zurückgibt. Wie oben schon von jemandem erwähnt kann das aufrufende 
Programm also selbst entscheiden, ob es warten will, oder nicht.

key=keyboard() fragt also das keyboard ab und speichert den Wert in key.
Im nächsten Schritt wird der Wert aber noch gegen -1 geprüft und die 
while-Schleife wird so lange wiederholt, bis eine Taste gedrückt wurde, 
also key <> -1 ist.
Zu ergebnis+=key; könnte man noch sagen, dass hier bewusst nicht nochmal 
keyboard() aufgerufen wird. Denn in einem von keine Ahnung wieviel 
millionen Fällen kann es vorkommen, dass genau zwischen dem Aufruf 
innerhalb der while-Schleife und dem Aufruf von ergebnis+=... die Taste 
wieder losgelassen wird. Darum die key-variable. Es wird sichergestellt, 
dass mit dem Wert gearbeitet wird, der auch zum Abbruch der Schleife 
geführt hat. Wenn man das nicht so macht, dann hat man Bugs, die zwar 
nur sehr selten auftauchen, dafür aber um so schwerer zu finden sind.

Die folgende Schleife soll dann eben wieder darauf warten, dass die 
Taste auch wieder losgelassen wird bevor sie für die nächste 
dezimal-Stelle wieder neu abgefragt wird. Wie gesagt .. im Vergleich zu 
deinem Finger ist so ein uC schon verdammt schnell!
Die 2ms Wartezeit sollen einigermaßen sicherstellen, daß ein Prellen der 
Taste nicht dazu führt die Schleife zu schnell zu verlassen. Aber ich 
glaube zum Thema Prellen gibt es hier auch ein Tutorial.

Mit anderen Worten, um eine 3 stellig Zahl einzugeben musst du hier
Taste drücken
Taste wieder loslassen (auch wenn die 2. Stelle gleich ist)
Taste drücken
Taste wieder loslassen....

Später kann man das immer noch ändern! Also z.B. wenn die Taste >1 sec 
gedrückt bleibt, dann wird sie auch für die 2. Ziffer benutzt. >2 sec -> 
3.Ziffer. Aber das ist Luxus ;o)

von Jan S. (simpson1991)


Lesenswert?

Peter Dannegger schrieb:

> Die Funktion ist ganz einfach.
> Zuerst werden alle Zeilen auf low gesetzt und die low-Spalte gesucht.
> Und dann umgekehrt, d.h. alle Spalten auf low und die low-Zeile suchen.
> Das NOP ist wichtig, da die Eingänge des AVR einen Zyklus früher
> gelatcht werden.
>
>
> Peter

Danke aber ich habe ja nur die Spalten auf low heißt eingang, die zeilen 
werden ja alle als Ausgang benutzt.
das mit dem NOP verstehe ich nicht.

Ist das okay wen ich einfach alle internen Pullups aktiviere und 
aktiviert lasse? Also gleichzeitig oder gibt das Probleme?
würde dan so aussehen.

DDRB 0xF0 //PINB 0-3 als eingang setzen
PORTB 0x0F // zugehörige pullups aktivieren

MfG :)

von Jan S. (simpson1991)


Lesenswert?

Ah ja vielen dank jetzt habe ich kapiert hat mich wirklich das fehlende 
; verwirrt ^^

das mit den 2 sec und dem entprellen habe ich schon verstanden aber 
trotzdem vielen dank :)

hatte für mich halt keinen Sinn gemacht den wert -1 in key zu speichern 
:)
Dann ahbe ich das ja richtig gelesen nur nciht verstanden :)

werde dann mal anfangen mit dem löten, und die keymap einbauen.
Code fertig schreiben und mich dann wieder melden,
vielen Dank!!!

von Michael S. (rbs_phoenix)


Lesenswert?

Also ich kann Karl Heinz schon gut verstehen, wenn auch manches schon 
beleidigend aufgefasst werden kann.

Denn wenn man einen Taster schonmal erfolgreich betrieben hat, der weiß, 
weshalb man einen Dropdownwiderstand braucht und auch, warum 470 Ohm 
schon recht/unnötig klein ist. 2 Minuten gegoogled:
http://www.rn-wissen.de/index.php/Pullup_Pulldown_Widerstand

Zitat: "Wenn es nur darum geht, einen Prozessor-Pin, an dem sich keine 
lange Leitung befindet, auf einen definierten Pegel zu bringen, können 
es auch über 10 kOhm sein.
Bei Arbeiten im Bereich der Mikrocontroller haben sich Werte von 4,7 
kOhm für Pullup- bzw. 10 kOhm für Pulldown-Widerstände in den meisten 
Fällen bewährt. "

Ich weiß nicht, wie man das falsch verstehen kann oder was ich anderes 
sagen sollte. Wenn man durcheinander ist, weil man mal was anderes 
gehört hat, dann kann man ja auch schreiben, wo man das gelesen/gefragt 
hat (denn ich kann mir vorstellen, dass das nicht ohne Grund so ein 
kleiner Widerstand war). Es sei denn der Antworter hatte keine Ahnung 
oder hat die Frage falsch verstanden.

Wenn jemand schon ein oder mehrere Tutorials gelesen hat und meint, er 
versteht es nicht, dann kann das ja schon sein, nur weiß ich nicht, wie 
jemand das dann noch anders Erklären kann, zumindest bei recht simplen 
Dingen wie Pullup/-downwiderständen. Sicher kann man dann nochmal 
nachfragen, was er nicht versteht oder ihm eine eigene Beschreibung 
nochmal schreiben, die inhaltlich identisch ist, doch dadurch lernt bzw 
versteht er evtl doch die Funktion, doch wie man KONKRETE Fragen stellt 
nicht. Und ich denke das ist genau das, was Karl Heinz meint. Anders 
wäre es ja, wenn er fragt, warum die Ausgänge auf Eingänge umgestellt 
werden (also als Beispiel). Das ist eine konkrete Frage und solche 
werden hier meiner Erfahrung nach auch IMMER normal beantwortet.

Jeder hat mal angefangen, keine Frage. Aber man sollte, egal ob mit 
Büchern, Unterricht, Foren oder Tutorials mit einfachen Sachen anfangen 
und sich hocharbeiten. Ich will mir einen MP3-Player bauen mit 
Festplatte, USB-Host und SD-Kartenleser. Dafür gibt es bestimmt nicht 
mal wirklich Tutorials, hab ich auch nicht nach gesucht. Aber ich 
arbeite drauf hin. Das einfachste wird denke ich die Wiedergabe per 
SD-Karte sein, daher fang ich damit mal an. Um mit SD-Karten zu 
kommunizieren, will ich SPI benutzen. Also ist das erste, was ich mache, 
eine SD-Karte oder EEPROM mit SPI ansteuern. Dann frag ich aber auch 
nicht in einem Forum, wie ich ein MP3-Player bauen kann, sondern, wieso 
ein gewisses Problem beim SPI nicht funktioniert oder wie das und das in 
dem und dem Tutorial gemeint ist. Es ist natürlich komplizierter ein 
MP3-Player zu bauen als eine Tastaturmatrix zum laufen zu kriegen. Aber 
vom Prinzip her ist es ähnlich, man arbeitet auf etwas hin und muss halt 
den auch evtl nervigen Weg dahin gehen. Nämlich eine Taste mit dem 
Pulldown-Widerstand zu betreiben. Dann nimmt man nen zweiten Taster. 
Dort kann man schonmal gucken, wie geprüft wird, welche Taste gedrückt 
ist, was passieren soll, wenn keine gedrückt ist, was passieren soll, 
wenn beide gleichzeitig gedrückt werden oder was passieren soll, wenn 
man eine Taste länger drückt. Dann kann man die beiden Taster über 2 
Ausgänge und einem Eingang betreiben und der Rest ist nur kopieren.


@Jan: Was mir noch aufgefallen ist:

Jan Schmitz schrieb:
> int main(void)
> {
> int i, Zahl, ergebnis = 0;
> int keyboard();

Das "int keyboard();" ist der Prototyp der Funktion und gehört deshalb 
nicht in die main sondern davor.

von Jan S. (simpson1991)


Lesenswert?

So mir werden nur balken angezeigt :/
Hier ist der code bin schon an der suche dran :/

#include <avr/io.h>
#include "lcd-routines.h"
#include <stdio.h>
#include <util/delay.h>
int keyboard();

int main(void)
{
int i, Zahl, ergebnis = 0, key;
char Result[9], text[16], texxt[16], xxx[16];


while( (key=keyboard()) == -1 );
ergebnis+=key;
ergebnis *= 100;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );
lcd_init();
lcd_setcursor(0 ,1);
sprintf(xxx,"%d",ergebnis);
lcd_string(xxx);
while( (key=keyboard()) == -1 );
ergebnis+=key;
ergebnis *= 10;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );
lcd_setcursor(0 ,1);
sprintf(xxx,"%d",ergebnis);
lcd_string(xxx);
while( (key=keyboard()) == -1 );
ergebnis+=key;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );
lcd_setcursor(0 ,1);
sprintf(xxx,"%d",ergebnis);
lcd_string(xxx);
Zahl = ergebnis;
if (Zahl > 255)
{ lcd_init();
lcd_setcursor(0, 1);
lcd_string("Zahl zu gross");
}
else
{
lcd_init();
lcd_setcursor(0, 1);
lcd_string("Hex: ");
lcd_setcursor(8, 1);
sprintf(text,"%X",Zahl);
lcd_string(text);

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
 Result[8] = '\0';
lcd_setcursor( 0, 2);
lcd_string("Bin: ");
lcd_setcursor( 8, 2);
sprintf(texxt,"%s",Result);
lcd_string(texxt);
return 0;
  return 0;
  }
}

int keyboard()
{

int taste = -1, x = 0;
DDRB = 0xF0;
PORTB = 0x0F;


for (x=0; x<1; x)
{

  DDRC = 0x40;  // x1 auf ausgang
  PORTC = 0x40; //x1 auf High

  if(PINB & (1 << 0))
 // ist y1 auf High
    {taste = 1;
  x++;}

  if(PINB & ( 1<< 1))// ist y2 auf High
    {taste = 2;
  x++;}

  if(PINB & ( 1<< 2)) // ist y3 auf High
    {taste = 3;
     x++;}

  if(PINB & ( 1<< 3)) // ist y4 auf High
    {taste = 0;
     x++;}

  DDRC = 0x20;
  PORTC = 0x20;

  if(PINB & (1 << 0))
    {taste = 4;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 5;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 6;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
     x++;}

  DDRC = 0x10;
  PORTC = 0x10;

  if(PINB & (1 << 0))
    {taste = 7;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 8;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 9;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
     x++;}

  DDRC = 0x08;
  PORTC = 0x08;

  if(PINB & (1 << 0))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 1))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 2))
    {taste = 0;
     x++;}

  if(PINB & ( 1<< 3))
    {taste = 0;
  x++;}
}


return (taste);
}

von Jan S. (simpson1991)


Lesenswert?

werde mal ein kleineres programm schreiben um zu überprüfen ob eine der 
16 tasten geht

von Jan S. (simpson1991)


Lesenswert?

so also sobald ich diesen part reinpacke:

while( (key=keyboard()) == -1 );
ergebnis+=key;
ergebnis *= 100;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );

zeigt das display mir nur balken an,
weiß jemand evtl schon wo das problem liegt?
ich suche weiter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jan Schmitz schrieb:
> weiß jemand evtl schon wo das problem liegt?
Kommt der uC jemals über diesen Codeabschitt drüber weg?

von Jan S. (simpson1991)


Lesenswert?

das habe ich auch vermutet, habe aber einen kleineren code gebastelt,
heißt wenn ich irgendeine Ziffer drücke müsste er ja dann weiter machen 
und mir das ergebnis bzw. in dem neuen code mir die zahl anzeigen.
tut er aber nicht,
werde später mal eine led dranhängen und schauen ob die keymap überhapt 
richtig funktioniert.

von Peter D. (peda)


Lesenswert?

Jan Schmitz schrieb:
> so also sobald ich diesen part reinpacke:

Wo reinpackst?

Bricht Dir wirklich ein Zacken aus der Krone, wenn Du den Codeabschnitt 
formatierst (Postingregeln) und den kompletten compilierbaren Code als 
Anhang postest?


Peter

von Jan S. (simpson1991)


Lesenswert?

tut mir leid war vertieft.
Im grunde bleibt es der gleiche code nur das 4 Tasten aktiv sind und es 
übersichtlicher ist.
wenn ich

while( (key=keyboard()) == -1 );
ergebnis+=key;
ergebnis *= 100;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );

rausnehme wird mir eine 0 angezeigt wenn nicht dann sehe ich nur blöcke.
habe jetzt mal ne led drangeklemmt und werde gleich ein Test machen ob 
die keymap funktionstüchtig ist.
MFG

#include <avr/io.h>
#include "lcd-routines.h"
#include <stdio.h>
#include <util/delay.h>
int keyboard();

int main(void)
{
int i, Zahl, ergebnis = -1, key;
char xxx[16];

while( (key=keyboard()) == -1 );
ergebnis+=key;
ergebnis *= 100;
do
{
_delay_ms(2);
}
while( keyboard() != -1 );

lcd_init();
lcd_setcursor(0 ,1);
lcd_string("dezimal");
lcd_setcursor(0, 2);
sprintf(xxx,"%d",ergebnis);
lcd_string(xxx);

}

int keyboard()
{
int taste = -1, x = 0;
DDRB = 0xF0;
PORTB = 0x0F;


for (x=0; x<1; x)
{

  DDRC = 0x40;  // x1 auf ausgang
  PORTC = 0x40; //x1 auf High

  if(PINB & (1 << 0))
 // ist y1 auf High
    {taste = 1;
  x++;}

  if(PINB & ( 1<< 1))// ist y2 auf High
    {taste = 2;
  x++;}

  if(PINB & ( 1<< 2)) // ist y3 auf High
    {taste = 3;
     x++;}

  if(PINB & ( 1<< 3)) // ist y4 auf High
    {taste = 0;
     x++;}
   }

return (taste);
}

von Michael S. (rbs_phoenix)


Lesenswert?

Jan Schmitz schrieb:
> for (x=0; x<1; x)

Das ergibt so keinen Sinn, es muss meiner Meinung nach "for (x=0; x<1; 
x++)" sein. Dann kannst du auch die x++; in den ifs weglassen. Was 
passiert denn, wenn du keine Taste drückst? Das x zählt nich hoch und 
deine For endet nie.

Und:
http://www.mikrocontroller.net/articles/Formatierung_im_Forum
-> [ c] und [/ c]
1
for (x=0; x<1; x)
2
{
3
4
  DDRC = 0x40;  // x1 auf ausgang
5
  PORTC = 0x40; //x1 auf High
6
7
  if(PINB & (1 << 0)){
8
  // ist y1 auf High
9
    taste = 1;
10
  }
11
12
  if(PINB & ( 1<< 1)){
13
  // ist y2 auf High
14
    taste = 2;
15
  }
16
17
  if(PINB & ( 1<< 2)){
18
  // ist y3 auf High
19
    taste = 3;
20
  }
21
22
  if(PINB & ( 1<< 3)){ 
23
  // ist y4 auf High
24
    taste = 0;
25
  }
26
}

von Jan S. (simpson1991)


Lesenswert?

wieso endet die nie?
ich weiß in der for schleife steht nur x statt x++ das ist mir aber 
bewust, da das x nicht um 1 inkrementiert werden soll wen die schleife 
wiederholt wird sondern nur wenn ich eine taste drücke deswegen steht 
hinter jeder tastenabfrage ein x++, wodurch die schleife dann vor dem 
nächsten durchlauf beendet wird.

von MagIO (Gast)


Lesenswert?

Du kannst dann das x komlett weglassen, also
for(x=0;x<1;)

LCDs die Balken anzeigen sind in der Regel nicht richtig initialisiert. 
Ich würde an deiner stelle in kleineren Schritten vorgehen, sonst ist es 
schwierig den Fehler zu finden.

1. LCD austesten ... mal nen Text ausgeben ... mal ne Schleife und den 
Zählerstand ausgeben

2. keyboard() alleine testen, also einfach ausgeben, was dir die 
funktion zurückliefert.

3. Jetzt erst die 3 stellige Eingabe angehen

lcd_init(); macht man üblicherweise ganz am Anfang des codes oder lagert 
es gleich in eine Init-Funktion aus. Und vor allem nur einmal! Weiter 
oben hab ich mal code gesehen, wo init öfters aufgerufen wurde.

Das hier ist auf jeden fall schonmal falsch:
ergebnis+=key;
ergebnis *= 100;
ergebnis+=key;
ergebnis *= 10;
ergebnis+=key;
Du multiplizierst letztendlich die erste Ziffer mit 1010.

Entweder so:
ergebnis+= key*100   // Ziffer gleich an die richtige Stelle bringen
ergebnis+= key*10
ergebnis+= key

oder
ergebnis+=key
ergebnis*=10        // Ziffer von hinten nach vorne durchschieben
ergebnis+=key
ergebnis*=10
ergebnis+=key

Aber wie gesagt ... bring erst mal dal LCD zum laufen und mache dich 
damit vertraut.

von Jan S. (simpson1991)


Lesenswert?

Hey, also textausgabe und die bloße rechnung klappt :)
heißt ohne keymap ich gebe dem Ergebnis einen vordefinierten wert.
Berrechnung und Ausgabe klappen ohne Probleme :)
Und die grade eingebaute led reagiert auch auf den Tastendruck.
hier schonmal der bisherige code :)
Die einzigen Meldungen die ich vom compiler bekomme sind:
helloworld.c:6: warning: function declaration isn't a prototype
helloworld.c:97: warning: function declaration isn't a prototype

MfG
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdio.h>
4
#include <util/delay.h>
5
6
int keyboard();
7
8
int main(void)
9
{
10
int i, Zahl, ergebnis = 0, key;
11
char Result[9], text[16], texxt[16], xxx[16];
12
13
14
lcd_init();
15
16
while( (key=keyboard()) == -1 );
17
18
ergebnis+= key*100;
19
20
do 
21
{ 
22
_delay_ms(2); 
23
} 
24
while( keyboard() != -1 );
25
26
lcd_setcursor(0 ,1);
27
sprintf(xxx,"%d",ergebnis);
28
lcd_string(xxx);
29
30
while( (key=keyboard()) == -1 );
31
32
ergebnis+=key;
33
ergebnis+= key*10;
34
35
do 
36
{ 
37
_delay_ms(2); 
38
} 
39
while( keyboard() != -1 );
40
41
lcd_setcursor(0 ,1);
42
sprintf(xxx,"%d",ergebnis);
43
lcd_string(xxx);
44
45
while( (key=keyboard()) == -1 );
46
47
ergebnis+= key;
48
49
do 
50
{ 
51
_delay_ms(2); 
52
} 
53
while( keyboard() != -1 );
54
55
lcd_setcursor(0 ,1);
56
sprintf(xxx,"%d",ergebnis);
57
lcd_string(xxx);
58
Zahl = ergebnis;
59
60
if (Zahl > 255)
61
{ lcd_init();
62
lcd_setcursor(0, 1);
63
lcd_string("Zahl zu gross");
64
}
65
66
else
67
{
68
lcd_setcursor(0, 1);
69
lcd_string("Hex: ");
70
lcd_setcursor(8, 1);
71
sprintf(text,"%X",Zahl);
72
lcd_string(text);
73
74
  for( i = 0; i < 8; ++i ) 
75
  {
76
    if( Zahl % 2 == 0 )
77
      Result[ 7 - i ] = '0';
78
    else
79
      Result[ 7 - i ] = '1';
80
    Zahl = Zahl / 2;
81
  }
82
83
Result[8] = '\0';
84
lcd_setcursor( 0, 2);
85
lcd_string("Bin: ");
86
lcd_setcursor( 8, 2);
87
sprintf(texxt,"%s",Result);
88
lcd_string(texxt);
89
90
return 0;
91
92
  }
93
}
94
95
96
int keyboard()
97
{
98
99
int taste = -1, x = 0;
100
DDRB = 0xF0;
101
PORTB = 0x0F;
102
103
104
for (x=0; x<1;)
105
{
106
  
107
  DDRC = 0x40;  // x1 auf ausgang
108
  PORTC = 0x40; //x1 auf High
109
110
  if(PINB & (1 << 0))
111
 
112
    {taste = 1;
113
  x++;}
114
115
  if(PINB & ( 1<< 1))// ist y2 auf High
116
    {taste = 2;
117
  x++;}
118
  
119
  if(PINB & ( 1<< 2)) // ist y3 auf High
120
    {taste = 3;
121
     x++;}
122
  
123
  if(PINB & ( 1<< 3)) // ist y4 auf High
124
    {taste = 0;
125
     x++;}
126
 
127
  DDRC = 0x20; 
128
  PORTC = 0x20; 
129
130
  if(PINB & (1 << 0))
131
    {taste = 4;
132
     x++;}
133
134
  if(PINB & ( 1<< 1))
135
    {taste = 5;
136
     x++;}
137
  
138
  if(PINB & ( 1<< 2)) 
139
    {taste = 6;
140
     x++;}
141
  
142
  if(PINB & ( 1<< 3)) 
143
    {taste = 0;
144
     x++;}
145
  
146
  DDRC = 0x10; 
147
  PORTC = 0x10; 
148
149
  if(PINB & (1 << 0)) 
150
    {taste = 7;
151
     x++;}
152
153
  if(PINB & ( 1<< 1)) 
154
    {taste = 8;
155
     x++;}
156
  
157
  if(PINB & ( 1<< 2)) 
158
    {taste = 9;
159
     x++;}
160
  
161
  if(PINB & ( 1<< 3)) 
162
    {taste = 0;
163
     x++;}
164
  
165
  DDRC = 0x08; 
166
  PORTC = 0x08; 
167
168
  if(PINB & (1 << 0)) 
169
    {taste = 0;
170
     x++;}
171
172
  if(PINB & ( 1<< 1))
173
    {taste = 0;
174
     x++;}
175
  
176
  if(PINB & ( 1<< 2)) 
177
    {taste = 0;
178
     x++;}
179
  
180
  if(PINB & ( 1<< 3)) 
181
    {taste = 0;
182
  x++;}
183
}
184
  
185
  
186
return (taste);
187
}

von MagIO (Gast)


Lesenswert?

An welchem Port hängt denn das Display? Vielleicht kommt keyboard() dem 
Display ja ins Gehege. Generell sollte man beim löschen/setzen von Pins 
eher mit bit-operationen arbeiten und nicht mit bytes - also zumindest 
wenn ein Port für verschiedene Dinge benutzt wird:
  DDRC = 0x40;  // x1 auf ausgang
  PORTC = 0x40; //x1 auf High
daraus wird dann
  DDRC |= 0x40
  PORTC |= 0x40

Zum löschen eines bits:
  PORTC &= ~0x40

Zum löschen der 4 least significant bits:
  PORTC &= 0xf0

Konnte man bei AVRs nicht auch direkt auf port-bits zugreifen??? Zu 
lange her.


Was ist hier wohl zuviel:
...
while( (key=keyboard()) == -1 );

ergebnis+=key;
ergebnis+= key*10;

do
...

Ein lcd_init ist immer noch zuviel.

sprintf(texxt,"%s",Result); ist auch Quatsch. Wenn Result doch eh schon 
ein String ist, warum dann in einen anderen String kopieren??

von Jan S. (simpson1991)


Lesenswert?

ah okay code ist angepasst, man übersieht echt schnell was.
ehm nein ich denke nicht PORTPINS C und B sind vollkommen frei das 
display hängt außschließlich an PD

von Michael S. (rbs_phoenix)


Lesenswert?

Bin ich jetzt verwirrt? Wenn man keine Taste drückt, kommt er doch aus 
der For-Schleife und somit aus der keyboard()-Funktion nicht raus? Die 
schleife ist beendet, wenn x=1 ist. Wenn aber keine Taste gedrückt wird, 
wird kein x++ ausgeführt und somit bleibt x auch immer 0.

Jan Schmitz schrieb:
> do
> {
> _delay_ms(2);
> }
> while( keyboard() != -1 );

Hier bleibt er in der while hängen. Er beendet es, wenn keyboard -1 
wiedergibt. Dies passiert nie, da die Funktion nur beendet wird, wenn 
die Forschleife beendet ist und dies passiert, wenn eine Taste gedrückt 
wurde.

von MagIO (Gast)


Lesenswert?

Achso ... nochwas:

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
kann man auch so schreiben

  for( i=7; i>=0; i--)
  {
    if( Zahl & 1 )
       Result[ i ] = '1';
    else
       Result[ i ] = '0';
    Zahl>>=1
  }

Zahl%2 macht ne Division um an den Rest zu kommen, die im Vergleich mit 
& sehr viel langsamer ist.
Zahl/2 ist auch viel langsamer, als ein shift nach rechts.

von Michael S. (rbs_phoenix)


Lesenswert?

Michael Skropski schrieb:
> Bin ich jetzt verwirrt? Wenn man keine Taste drückt, kommt er doch aus
> der For-Schleife und somit aus der keyboard()-Funktion nicht raus? Die
> schleife ist beendet, wenn x=1 ist. Wenn aber keine Taste gedrückt wird,
> wird kein x++ ausgeführt und somit bleibt x auch immer 0.
>
> Jan Schmitz schrieb:
>> do
>> {
>> _delay_ms(2);
>> }
>> while( keyboard() != -1 );
>
> Hier bleibt er in der while hängen. Er beendet es, wenn keyboard -1
> wiedergibt. Dies passiert nie, da die Funktion nur beendet wird, wenn
> die Forschleife beendet ist und dies passiert, wenn eine Taste gedrückt
> wurde.

Ich glaub die keyboard()-Funktion is so nich ganz logisch. Wenn keine 
Taste gedrückt wurde, soll -1 wiedergegeben werden. Doch wenn keine 
gedrückt wurde, wird die Forschleife nicht beendet (da die nur beendet 
wird, wenn x >= 1 ist und das nur passiert wenn x inkrementiert wird, 
was nur passiert wenn man eine Taste drückt.

Also müsste man schreiben:
for(x=0; x<1; x++)

Und da am ende das x++ ausgeführt wird und die Schleife beendet wird, 
kann man sie auch gleich weglassen. Wie am Anfang schon gesagt, die 
Schleife kommt beim Aufruf der keyboard()-Funktion und nicht innerhalb 
der Funktion.

Edit:
Kommentier die ForSchleife einfach mal aus und probiers.
sprich so:
1
int keyboard()
2
{
3
4
int taste = -1, x = 0;
5
DDRB = 0xF0;
6
PORTB = 0x0F;
7
8
9
//for (x=0; x<1;)
10
//{
11
  
12
  DDRC = 0x40;  // x1 auf ausgang
13
  PORTC = 0x40; //x1 auf High
14
15
  if(PINB & (1 << 0))
16
 
17
    {taste = 1;
18
  x++;}
19
20
  if(PINB & ( 1<< 1))// ist y2 auf High
21
    {taste = 2;
22
  x++;}
23
  
24
  if(PINB & ( 1<< 2)) // ist y3 auf High
25
    {taste = 3;
26
     x++;}
27
  
28
  if(PINB & ( 1<< 3)) // ist y4 auf High
29
    {taste = 0;
30
     x++;}
31
 
32
  DDRC = 0x20; 
33
  PORTC = 0x20; 
34
35
  if(PINB & (1 << 0))
36
    {taste = 4;
37
     x++;}
38
39
  if(PINB & ( 1<< 1))
40
    {taste = 5;
41
     x++;}
42
  
43
  if(PINB & ( 1<< 2)) 
44
    {taste = 6;
45
     x++;}
46
  
47
  if(PINB & ( 1<< 3)) 
48
    {taste = 0;
49
     x++;}
50
  
51
  DDRC = 0x10; 
52
  PORTC = 0x10; 
53
54
  if(PINB & (1 << 0)) 
55
    {taste = 7;
56
     x++;}
57
58
  if(PINB & ( 1<< 1)) 
59
    {taste = 8;
60
     x++;}
61
  
62
  if(PINB & ( 1<< 2)) 
63
    {taste = 9;
64
     x++;}
65
  
66
  if(PINB & ( 1<< 3)) 
67
    {taste = 0;
68
     x++;}
69
  
70
  DDRC = 0x08; 
71
  PORTC = 0x08; 
72
73
  if(PINB & (1 << 0)) 
74
    {taste = 0;
75
     x++;}
76
77
  if(PINB & ( 1<< 1))
78
    {taste = 0;
79
     x++;}
80
  
81
  if(PINB & ( 1<< 2)) 
82
    {taste = 0;
83
     x++;}
84
  
85
  if(PINB & ( 1<< 3)) 
86
    {taste = 0;
87
  x++;}
88
//}
89
  
90
  
91
return (taste);
92
}

von MagIO (Gast)


Lesenswert?

Die for-Schleife war ja so in meinem Vorschlag von weiter oben nicht so 
vorgesehen. Eigentlich war der Tipp, dass keyboard() nicht wartet.

for( x=0; x<1; )
wartet so lange, bis eine Taste gedrückt wurde. In den if-Blöcken wird 
ja immer x hochgezählt. Wenn man eine Taste drückt steht dann eben ne 1 
drin und die Schleifen-Bedingung wird falsch -> Schleife beendet

Ein -1 wird es mit dieser for-Schleife nie geben und damit funktioniert 
das Warten auf "Taste loslassen" nicht!

Jep, danke Michael!

Also, Jan, schau Dir nochmal die keyboard-funktion in dem Post von 08:32 
an.

von Jan S. (simpson1991)


Lesenswert?

@ MagIO
danke habe es mal geändert :)

@Michael
er soll ja auch nicht aus der Schleife raus.
er soll die Schleife ja solange wiederholen bis ich eine Taste gedrückt 
habe.
und erst weiter machen wenn ich die losgelassen habe.
Wobei ich sehe garde muss ja eigentlich die zuweisung von -1 der taste 
inerhalb der schleife geschehen.
Sonst kann der wert nciht mehr geändert werden.

von Michael S. (rbs_phoenix)


Lesenswert?

Jan Schmitz schrieb:
> er soll die Schleife ja solange wiederholen bis ich eine Taste gedrückt
> habe.

Dann macht es aber keinen Sinn darauf zu warten, dass die Taste 
losgelassen wurde:

Jan Schmitz schrieb:
> do
> {
> _delay_ms(2);
> }
> while( keyboard() != -1 );

Jan Schmitz schrieb:
> Wobei ich sehe garde muss ja eigentlich die zuweisung von -1 der taste
> inerhalb der schleife geschehen.

Das nützt genauso viel, solange du erst die Funktion beendest, wenn eine 
Taste gedrückt wurde. Genau das ist ja der Grund, warum in die keyboard 
Funktion KEINE Schleife reingehört. Übernehm in dem Programm aus deinem 
Post von 19:28 und änder die Funktion so, wie ich in meinem Post von 
20:01 geschrieben habe und probier es.


Jan Schmitz schrieb:
> while( (key=keyboard()) == -1 );

Hier wartest du solange, bis eine Taste gedrückt wurde. Das ist soweit 
auch richtig, nur tust du das im Moment ja sowieso schon in der 
Funktion. In der Funktion das For rauswerfen und alles sollte 
funktionieren.


Der Grund, warum da ursprünglich eine Schleife drin war, war der, dass 
damit die Umschaltung von Ausgang zu Eingang und dem nächsten Eingang 
zum Ausgang automatisiert wurde. Da du das aber untereinander 
geschrieben hast, was kein Problem ist, wird diese Schleife aber 
überflüssig.

von Jan S. (simpson1991)


Lesenswert?

@MagIO
ich ahbe es mir erneut gründlich angeguckt,
2 Fragen bleiben aber
1. was genau macht der intenger offset?, ich verstehe nicht warum der 
ständig um 3 addiert wird.
Und die Schleife läuft ja 3 mal durch selbst wenn ich nichts drücke,
oder wartet er einen if block ab?
Meines wissens nicht und wenn ich dann inerhalb der drei Durchgänge 
nichts drücke dann ist die schleife beendet und ich hatte keine zeit 
eine Eingabe zu machen oder?
Und zu der -1, ich habe jetzt taste = -1; in der keyboard schleife 
reingesteckt so das der tasten wert bei jeder Schleifenwiederholung auf 
-1 gesetzt wird.
Oder habe ich da was missverstanden?

MfG und vielen Dank

PS: gibts heir eine spoiler funktion im Forum?
dann kann ich immer den aktuellen code anhängen ohne das es zu lang wird 
für jeden?

@michael warte bitte ich sehe erst grade das du geschrieben hast :)

von Jan S. (simpson1991)


Lesenswert?

so habe mal auf Rat die do while, while und for schleife entfernt.
Ich komme weiter xD
so jetzt zeigt er mit zuerst ne 0 an.
und springt sofort weiter und zeigt an:
Hex: 00
Bin: 00000000

es ist so als würde er die keyboard() überspringen.
hier mal der neue code.
PS. habe mal die
1
while( keyboard() != -1);
vor jedem key = keyboard(); eingefügt damit er keyboard so oft 
wiederholt bis er einen richtigen wert hat jetzt habe ich aber wieder 
blöcke.

MfG
1
 
2
#include <avr/io.h>
3
#include "lcd-routines.h"
4
#include <stdio.h>
5
#include <util/delay.h>
6
7
int keyboard();
8
9
int main(void)
10
{
11
int i, Zahl, ergebnis = 0, key;
12
char Result[9], text[16], texxt[16], xxx[16];
13
14
15
lcd_init();
16
key = keyboard();
17
ergebnis+= key*100;
18
_delay_ms(10);
19
lcd_setcursor(0 ,1);
20
sprintf(xxx,"%d",ergebnis);
21
lcd_string(xxx);
22
23
key = keyboard();
24
ergebnis+= key*10;
25
_delay_ms(10);
26
lcd_setcursor(0 ,1);
27
sprintf(xxx,"%d",ergebnis);
28
lcd_string(xxx);
29
30
key = keyboard();
31
ergebnis+= key;
32
_delay_ms(10);
33
lcd_setcursor(0 ,1);
34
sprintf(xxx,"%d",ergebnis);
35
lcd_string(xxx);
36
Zahl = ergebnis;
37
38
if (Zahl > 255)
39
{
40
lcd_setcursor(0, 1);
41
lcd_string("Zahl zu gross");
42
}
43
44
else
45
{
46
lcd_setcursor(0, 1);
47
lcd_string("Hex: ");
48
lcd_setcursor(8, 1);
49
sprintf(text,"%X",Zahl);
50
lcd_string(text);
51
52
  for( i=7; i>=0; i--)
53
  {
54
    if( Zahl & 1 )
55
       Result[ i ] = '1';
56
    else
57
       Result[ i ] = '0';
58
    Zahl>>=1;
59
  }
60
61
Result[8] = '\0';
62
lcd_setcursor( 0, 2);
63
lcd_string("Bin: ");
64
lcd_setcursor( 8, 2);
65
sprintf(texxt,"%s",Result);
66
lcd_string(texxt);
67
68
return 0;
69
70
  }
71
}
72
73
74
int keyboard()
75
{
76
77
int taste = -1, x = 0;
78
DDRB = 0xF0;
79
PORTB = 0x0F;
80
81
82
    
83
  DDRC = 0x40;  // x1 auf ausgang
84
  PORTC = 0x40; //x1 auf High
85
86
  if(PINB & (1 << 0))
87
 
88
    {taste = 1;
89
  x++;}
90
91
  if(PINB & ( 1<< 1))// ist y2 auf High
92
    {taste = 2;
93
  x++;}
94
  
95
  if(PINB & ( 1<< 2)) // ist y3 auf High
96
    {taste = 3;
97
     x++;}
98
  
99
  if(PINB & ( 1<< 3)) // ist y4 auf High
100
    {taste = 0;
101
     x++;}
102
 
103
  DDRC = 0x20; 
104
  PORTC = 0x20; 
105
106
  if(PINB & (1 << 0))
107
    {taste = 4;
108
     x++;}
109
110
  if(PINB & ( 1<< 1))
111
    {taste = 5;
112
     x++;}
113
  
114
  if(PINB & ( 1<< 2)) 
115
    {taste = 6;
116
     x++;}
117
  
118
  if(PINB & ( 1<< 3)) 
119
    {taste = 0;
120
     x++;}
121
  
122
  DDRC = 0x10; 
123
  PORTC = 0x10; 
124
125
  if(PINB & (1 << 0)) 
126
    {taste = 7;
127
     x++;}
128
129
  if(PINB & ( 1<< 1)) 
130
    {taste = 8;
131
     x++;}
132
  
133
  if(PINB & ( 1<< 2)) 
134
    {taste = 9;
135
     x++;}
136
  
137
  if(PINB & ( 1<< 3)) 
138
    {taste = 0;
139
     x++;}
140
  
141
  DDRC = 0x08; 
142
  PORTC = 0x08; 
143
144
  if(PINB & (1 << 0)) 
145
    {taste = 0;
146
     x++;}
147
148
  if(PINB & ( 1<< 1))
149
    {taste = 0;
150
     x++;}
151
  
152
  if(PINB & ( 1<< 2)) 
153
    {taste = 0;
154
     x++;}
155
  
156
  if(PINB & ( 1<< 3)) 
157
    {taste = 0;
158
  x++;}
159
160
  
161
  
162
return (taste);
163
}

von Michael S. (rbs_phoenix)


Lesenswert?

Jan Schmitz schrieb:
> es ist so als würde er die keyboard() überspringen.

Und das tut er quasi auch. Du hast in der main die While und do_while 
Schleife weggemacht, die aber richtig waren. Das einzige, was falsch 
war, war die Forschleife in der Funktion.

Wenn du hier:
1
lcd_init();
2
key = keyboard();
3
ergebnis+= key*100;

das schreibst:
1
lcd_init();
2
while((key = keyboard()) == -1); // solange warten, bis eine Taste gedrückt wurde
3
ergebnis+= key*100;
4
while((key = keyboard()) != -1); // solange warten, bis die Taste losgelassen wurde bzw. bis keine Taste gedrückt wurde

oder etwas übersichtlicher und evtl einfacher zu verstehen:
1
lcd_init();
2
key = -1;
3
while(key == -1){ // solange warten, bis eine Taste gedrückt wurde
4
  key = keyboard();
5
}
6
ergebnis+= key*100;
7
while(key != -1); // solange warten, bis die Taste losgelassen wurde bzw. bis keine Taste gedrückt wurde
8
  key = keyboard();
9
}

sollte es gehen. Und das jetzt dementstprechend bei den Anderen Stellen 
auch.

von MagIO (Gast)


Lesenswert?

Die for-Schleife in meinem Beispiel soll einfach den code kürzer machen 
mit dem die 4 X-Ausgänge nacheinander geschaltet werden. Der Unterschied 
ist doch, dass dann beim Einlesen von Y jeweils andere Werte in Taste

Ausgang X1 => 1. Schleifendurchlauf: 1 2 3 0
Ausgang X2 => 2. Schleifendurchlauf: 4 5 6 0
Ausgang X3 => 3. Schleifendurchlauf: 7 8 9 0
Ausgang X4 => 4. Schleifendurchlauf: 0 0 0 0

Beim 1. Schleifendurchlauf ist der Offset =0, beim 2. =3 und beim 3.=6.
Je nachdem welches if dann passt wird die varable Taste damit 
entsprechend errechnet. Wie schon gesagt, um die Tastatur komplett 
auswertbar zu machen sollte man auch statt 0 für die anderen Tasten 
einen entsprechenden Wert zurückliefern. Hier bietet sich an alle 
Zahlen-Tasten so zu belassen (werte von 0-9 und für die anderen Tasten 
Werte > 9 zu liefern.

Also die Empfehlung für keyboard() wäre, dass folgende Werte 
zurückgeliefert werden:
-1 => keine Taste gedrückt
0-9 => entsprechende Ziffern Taste gedrückt
10-15 => andere Taste gedrückt

Die Schleife wird 4 mal durchlaufen und schaltet bei jedem Durchgang 
eine  Zeile aktiv und prüft die Eingänge. Wenn keine Taste gedrückt wird 
sorgt die Schleife im Hauptprogramm fürs warten.

-1 muss nur vor der Schleife initialisiert sein. Wenn mehrere Tasten 
gedrückt werden, dann "gewinnt" in dieser Implementierung die Letzte. 
Eine genauere Auswertung (mehrere Tasten gleichzeitig) macht den Code 
nur komplizierter. Und was dann? Tasten aufsummieren? Dann doch lieber 
-1 zurückgeben? Ich denke du weißt, dass man nicht 2 Tasten drücken 
sollte und andere User lernen es schnell :o)

von Jan S. (simpson1991)


Lesenswert?

@Michael
so sollte es jetzt deines ermessens aussehen oder habe ich schon wieder 
was falsch gemacht?
Bekomme wieder nur blöcke.

MfG
1
 #include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdio.h>
4
#include <util/delay.h>
5
6
int keyboard();
7
8
int main(void)
9
{
10
int i, Zahl, ergebnis = 0, key;
11
char Result[9], text[16], texxt[16], xxx[16];
12
13
14
lcd_init();
15
16
key = -1;
17
while (key== -1)
18
{
19
key = keyboard();
20
}
21
ergebnis+= key*100;
22
while(key != -1);
23
{
24
key = keyboard();
25
}
26
27
key = -1;
28
while (key== -1)
29
{
30
key = keyboard();
31
}
32
ergebnis+= key*10;
33
while(key != -1);
34
{
35
key = keyboard();
36
}
37
38
key = -1;
39
while (key== -1)
40
{
41
key = keyboard();
42
}
43
ergebnis+= key;
44
while(key != -1);
45
{
46
key = keyboard();
47
}
48
49
lcd_setcursor(0 ,1);
50
sprintf(xxx,"%d",ergebnis);
51
lcd_string(xxx);
52
Zahl = ergebnis;
53
54
if (Zahl > 255)
55
{
56
lcd_setcursor(0, 1);
57
lcd_string("Zahl zu gross");
58
}
59
60
else
61
{
62
lcd_setcursor(0, 1);
63
lcd_string("Hex: ");
64
lcd_setcursor(8, 1);
65
sprintf(text,"%X",Zahl);
66
lcd_string(text);
67
68
  for( i=7; i>=0; i--)
69
  {
70
    if( Zahl & 1 )
71
       Result[ i ] = '1';
72
    else
73
       Result[ i ] = '0';
74
    Zahl>>=1;
75
  }
76
77
Result[8] = '\0';
78
lcd_setcursor( 0, 2);
79
lcd_string("Bin: ");
80
lcd_setcursor( 8, 2);
81
sprintf(texxt,"%s",Result);
82
lcd_string(texxt);
83
84
return 0;
85
86
  }
87
}
88
89
90
int keyboard()
91
{
92
93
int taste = -1;
94
DDRB = 0xF0;
95
PORTB = 0x0F;
96
97
98
    
99
  DDRC = 0x40;  // x1 auf ausgang
100
  PORTC = 0x40; //x1 auf High
101
102
  if(PINB & (1 << 0))
103
 
104
    {taste = 1;
105
  }
106
107
  if(PINB & ( 1<< 1))// ist y2 auf High
108
    {taste = 2;
109
  }
110
  
111
  if(PINB & ( 1<< 2)) // ist y3 auf High
112
    {taste = 3;
113
     }
114
  
115
  if(PINB & ( 1<< 3)) // ist y4 auf High
116
    {taste = 11;
117
     }
118
 
119
  DDRC = 0x20; 
120
  PORTC = 0x20; 
121
122
  if(PINB & (1 << 0))
123
    {taste = 4;
124
     }
125
126
  if(PINB & ( 1<< 1))
127
    {taste = 5;
128
     }
129
  
130
  if(PINB & ( 1<< 2)) 
131
    {taste = 6;
132
     }
133
  
134
  if(PINB & ( 1<< 3)) 
135
    {taste = 12;
136
     }
137
  
138
  DDRC = 0x10; 
139
  PORTC = 0x10; 
140
141
  if(PINB & (1 << 0)) 
142
    {taste = 7;
143
     }
144
145
  if(PINB & ( 1<< 1)) 
146
    {taste = 8;
147
     }
148
  
149
  if(PINB & ( 1<< 2)) 
150
    {taste = 9;
151
     }
152
  
153
  if(PINB & ( 1<< 3)) 
154
    {taste = 13;
155
     }
156
  
157
  DDRC = 0x08; 
158
  PORTC = 0x08; 
159
160
  if(PINB & (1 << 0)) 
161
    {taste = 15;
162
     }
163
164
  if(PINB & ( 1<< 1))
165
    {taste = 0;
166
    }
167
  
168
  if(PINB & ( 1<< 2)) 
169
    {taste = 16;
170
     }
171
  
172
  if(PINB & ( 1<< 3)) 
173
    {taste = 17;
174
  }
175
   
176
  
177
  
178
return (taste);
179
}

von Jan S. (simpson1991)


Lesenswert?

was mir aufgefallen ist ist:
ich bekomme diese blöcke nur sobald ich diese while schleifen einbaue.
ohne hat es ja alles angezeigt nur wurde eben die eingabe übersprungen.
Kann es sein das der atmega8 nicht die while schleife verarbeiten aknn 
und deswegen ein "error" ausgibt?

von MagIO (Gast)


Lesenswert?

Sehen die Balken so aus? 
http://www.moddingpower.de/artikel/minilcd/balken.jpg

Dann könnte ich mir nur vorstellen, dass du noch ein Hardware-Problem 
hast. Sprich einen Kurzschluss von einem der Pins, die von Keyboard 
benutzt werden hin zum Reset des Displays.

Vielleicht hattest Du ja auch deswegen die vielen lcd_init Aufrufe! Aber 
die lösen ja nicht das eigentliche Problem. Im Gegenteil, wenn es einen 
Kurzschluss zwischen 2 Ausgängen gibt ist das auf Dauer nicht gut für 
den uC!

von Jan S. (simpson1991)


Lesenswert?

ja ich werde hier gleich mal alle Daten und den schaltplan posten :)

von Jan S. (simpson1991)


Angehängte Dateien:

Lesenswert?

Sooo also der schaltplan ist obern hier nochmal alles schriftlich:
1
Display - Atmega        Keymap - Atmega
2
 1 VSS                    x1     14 PB0
3
 2 VDD                    x2     15 PB1
4
 3 VO                     x3     16 PB2
5
 4 RS     6 PD4           x4     17 PB3
6
 5 RW                     y1     28 PC5
7
 6 EN    11 PD5           y2     27 PC4
8
 7 D0                     y3     26 PC3
9
 8 D1                     y4     25 PC2
10
 9 D2
11
10 D3
12
11 D4     2 PD0
13
12 D5     3 PD1
14
13 D6     4 PD2
15
14 D7     5 PD3
16
15 LED+
17
16 LED-

Und ja genau so sehen die Blöcke aus aber eben nur wenn ich eine while 
schleife reinbaue.
Ohne hat es wie gesagt alles richtig angezeigt mir eben nur den wert 0 
ausgegeben weil ich ncihts eingeben konnte.
MfG und besten Dank :)

von spess53 (Gast)


Lesenswert?

Hi

Wenn deine Tastatur wirklich so angeschlossen ist, dann geht das

> DDRC = 0x40;  // x1 auf ausgang
>  PORTC = 0x40; //x1 auf High

ins nirgendwo ->PC6. Und die Ansteuerung für PC2 fehlt.

MfG Spess

von Jan S. (simpson1991)


Lesenswert?

ich werde gleich wenn ich 10min zeit habe nochmal alle werte überprüfen

von Jan S. (simpson1991)


Lesenswert?

danke für den Tipp ahbe wohl mal überall einen zu hoch gesetzt :)

heir der neue code:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdio.h>
4
#include <util/delay.h>
5
6
int keyboard();
7
8
int main(void)
9
{
10
int i, Zahl, ergebnis = 0, key;
11
char Result[9], text[16], texxt[16], xxx[16];
12
13
14
lcd_init();
15
16
key = -1;
17
while (key== -1)
18
{
19
key = keyboard();
20
}
21
ergebnis+= key*100;
22
while(key != -1);
23
{
24
key = keyboard();
25
}
26
27
key = -1;
28
while (key== -1)
29
{
30
key = keyboard();
31
}
32
ergebnis+= key*10;
33
while(key != -1);
34
{
35
key = keyboard();
36
}
37
38
key = -1;
39
while (key== -1)
40
{
41
key = keyboard();
42
}
43
ergebnis+= key;
44
while(key != -1);
45
{
46
key = keyboard();
47
}
48
49
lcd_setcursor(0 ,1);
50
sprintf(xxx,"%d",ergebnis);
51
lcd_string(xxx);
52
Zahl = ergebnis;
53
54
if (Zahl > 255)
55
{
56
lcd_setcursor(0, 1);
57
lcd_string("Zahl zu gross");
58
}
59
60
else
61
{
62
lcd_setcursor(0, 1);
63
lcd_string("Hex: ");
64
lcd_setcursor(8, 1);
65
sprintf(text,"%X",Zahl);
66
lcd_string(text);
67
68
  for( i=7; i>=0; i--)
69
  {
70
    if( Zahl & 1 )
71
       Result[ i ] = '1';
72
    else
73
       Result[ i ] = '0';
74
    Zahl>>=1;
75
  }
76
77
Result[8] = '\0';
78
lcd_setcursor( 0, 2);
79
lcd_string("Bin: ");
80
lcd_setcursor( 8, 2);
81
sprintf(texxt,"%s",Result);
82
lcd_string(texxt);
83
84
return 0;
85
86
  }
87
}
88
89
90
int keyboard()
91
{
92
93
int taste = -1;
94
DDRB = 0xF0;
95
PORTB = 0x0F;
96
97
DDRC = 0x20;  
98
PORTC = 0x20;
99
100
  if(PINB & (1 << 0))
101
 
102
    {taste = 1;
103
  }
104
105
  if(PINB & ( 1<< 1))// ist y2 auf High
106
    {taste = 2;
107
  }
108
  
109
  if(PINB & ( 1<< 2)) // ist y3 auf High
110
    {taste = 3;
111
     }
112
  
113
  if(PINB & ( 1<< 3)) // ist y4 auf High
114
    {taste = 11;
115
     }
116
 
117
  DDRC = 0x10; 
118
  PORTC = 0x10; 
119
120
  if(PINB & (1 << 0))
121
    {taste = 4;
122
     }
123
124
  if(PINB & ( 1<< 1))
125
    {taste = 5;
126
     }
127
  
128
  if(PINB & ( 1<< 2)) 
129
    {taste = 6;
130
     }
131
  
132
  if(PINB & ( 1<< 3)) 
133
    {taste = 12;
134
     }
135
  
136
  DDRC = 0x08; 
137
  PORTC = 0x08; 
138
139
  if(PINB & (1 << 0)) 
140
    {taste = 7;
141
     }
142
143
  if(PINB & ( 1<< 1)) 
144
    {taste = 8;
145
     }
146
  
147
  if(PINB & ( 1<< 2)) 
148
    {taste = 9;
149
     }
150
  
151
  if(PINB & ( 1<< 3)) 
152
    {taste = 13;
153
     }
154
  
155
  DDRC = 0x01; 
156
  PORTC = 0x01; 
157
158
  if(PINB & (1 << 0)) 
159
    {taste = 15;
160
     }
161
162
  if(PINB & ( 1<< 1))
163
    {taste = 0;
164
    }
165
  
166
  if(PINB & ( 1<< 2)) 
167
    {taste = 16;
168
     }
169
  
170
  if(PINB & ( 1<< 3)) 
171
    {taste = 17;
172
  }
173
   
174
  
175
  
176
return (taste);
177
}

von Jan S. (simpson1991)


Lesenswert?

Update:
jetzt sehe ich nicht mehr nur oben blöcke sondern auch unten :/
aber normale textausgabe bzw. die rechnung an sich mit vordefinierten 
wert kalppt wunderbar auch mit der anzeige.

PS. ich meine natürlich DDRC / PORTC 0x04 und nicht 1 :)

von MagIO (Gast)


Lesenswert?

DDRC = 0x01;
  PORTC = 0x01;

ist immer noch falsch, sollte meines Erachtens 0x02 sein.


Liegt R/W vom Display auch wirklich auf GND, oder hast Du es nicht 
verbunden?

von Jan S. (simpson1991)


Lesenswert?

MagIO schrieb:
> DDRC = 0x01;
>   PORTC = 0x01;
>
> ist immer noch falsch, sollte meines Erachtens 0x02 sein.
>
>
> Liegt R/W vom Display auch wirklich auf GND, oder hast Du es nicht
> verbunden?

habe darauf schon geantowrtet :)
sind das nicht 0x04?

gesucht: PC02 also das 3. bit

also 0/1 2 4 <- oder?


ja R/W liegt an GND kann es aber gleich nochmal nach löten.
Aber wenn es nicht daran anliegt dann funktioniert es doch agr nciht 
oder?
ich meine eifnache sachen ohne while schleife funktionieren ja richtig.
MfG :) Jan

von Karl H. (kbuchegg)


Lesenswert?

Jan Schmitz schrieb:
> MagIO schrieb:
>> DDRC = 0x01;
>>   PORTC = 0x01;
>>
>> ist immer noch falsch, sollte meines Erachtens 0x02 sein.
>>
>>
>> Liegt R/W vom Display auch wirklich auf GND, oder hast Du es nicht
>> verbunden?
>
> habe darauf schon geantowrtet :)
> sind das nicht 0x04?
>
> gesucht: PC02 also das 3. bit
>
> also 0/1 2 4 <- oder?

Schreibs halt einfach als

   PORTC = ( 1 << PC2 );

so wie man das eben (in erster Näherung) vernünftig schreibt. Dann 
erübrigt sich die ganze Diskussion.

von MagIO (Gast)


Lesenswert?

Aber die while-Schleife (also keyboard) hat nichts mit dem Display zu 
tun! Display liegt auf Port D, Keypad auf B und C. Also ist die 
wahrscheinlichste Erklärung, dass du irgendwo einen Kurzschluss 
reingelötet hast.

Wäre vielleicht auch ne Idee mal die PORT- und DIR-Register richtig zu 
benutzen. Wenn man nämlich nicht den ganzen Port benutzt, dann sollte 
man mit & und | Operationen arbeiten. Habe ich weiter oben glaube ich 
schon mal erwähnt.

DDRB = DDRB & 0xF0;
// PORTB = 0x0F;

DDRC = DDRC & 0x3C | 0x20;
PORTC = 0x20;

DDRC = DDRC & 0x3C | 0x10;
PORTC = 0x10;

...

Das hilft aber nur dann, wenn die nicht benutzten Pins von Port B/C in 
den Kurzschluss involviert sind und hilft auch nur bei der Diagnose - 
entfernen muss man den Fehler in der HW dann trotzdem.

von MagIO (Gast)


Lesenswert?

Sorry ... 0x3C ist natürlich genau falschrum, 0xC3 wäre richtig.

DDRC & 0xC3 löscht nur die bits, die hinter den Pins PC2-PC5 stecken. 
Dann wird genau der eine Pin auf Ausgang geschaltet, der Momentan 
interessant ist ( | 0x20 ).

von Jan S. (simpson1991)


Lesenswert?

also schreibe ich:
Finde die erste schreibweise irgendwie leichter :)
wenn ich hier mal alles richtig gemacht habe :)
1
nt keyboard()
2
{
3
4
int taste = -1;
5
DDRB = ( 0 << PB0) | ( 0 << PB1) | ( 0 << PB2) | ( 0 << PB3); 
6
PORTB = ( 1 << PB0) | ( 1 << PB1) | ( 1 << PB2) | ( 1 << PB3); 
7
8
DDRC = ( 0 << PC5) | ( 0 << PC4) | ( 0 << PC3) | ( 0 << PC2);
9
DDRC |= (1 << PC5);
10
PORTC = (1 << PC5);
11
12
  if(PINB & (1 << PB0))
13
 
14
    {taste = 1;}
15
16
  if(PINB & ( 1<< PB1))
17
    {taste = 2;}
18
  
19
  if(PINB & ( 1<< PB2)) 
20
    {taste = 3;}
21
  
22
  if(PINB & ( 1<< PB3))
23
    {taste = 11;}
24
 PORTC &= ~(0 << PC5);
25
 DDRC &= ~(1 << PC5);
26
DDRC |= (1 << PC4);
27
PORTC = (1 << PC4);
28
29
  if(PINB & (1 << PB0))
30
 
31
    {taste = 4;}
32
33
  if(PINB & ( 1<< PB1))
34
    {taste = 5;}
35
  
36
  if(PINB & ( 1<< PB2)) 
37
    {taste = 6;}
38
  
39
  if(PINB & ( 1<< PB3))
40
    {taste = 12;}
41
  
42
PORTC &= ~(0 << PC4);
43
DDRC &= ~(1 << PC4);
44
DDRC |= (1 << PC3);
45
PORTC = (1 << PC3); 
46
47
    if(PINB & (1 << PB0))
48
 
49
    {taste = 7;}
50
51
  if(PINB & ( 1<< PB1))
52
    {taste = 8;}
53
  
54
  if(PINB & ( 1<< PB2)) 
55
    {taste = 9;}
56
  
57
  if(PINB & ( 1<< PB3))
58
    {taste = 13;}
59
  
60
PORTC &= ~(0 << PC3);
61
DDRC &= ~(1 << PC3);
62
DDRC |= (1 << PC2);
63
PORTC = (1 << PC2); 
64
65
     if(PINB & (1 << PB0))
66
 
67
    {taste = 15;}
68
69
  if(PINB & ( 1<< PB1))
70
    {taste = 0;}
71
  
72
  if(PINB & ( 1<< PB2)) 
73
    {taste = 16;}
74
  
75
  if(PINB & ( 1<< PB3))
76
    {taste = 17;}
77
  
78
return (taste);
79
}

von Jan S. (simpson1991)


Lesenswert?

aber wieso funktioniert es dann "fast" sobald ich das while raushaue?
ich meine die funktion aht er ja trotzdem aufgerufen.
nur halt eben nur 1 mal 0 wurde ausgegeben und wurde auch so angezeigt, 
die blöcke bekomme ich nur wenn ich die while schleife in die main 
funktion packe :/

von MagIO (Gast)


Lesenswert?

Mit dem while erzeugst Du ein Rechteck-Signal auf den 4 Ausgängen, ohne 
while nur mal eben einen Puls pro Ausgang und dann ist Schluss.

Der eine Puls reicht nicht um den Inhalt des Displays zu überschreiben - 
das Rechteck schon.

Setz doch mal DDRC auf 0 und lass die while-Schleife. Dann wird keyboard 
zwar nie zurückkommen, aber das würde bestätigen, dass zwischen Port C 
und D ein Kurzschluss ist. Vermutlich von einem der 4 Ausgänge zu E vom 
Display, da hier der Takt zum schreiben ins Display RAM führen könnte.

von Jan S. (simpson1991)


Lesenswert?

okay DDRC habe ich jetzt überal auf 0x00 gesetzt wobei PORTC bleibt es 
werden die internen pullups aktiviert aber das sollte ja irelevant 
sein:)
Ergebnis:

Blöcke oben und unten.

code:
1
 
2
int keyboard()
3
{
4
5
int taste = -1;
6
7
DDRB = 0xF0;
8
PORTB = 0x0F;
9
DDRC = 0x00;  
10
PORTC = 0x20;
11
12
  if(PINB & (1 << 0))
13
 
14
    {taste = 1;
15
  }
16
17
  if(PINB & ( 1<< 1))// ist y2 auf High
18
    {taste = 2;
19
  }
20
  
21
  if(PINB & ( 1<< 2)) // ist y3 auf High
22
    {taste = 3;
23
     }
24
  
25
  if(PINB & ( 1<< 3)) // ist y4 auf High
26
    {taste = 11;
27
     }
28
  
29
  PORTC = 0x10; 
30
31
  if(PINB & (1 << 0))
32
    {taste = 4;
33
     }
34
35
  if(PINB & ( 1<< 1))
36
    {taste = 5;
37
     }
38
  
39
  if(PINB & ( 1<< 2)) 
40
    {taste = 6;
41
     }
42
  
43
  if(PINB & ( 1<< 3)) 
44
    {taste = 12;
45
     }
46
   
47
  PORTC = 0x08; 
48
49
  if(PINB & (1 << 0)) 
50
    {taste = 7;
51
     }
52
53
  if(PINB & ( 1<< 1)) 
54
    {taste = 8;
55
     }
56
  
57
  if(PINB & ( 1<< 2)) 
58
    {taste = 9;
59
     }
60
  
61
  if(PINB & ( 1<< 3)) 
62
    {taste = 13;
63
     }
64
   
65
  PORTC = 0x01; 
66
67
  if(PINB & (1 << 0)) 
68
    {taste = 15;
69
     }
70
71
  if(PINB & ( 1<< 1))
72
    {taste = 0;
73
    }
74
  
75
  if(PINB & ( 1<< 2)) 
76
    {taste = 16;
77
     }
78
  
79
  if(PINB & ( 1<< 3)) 
80
    {taste = 17;
81
  }
82
   
83
  
84
  
85
return (taste);
86
}

von Jan S. (simpson1991)


Lesenswert?

werde morgen alle bauteile evtl mal auswechseln und auf eine neue 
platine löten.
Gebe dann morgen bescheid :)

von Jan S. (simpson1991)


Angehängte Dateien:

Lesenswert?

So da bin ich wieder.
Habe alles auf eine neue Platine gelötet.
Und dieses mal 10 mal ordentlicher.
Ergebniss bleibt das Gleiche:
Hier mal ein Bild wie es ausieht wenn die while schleife nicht drinn ist 
aber die Zahl vordefiniert ist.
Hier Dezimal 189

erst immer wenn ich das while reinpacke kommen oben und unten Blöcke.
Wenn irgendwer noch einen Einfall hat, bitte hilft mir Ihr bekommt alle 
nötigen Infos.
MfG Jan

von Michael S. (rbs_phoenix)


Lesenswert?

Hmm. Wenn du einen debugger hast, würd ich damit mal gucken. Ansonsten 4 
LEDs mal dranhängen und hinter

ergebnis+= key*100;
ergebnis+= key*10;
ergebnis+= key;
und
Zahl = ergebnis;

jeweils eine LED anmachen. Dann kannst du gucken, ob dein Programm 
überhaupt zur Ausgabe kommt.

Was mir auch noch aufgefallen ist, ist das du unten ein if-else hast, wo 
du prüfst, ob die zahl zu groß ist. Im Else ist unten ein Return und 
beim If nicht. Beides ist bei µC meist nicht sinnvoll. Mir fällt 
jedenfalls keine Anwendung ein, wo der µC das Programm abarbeitet und 
der Program Counter dann in einen evtl nicht programmierten/definierten 
Programmspeicherbereich geht.

Also nach "lcd_init();" ein "while(1){", nach dem else dann die "}" und 
das return aus dem else raus.

Wenn du das geändert hast zeig nochmal deinen Code, aber bitte häng den 
als Datei an, sonst wird dieser Thread hier elendlang ;)

von Jan S. (simpson1991)


Lesenswert?

wo jetzt?
das return 0 ist am ende der main(), habe es aber weggemacht, war in der 
Zeit zu viel mit konsolenanwendungen beschäftigt :)
und wo genau meinst du soll ich die while schleife einfügen?
MfG und danke :)

PS: so ahbe es geändetr aber weiterhin sehe ich nur Blöcke.
Habe den neuen code mal hochgeladen :)
kann es evtl. auch am uc liegen?

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.