Hallo, ich hab einen Atmel8-16 und steuere damit schon ein LCD Display,
das klappt wunderbar. Nun habe ich an den PORTB PB0 einen Schalter
direkt auf Masse gelegt, sofern ich den drücke würd ich gern eine
vorgegebe Zeile im LCD Display sehen.
Dazu habe ich im header den Button so deklariert:
#define BUTTON_PORT PORTB /* PORTx - register for button output */
#define BUTTON_PIN PINB /* PINx - register for button input */
#define BUTTON_BIT PB0 /* bit for button input/output */
Im mainfile habe ich dann den Port so schalten wollen, dass der interne
Pullup Widerstand aktiv ist und sofern man den Button drückt, soll durch
die While Schleife der neue Befehl zum Senden an das Display geschickt
werden.. leider klappt hier aber irgendwas noch nicht. Würde mich über
Feedback sehr freuen!
#include <avr/io.h>
#include <stdio.h>
#include <string.h>
#include "lcd-routines.h"
#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
int main(void)
{
lcd_init();
set_cursor( 0, 1 );
lcd_start();
//init_io();
//DDRB = 0b00000111; //set B0, B1 and B2 as output
//DDRB = ( 1 << PB2 );
// DDRB = ( 1 << PB1 );
//PINB &= ~(1<<PB0); //set PB0 to input
//PORTB |= (1<<PB0); //enable pullup on input
PORTB=0xFE;
PINB=0xFF;
while(1==1)
{
if(!(PB0 & 0x01))
{
while(!(PB0 & 0x01));
_delay_ms(500);
lcd_init();
//lcd_clear();
set_cursor(0,2);
lcd_string("YEAH");
}
}
return 0;
}
ich habs jetzt so verbessert, aber auch noch keine Reaktion auf einen
tastendruck..
int main(void)
{
lcd_init();
PORTB=0xFE;
PINB=0xFF;
while(1==1)
{
if(!(PINB & 0x01))
{ _delay_ms(50);
while(!(PINB & 0x01));
_delay_ms(50);
lcd_init();
//lcd_clear();
set_cursor(0,2);
lcd_string("YEAH");
}
}
return 0;
}
patrick bateman schrieb:> if(!(PB0 & 0x01))
Irgendwo in den Headern (avr/iom8.h) findest Du:
#define PB0 0
PB0 ist also ein Alias für Bit nummer 0
if (!(0 & 0x01))
Die Bedingung ist niemals erfüllt.
Du meinst
if (!(PINB & (1 << PB0)))
das lcd_init() hat da drinn nichts verloren.
'Initialisieren' bedeutet 'etwas in den Grundzustand bringen'.
Initalisiert wird daher am Programmanfang. Und zwar einmalig.
(Es gibt Ausnahmen, aber da muss man schon wissen, was man tut)
Der Grundaufbau ist immer
patrick bateman schrieb:> danke für eure Kommentare. hab alles ausprobiert, leider noch Lösung,
Was heist denn "leider noch Lösung"?
Dass es immer noch flackert, wenn Du die Taste ein zweites Mal drückst?
Und was bezweckt dieses:
1
PINB=0xFF;
(Die Sache mit der Entprellung lassen wir jetzt mal außen vor)
patrick bateman schrieb:> PINB=0xFF; damit wollte ich den PINB als input definieren, dann sollte> es aber richtig so sein PINB=0xFF; oder?
Du verwechselst gerade PINB mit DDRB. Letzteres bestimmt die Richtung.
Bit gesetzt: Output
Bit gelöscht: Input
Du hast aber Glück. Nach dem Reset ist DDRB = 0, somit sind alle Pins am
Port auf Input. Sag mal... wo hängt überhaupt Dein LCD dran? Und wofür
setzt Du vor dem while() den Cursor? Was macht lcd_start()? Ich kenne
Deine LCD-Routinen nicht. Wo hast Du die her?
Funktioniert denn ein zusätzliches(!)
lcd_string("YUPP");
vor der while-Schleife?
patrick bateman schrieb:> ja das LCD funktioniert auch vor der while-Schleife.
Ach? Kaum zu glauben, Du sagst also, dass bei Einfügen der YUPP-Zeile
unmittelbar vor dem while() tatsächlich YUPP auf dem Display erscheint?
1
....
2
PINB=0xFF;
3
PORTB=(1<<PB0);
4
5
lcd_string("YUPP");
6
7
while(1==1)
8
{
9
....
Meines Erachtens macht bei Dir
PORTB = (1<<PB0);
ziemlich viel kaputt, Da Du nämlich R/W, EN und RS auch am PORT B hängen
hast! Was soll die Zeile überhaupt tun?
Schmeiß die Zeilen
PINB=0xFF;
PORTB = (1<<PB0);
raus, die sind absoluter Unsinn.
Und ändere
while(!(PINB & 0x01));
in
while(!(PINB & (1<<PB0)));
damit Du dann auch konsequent 1<<PB0 statt 0x01 verwendest.
Tja, so ist das halt, wenn man fremden Code zusammenkopiert und dann was
drumherum strickt, ohne wirklich Ahnung von PORTB, PINB und DDRB zu
haben...
Du solltest erstmal das C-Tutorial hier durcharbeiten und mit einer LED
anfangen...
Frank M. schrieb:> Schmeiß die Zeilen>> PINB=0xFF;> PORTB = (1<<PB0);>> raus, die sind absoluter Unsinn.
Die erste ja, die dreht einmal alle Ausgänge um. Die zweite soll den im
Pull-Up aktivierten und dass ist ja nicht ganz unsinnig. |= statt = wäre
aber hilfreich.
Dein Taster ist sicher am Pin 0 vom Port B angeschlossen?
1
intmain(void)
2
{
3
DDRB&=~(1<<PB0);// auf Eingang setzen (eigentlich unnötig, da er es schon ist)
4
PORTB|=(1<<PB0);// Pullup ein
5
6
lcd_init();
7
set_cursor(0,1);
8
lcd_start();
9
10
while(1==1)
11
{
12
if(!(PINB&(1<<PB0)))// Taste gedrückt
13
{
14
set_cursor(0,1);// Ja: ->
15
lcd_string("YEAH");
16
}
17
else
18
{
19
set_cursor(0,1);// Nein: ->
20
lcd_string("Toll");
21
}
22
}
23
24
return0;
25
}
vielleicht ist ja auch das dein Problem, dass du irgendwie erwartest,
dass sich der Text auch mal ändert. Tut er bei dir natürlich nicht, weil
du ja nicht programmiert hast, was passieren soll, wenn der Taster nicht
gedrückt ist.
Was macht eigentlich der ganze Mist bei den LCD-Routinen
1
voidinit_io()
2
{
3
/* set LED pin as digital output */
4
LED_DDR=_BV(LED_BIT);
5
6
/* led is OFF initially (set pin high) */
7
LED_PORT|=_BV(LED_BIT);
8
/* turn on internal pull-up resistor for the switch */
9
BUTTON_PIN&=~_BV(BUTTON_PIN);
10
BUTTON_PORT|=_BV(BUTTON_BIT);
11
}
Hat das irgendwas mit einem LCD zu tun? Nein.
Besteht hier Potential, dass du wieder mal durch Zuweisung an einen
kompletten Port alles durcheinander bringst. Ja.
Verteil deine Funktionen nicht 'zufällig' irgendwie in den diversen
Code-Files. Ein C-File namens lcd.c hat einen Themenkreis. Dieser
Themenkreis lautet: LCD. Er lautet nicht: Buttons oder Leds.
Wenn du so weiter machst, wirst du nie den Überblock behalten, welcher
Pin wo und wofür benutzt wird und noch viel wichtiger: wo er oder seine
Einstellung verändert wird.
Warum nicht? Weil kein Mensch damit rechnet, dass du mitten im LCD-Code
Code versteckst, der sich auch an anderen Pins zuschaffen macht, anstatt
nur und ausschliesslich an den LCD Pins.
Sag schon: wo verstecken sich weitere DDR/Pin/Port Umschaltungen.
patrick bateman schrieb:> Die If Schleif wird so immer noch nicht ausgeführt.
Das wundert mich nicht.
So etwas wie eine If-'Schleife' existiert nicht.
Das Wesen einer Schleife besteht nun mal darin, dass etwas wiederholt
wird. Drum heißt es Schleife. Weil es immer wieder im Kreis rum geht und
wieder und wieder von vorne anfängt.
Ein if macht das aber nicht. Ein if trifft eine Auswahl aus 2
Möglichkeiten. Das ist aber etwas ganz anderes als eine Schleife.
Karl Heinz Buchegger schrieb:> Hat das irgendwas mit einem LCD zu tun? Nein.> Besteht hier Potential, dass du wieder mal durch Zuweisung an einen> kompletten Port alles durcheinander bringst. Ja.
hab ich raus genommen, hat sich nichts durch verändert.
Karl Heinz Buchegger schrieb:> Ein if macht das aber nicht. Ein if trifft eine Auswahl aus 2> Möglichkeiten. Das ist aber etwas ganz anderes als eine Schleife.
du hast Recht, sorry.
Karl Heinz Buchegger schrieb:> Wenn du so weiter machst, wirst du nie den Überblock behalten, welcher> Pin wo und wofür benutzt wird und noch viel wichtiger: wo er oder seine> Einstellung verändert wird
stimmt, hab an dieser Stelle schon viel gelernt und werd ich beim
zweiten Layout berücksichtigen..
J.-u. G. schrieb:> patrick bateman schrieb:>> 0V in beiden Fällen..>> Was meinst Du mit "beiden Fällen"? Wenn der Taster nicht gedrückt ist,> sollte Vcc an PB0 anliegen.
genau, da liegt wohl dann der Fehler..
Also ist der Pull-Up doch nicht an oder es gibt da nen Kurzschluss.
Was passiert, wenn du probehalber einen externen Pull-Up dazuschaltest?
Hast du evtl. zwei Kontakte vom Taster verbunden, die fest verbunden
sind? Wie sieht es aus, wenn der gar nicht angeschlossen ist?