Hallo Freunde=),
ich sitze gerade an einem Projekt, mit dem ich über den ATMega8 einen
LCD (HD44780)ansteuern möchte. Die Ausgabe klappt soweit, leider schaffe
ich es nicht ein anliegendes Signal (Taster) am PORTC durch den ATMega
zum LCD zu schicken.
PortB wird hierbei als Eingang definiert, Pin 1 besitzt die Wertigkeit
1, Pin 2 Wertigkeit 2 usw. usf. Somit ergibt sich bei aktivierten Pin1
und Pin2 eine 3. (Binär zu Dezimal). Problem hierbei ist, das wir eine
Variable haben, welche direkt um die Wertigkeit erhöht werden soll.
Sprich;
i = 0;
Wenn An Pin1 nun ein high Signal anliegt, so wird i um 1 inkrementiert,
bei Pin2 um 2, Pin3 um 4, Pin4 um 8.
Der Code sieht folgendermaßen aus:
1
inti;
2
3
DDRC=0x00// Port C als Eingang definieren
4
5
If(PC1==1)
6
{
7
i=i+1
8
}
9
10
If(PC2==1)
11
{
12
i=i+2
13
}
14
If(PC3==1)
15
{
16
i=i+4
17
}
18
...
Auch die Ausgabe von der Variablen I stellt kein Problem dar, bei dem
eben genannte code jedoch wird die Zahl unabhängig von dem
Eingangssignal leider nicht erhöht.
Wäre für jede Anregung dankbar.
bussi Laura
Laura schrieb:
> Der Code sieht folgendermaßen aus:
Bitte poste ihn vollständig.
>>
1
>
2
>inti;
3
>
4
>DDRC=0x00// Port C als Eingang definieren
5
>
6
>If(PC1==1)
7
>{
8
>i=i+1
9
>}
10
>
11
>If(PC2==1)
12
>{
13
>i=i+2
14
>}
15
>If(PC3==1)
16
>{
17
>i=i+4
18
>}
19
>...
20
>
>>> Auch die Ausgabe von der Variablen I stellt kein Problem dar, bei dem> eben genannte code jedoch wird die Zahl unabhängig von dem> Eingangssignal leider nicht erhöht.
Hast du deine ganze Programlogik in eine Schleife gepackt?
Wenn nicht: Du hast nach starten des Programms ein paar Nanosekunden
Zeit die Taste zu drücken (oder du drückst sie bereits bevor das
Programm startet). Bist du wirklich so schnell?
(Aber auch in einer Schleife wird das nicht gehen. Der µC arbeitet die
Schleife viele Tausend male in der Sekunde ab. So schnell bist du nicht,
dass du den Taster nur für einen Schleifendurchlauf gedrückt halten
kannst)
Aber zeig jetzt erst mal dein komplettes Programm.
i = i + (portc & 7) ist auch ne Idee. Wenn der Code auch noch
sicherstellen muss, dass nur eine Taste gedrückt wird, dann muss man eh
beide Ansätze nochmal überdenken.
Guten Abend :)
vielen Dank für die zahlreichen Antworten, haben mir sehr
weitergeholfen. Nun muss ich doch etwas ausschwenken.
Durch PortD bekomme ich ein codiertes Signal, welches zuerst decodiert
wird und über die ersten 4 Pins an PortB ausgegeben wird. Die 4 Bits
ergeben einen dem Binärcode entsprechenden Zahlenwert wie z.b. (Binär)
1 0 1 1 = 11 (Dezimal). Diese verbinde ich parallel mit den letzten 4
Pins von PortB, welche als Eingang defniniert werden müssen.
Nun das Problem :-(, will den Zustand an allen Pins(Pin4 - Pin7)
einlesen (einmalig, bis sich etwas ändert), bearbeiten und als
Dezimalzahl auf dem LCD-Display ausgeben. Alternativ könnte die Abfrage
auch zyklisch? laufen, also alle 2 Sekunden wird der Wert eingelesen und
ausgegeben. Wichtig hierbei wäre mir, dass wenn möglich kein Interrupt
verwendet wird, da diese in anderen Programmteilen schon verwendet
werden.
Was bei dem versuchten Beispiel noch fehlt, ist zum Einen die
Schleifenbedingung wie auch die Eingangs/Ausgangsdefinierung von PortB.
Danke nochmals für Eure investierte Zeit, freue mich auf neue Anregungen
und Ansätze.
1
#include<avr/io.h>
2
#include"lcd-routines.h"
3
4
5
intmain(void)
6
{
7
lcd_init();
8
inti;
9
10
if(PINC&(1<<PC1))
11
{
12
i=i++
13
}
14
15
if(PINC&(1<<PC2))
16
{
17
i=i+2
18
}
19
20
if(PINC&(1<<PC3))
21
{
22
i=i+4
23
}
24
25
if(PINC&(1<<PC4))
26
{
27
i=i+8
28
}
29
30
charBuffer[20];
31
32
33
toa(i,Buffer,10);
34
lcd_string(Buffer);
35
36
37
38
while(1)
39
{
40
}
41
42
return0;
43
}
bussi Laura
PS: Was mir sonst noch einfallen würde, wäre eine
Case-Fallunterscheidung je nach String, da im späteren Stadium des
Projekts nur 4-6 Fälle möglich sind.
Guten Morgen =)
hab nochmal eine Nacht darüber geschlafen, der jetzige Code (Vorerst nur
mit einem PIN, anstatt 4) sieht wie folgt aus:
1
#include<avr/io.h>
2
#include<stdlib.h>
3
#include"lcd-routines.h"
4
#include<util/delay.h>
5
6
inti=0;
7
8
intmain(void)
9
{
10
DDRC=0x00;
11
12
lcd_init();
13
while(1)
14
{
15
if(PINC&(1<<PC1))
16
{
17
i=i++;
18
_delay_ms(1000);
19
20
21
charBuffer[20];
22
23
24
itoa(i,Buffer,10);
25
lcd_string(Buffer);
26
}
27
28
29
30
31
}
32
33
return0;
34
}
Leider reagiert der mega8 weder auf das Eingangssignal, noch
aktualisiert er die Zahl am Display.
Sollte ja so aussehen:
Sequenz 1 : 0
Sequenz 2 : 1 (Wenn an dem Pin ein high Signal anliegt)
Sequenz 3 : 1 (Wenn Low)
Sequenz 4 : 2 (Wenn high)
usw usf.
So sieht es momentan aus:
Sequenz 1 : 1
Sequenz 2 : 12
Sequenz 3 : 123
(Unabhängig vom Eingangssignal)
Bin echt am Ende. vielleicht weiß jemand von Euch weiter.
bussi laura
Laura schrieb:
> So sieht es momentan aus:> Sequenz 1 : 1> Sequenz 2 : 12> Sequenz 3 : 123> (Unabhängig vom Eingangssignal)
unabhängig kann nicht sein.
Da wird wohl der Pin ständig auf High liegen. Und jedesmal wenn die
Abfrage
if ( PINC & ( 1 << PC1 ) )
den Pin als High vorfindet, wird i um 1 erhöht.
Und da du die Zahlenwerte nicht übereinander schreibst, sondern
hintereinander, taucht eben dieses Sequenz auf deinem LCD auf.
Bist du sicher, dass _delay_ms(1000) - hardwaremäßig - eine Sekunde lang
Däumchen dreht? _delay_ms(1000) ist zunächst mal nur eine
Programmanweisung. Die ist so nur wirksam, wenn 1. die Hardware passend
beschaltet und eingestellt ist und 2. die Übersetzung entsprechend
gemacht wurde. Näheres siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29
Bist du sicher, dass du die Taste active high angeschlossen hast? Vom
Programm oben her, braucht deine Schaltung einen externen
Pull-Down-Widerstand. Ist der vorhanden? Näheres siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter
Bist du sicher, dass du die Taste in weniger als 1s wieder los lässt,
damit keine Mehrfachzählung auftritt? Du könntest diesen Punkt mit einer
Programmerweiterung entschärfen, indem du nach der Registrierung eines
Tastendrucks wartest, bis die Taste wieder losgelassen wurde. Bzgl.
Tasten schau dir auch das Thema Entprellung an.
Ich nehme mal an, dass PC von 0 bis 7 geht, oder? Programmiere gerade
nen anderen Controller ;o)
int main(void)
{
DDRC = 0x00;
lcd_init();
while(1)
{
if ( PINC & ( 1 << PC1 ) )
// if (PINC & 14) prüft alle 3 Pins gleichzeitig
// kann man ggf auch in ein switch ( PINC & 14 ) umwandeln,
// damit kann man dann nämlich das drücken mehrerer Tasten prüfen und
// ggf. ignorieren
{
i=i++;
// das wird zwar vom Compiler wegoptimiert, ist aber trotzdem
Unsinn.
// i++ schreibt das Ergebnis immer in i zurück, die Zuweisung
bringt
// also nix.
// abgesehen davon, für alle 3 Pins dann
i += ( PINC & 14 )>>1
_delay_ms(1000);
char Buffer[20];
// sowas macht man in der Regel außerhalb der Schleife.
itoa( i, Buffer, 10 );
// wofür steht die 10?
lcd_string( Buffer );
}
}
return 0;
// kann man sich sparen, da es eh eine Endloss-Schleife ist.
// Ggf int main in void main umwandeln.
}