PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Problem mit Taster ab frage



Ferdinand
04.01.2012, 11:12
Hallo

Ich habe mal wider ein Programm zum Ausprobieren und weis nicht, warum es nicht richtig läuft, ich möchte zwischen den tasten hin und her schalten können und wen ich keine Taste drücke Dan möchte ich zum aus Wahl Menü geleitet werden.



//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

//#include "lcd-routines.c"


int main(void)
{

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");

_delay_ms(100); //Gibt einem die moeglichckeit zu lesen was auf dem LCD stht

DDRD = 0x00;
PORTD = 0xff;
while(1)
{
lcd_clear();
lcd_home();
lcd_string("Taste 0-3 drucke");

_delay_ms(100);

lcd_clear();

while (PIND & (1<<PD0))
{

lcd_home();
lcd_string("Das ist Taste 0");
}

while (PIND & (1<<PD1))
{

lcd_home();
lcd_string("Das ist Taste 1");
}

while (PIND & (1<<PD2))
{

lcd_home();
lcd_string("Das ist Taste 2");
}

while (PIND & (1<<PD3))
{

lcd_home();
lcd_string("Das ist Taste 3");
}

}

}



by Ferdinand

Kampi
04.01.2012, 12:05
Hast du den Taster auch mit einem Pull-Up Widerstand an Vcc angeschlossen?
Wieso aktivierst du an PortD die Pull-Up Widerstände?
Mach das:

PortD = 0xFF;

mal weg. Ist doch bischen sinnlos den Pin auf 1 zu setzten und ihn dann nach 1 abzufragen ;)

radbruch
04.01.2012, 12:27
Hallo

Die Taster können auch gegen GND schalten:


//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

uint8_t temp;

int main(void)
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0x0f; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");
_delay_ms(100); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

temp = PIND & 0b00001111; // Status der Tasten einlesen

while(1)
{
if((PIND & 0b00001111) != temp) // Hat sich was geändert?
{
temp = PIND & 0b00001111; // Ja, deshalb neuen Status merken ...
lcd_clear(); // ... und ausgeben
switch(temp)
{
case 0b1110: lcd_string("Das ist Taste 0"); break;
case 0b1101: lcd_string("Das ist Taste 1"); break;
case 0b1011: lcd_string("Das ist Taste 2"); break;
case 0b0111: lcd_string("Das ist Taste 3"); break;
default: lcd_string("Taste druecken");
}
}
}
return(0);
}(ungetestet)

Gruß

mic

Kampi
04.01.2012, 12:57
Hallo

Die Taster können auch gegen GND schalten:


//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

uint8_t temp;

int main(void)
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0x0f; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");
_delay_ms(100); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

temp = PIND & 0b00001111; // Status der Tasten einlesen

while(1)
{
if((PIND & 0b00001111) != temp) // Hat sich was geändert?
{
temp = PIND & 0b00001111; // Ja, deshalb neuen Status merken ...
lcd_clear(); // ... und ausgeben
switch(temp)
{
case 0b1110: lcd_string("Das ist Taste 0"); break;
case 0b1101: lcd_string("Das ist Taste 1"); break;
case 0b1011: lcd_string("Das ist Taste 2"); break;
case 0b0111: lcd_string("Das ist Taste 3"); break;
default: lcd_string("Taste druecken");
}
}
}
return(0);
}(ungetestet)

Gruß

mic

Ja das kannst du natürlich auch machen :)
Nur er muss sich halt für eine Methode entscheiden :D. Was halt nicht funktioniert ist (egal wie er den Taster beschaltet hat) den Pin auf 1 setzt und dann nach 1 abfragt.

Ferdinand
05.01.2012, 21:47
Also dein Beispiel hat leider nicht getan, ich habe deine Idee mal versucht umzusetzen.



//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

uint8_t tasten;



int main(void)
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0xff; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");
_delay_ms(100); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht
lcd_home();

while(1)
{


switch((tasten))
{
case 1: lcd_string("Das ist Taste 0"); lcd_home(); break;

case 2: lcd_string("Das ist Taste 1"); lcd_home(); break;

case 3: lcd_string("Das ist Taste 2"); lcd_home();break;

case 4: lcd_string("Das ist Taste 3"); lcd_home(); break;

default: lcd_home(); lcd_string("Taste druecken");
}

}
return(0);
}



Nur möchte ich das Programm relative einfach halten damit man es gut lesen und relative kann.
Ich möchte stat 0b00000001 das (1 << PD0) benutzen, weil man Dan sofort erkennt, was gemeind ist.

Nun wie setz ich so was um?

Danke

radbruch
05.01.2012, 22:10
//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

uint8_t temp;

int main(void)
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0x0f; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");
_delay_ms(100); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

temp = PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0)) ; // Status der Tasten einlesen

while(1)
{
if((PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0))) != temp) // Hat sich was geändert?
{
temp = PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0)); // Ja, deshalb neuen Status merken ...
lcd_clear(); // ... und ausgeben
lcd_home();
switch(~temp & 0x0f) // Achtung! temp wird mit ~ invertiert!
{
case (1<<PD0): lcd_string("Das ist Taste 0"); break;
case (1<<PD1): lcd_string("Das ist Taste 1"); break;
case (1<<PD2): lcd_string("Das ist Taste 2"); break;
case (1<<PD3): lcd_string("Das ist Taste 3"); break;
default:lcd_string("Taste druecken");
}
}
}
return(0);
}Ob das besser zu lesen ist? Deine Taster schalten doch nach GND, oder?

Kampi
05.01.2012, 22:20
Wenn die Taster nach GND schalten musst du eine Low Abfrage machen.
Die machst du (mein ich) so:

if(!(1<<PD0))
{
}

Das "!" steht dabei für eine Invertierung d.h. wenn PD0 = 1 NICHT erfüllt ist ist die If-Abfrage erfüllt.
Und wenn du deinen Code besser lesen willst versuch die Kommentare alle an die Seite zu schreiben und auf gleicher Höhe ;)

Ferdinand
06.01.2012, 10:55
ok danke, es geht jetzt.



//
// ATMega644
// lcd-routines.c, lcd-routines.h
//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdlib.h>
#include "lcd-routines.h"

uint8_t temp;

int main(void)
{
DDRD = 0x00; // Pins sind Eingang
PORTD = 0x0f; // mit aktiviertem PullUp, Taster schalten nach GND

// Initialisierung des LCD
// Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken
// verschwunden sein
lcd_init();

lcd_string("LCD Start !!!");
_delay_ms(2000); //Gibt einem die moeglichckeit zu lesen was auf dem LCD steht

lcd_clear();
lcd_home();
lcd_string("Taste druecken");


temp = PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0)) ; // Status der Tasten einlesen

while(1)
{
if((PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0))) != temp) // Hat sich was geändert?
{
temp = PIND & ((1<<PD3) | (1<<PD2) | (1<<PD1) | (1<<PD0)); // Ja, deshalb neuen Status merken ...
lcd_clear(); // ... und ausgeben
lcd_home();
switch(~temp & 0x0f) // Achtung! temp wird mit ~ invertiert!
{
case (1<<PD0): lcd_string("Das ist Taste 0"); break;
case (1<<PD1): lcd_string("Das ist Taste 1"); break;
case (1<<PD2): lcd_string("Das ist Taste 2"); break;
case (1<<PD3): lcd_string("Das ist Taste 3"); break;
default:lcd_string("Taste druecken");
}
}
}
return(0);
}


Nun möchte ich aus einem Taster einen Schalter Programmiren, ich habe keine Ahnung, wie ich das anstelle.
Ja meine Taster schalten nach GND, ich benutze das STK500.

Kampi
06.01.2012, 12:26
Wenn es ein einfacher Ein/Aus Schalter ist kannst du ihn wie einen Taster im Programm behandeln. Ein Taster schaltet ja auch Ein und wenn du ihn los lässt Aus. Ein Schalter schaltet halt Ein und beim zweiten betätigen Aus. Aber das macht für die Software keinen wesentlichen Unterschied. Nur du darfst den Zustand des Schalters nicht mit "while" Abfragen, weil sich der Controller dann die ganze Zeit in der Schleife aufhält solange du den Schalter nicht nochtmal betätigst.

Ferdinand
06.01.2012, 13:26
ok und wie macht Mann das, wen sich der Controller nur in Schleifen bewegt.
Ich müsste den Aktuellen wert zwischen Speichern, da die aktuelle Abfrage ständig überschrieben wird, nur weis ich nicht wie man so was wegen den Ganzen schleifen hin bekommt.

Danke

Kampi
06.01.2012, 13:40
Was möchtest du genau machen?
Beschreib mal das was du tun möchtest.

Ferdinand
06.01.2012, 15:21
Hi Kampi, ich find es wirklich toll das du mir bei meinem Problem hilfst.
Ich möchte irgendwann mal ein aus Wahl Menü schreiben, wo man Funktionen ein und aus schalten kann.

Das heißt also das ich erlernen möchte wie man sich ein Volum fassendes Menü mit untergruben und Auswahl von Funktionen schreibt, weil man so was gelegentlich brauchen könnte.

Danke

Kampi
06.01.2012, 15:53
Naja du machst einen Cursor auf das Display und die Position von ihm ist in einer Variable als Zahlenwert gespeichert z.B. Erste Zeile da steht die Variable auf 0. Durch den Taster für Down wird die Variable um 1 erhöht und der Cursor steht in der zweiten Zeile. Durch Up wird die Variable um 1 verringert und der Cursor steht wieder in der ersten Zeile. Und beim Druck auf Enter oder Ok machst du eine Select Case Abfrage wo das Programm in die eigentlichen Unterprogramme springt je nachdem auf was die Variable für den Cursor steht. Das wäre meine Idee für ein ganz einfaches Menü.