Forum: Mikrocontroller und Digitale Elektronik Eingänge PORTC Probleme beim Atmega8


von Andreas (Gast)


Lesenswert?

hallo, ich habe folgendes problem und bin momentan mit meinem latein am 
ende. weiß nich woran das liegt. ich habe eine tastatur(0 bis 9 und 
Stern und Raute) an PortB und PortC angeschlossen. PortB und PortC 
jeweils 6 Pins, also passt. nun aber das problem. die letzten 3 Pins 
also vom PortC kann ich nicht ansprechen! siehe programmcode... PortB 
klappt alles perfekt aber bei PortC klappt das mit der 9, Stern und 
Rautetaste nicht. Hat jemand eine Idee? wäre sehr dankbar



switch(port_b)
{
case 0xFE: pw_org[counter]='0'; counter++; break;
case 0xFD: pw_org[counter]='1'; counter++; break;
case 0xFB: pw_org[counter]='2'; counter++; break;
case 0xF7: pw_org[counter]='3'; counter++; break;
case 0xEF: pw_org[counter]='4'; counter++; break;
case 0xDF: pw_org[counter]='5'; counter++; break;
}

switch(port_c)
{
case 0x3E: pw_org[counter]='6'; counter++; break;
case 0x3D: pw_org[counter]='7'; counter++; break;
case 0x3B: pw_org[counter]='8'; counter++; break;
case 0x37: pw_org[counter]='9'; counter++; break;
case 0x2F: goto j_set_pw; //ABGEBROCHEN
break;
case 0x1F: var=0; break;

von Toni (Gast)


Lesenswert?

Hi,

bin mir nicht ganz sicher was den ATMega8 angeht.

Aber schau mal ins Datenblatt. Soweit ich mich erinnern kann sind dort 
nur die Pins PC0 bis PC5 verfügbar.


Gruß

von Johannes M. (johnny-m)


Lesenswert?

Toni wrote:
> Aber schau mal ins Datenblatt. Soweit ich mich erinnern kann sind dort
> nur die Pins PC0 bis PC5 verfügbar.
Und? Sind doch 6 Stück, genau wie er schreibt... Das Problem liegt eher 
in seiner Auswertung.

@Andreas:
Du musst die Pins einzeln maskieren. So wie Du das machst, wird das 
nichts. Schau mal z.B. unter Bitmanipulation.

Das Problem liegt vermutlich hauptsächlich darin, dass Port C nicht 
komplett zur Verfügung stehen, und dementsprechend die nicht vorhandenen 
Pins undefinierte Zustände zurückliefern. Du nimmst diese nicht 
vorhandenen Bits in der Abfrage anscheinend leichtfertigerweise als '0' 
an (zumindest geht aus dem Codeschnipsel nichts anderes hervor), was 
aber nicht unbedingt der Realität entsprechen muss. Wenn Du es schon mit 
einer switch...case-Abfrage machen willst, dann maskiere vorher die 
beiden höchstwertigen Bits aus (also setze sie definiert auf Null). Nur 
dann kann die Abfrage überhaupt funktionieren.

Allerdings kann die ganze Geschichte natürlich nur funktionieren, wenn 
nicht mehr als eine Taste an einem Port betätigt wurde.

EDIT:
ohlala, ich sehe da grad noch was, was überhaupt nicht gut ist:
> case 0x2F: goto j_set_pw; //ABGEBROCHEN
Verwende kein goto, erst recht nicht in einem solchen Konstrukt! Ich 
vermute mal, dass da irgendwohin gesprungen wird aber nicht wieder 
zurück. Das wird möglicherweise Stacksalat geben, je nachdem, wie der 
Rest aussieht. Also BITTEBITTEBITTE kein goto in C-Programmen! Es 
gibt nur einige ganz wenige exotische Anwendungsfälle dafür, die in 
Deinem Programm mit größter Wahrscheinlichkeit nicht auftreten.

von Andreas (Gast)


Lesenswert?

okay ich danke dir erstmal...
das mit dem goto werd ich nochmal überdenken, da wird sich was besseres 
finden.
was das maskieren angeht, hast du natürlich recht.

so, ich hab dann mal ein kleines testprogramm geschrieben.. (an PORTD 
hängen LEDs)

#define   F_CPU 3686400
#include  <avr\io.h>

main()
{
    DDRC = 0x00;
    DDRB = 0x00;
    DDRD = 0xFF;

    PORTD = 0x00;
    PORTC = 0xFF;
    PORTB = 0xFF;
    int port_b=0xFF;
    int port_c=0xFF;
    int b=0xFF;
    int c=0xFF;

do
{
  port_b=0xFF;
  port_c=0xFF;

  do
  {
   port_b=PINB;
   port_c=PINC;
  }while(((port_b==0xFF)&&(port_c==0x3F)));

  do
  {
   b=port_b;
   c=port_c;
  }while(((b==PINB))&&((c==PINC)));

   port_c=port_c & 0b00111111;

   switch(port_c)
   {
    case 0x1F:PORTD=0xFF;  break;
   }
} while (true);


allerdings funktioniert es hier auch nich, eigentlich sollten die LEDs 
aber leuchten...oder seh ich da was falsch?
danke schonmal ;)

von crazy horse (Gast)


Lesenswert?

"Also BITTEBITTEBITTE kein goto in C-Programmen"

jaja, das hört man immer wieder, dennoch setze ich es hin und wieder 
ein. Ganz ohne Gewissensbisse - nur dass "man es nicht macht" ist für 
mich kein Grund, es nicht zu tun. Die Sprache sieht es vor, und es 
vereinfacht manche Sachen erheblich. Natürlich geht es ohne, es geht 
aber auch ohne viele andere Sachen. Und ein break ist letztenendes auch 
nichts anderes.
Ich will mit meiner Software keinen Schönheitspreis gewinnen, sie soll 
sicher funktionieren und den Umständen angemessen schnell genug sein, 
nebenbei mit dem zur Verfügung stehenden Platz auskommen. Und ewig Zeit 
zum Schönfeilen habe ich auch nicht, wird zumindest nicht bezahlt. Das 
sind meine Anforderungen, und wenn ich in einer grösseren Funktion 
mehrere Fehlermöglichkeiten habe, gibts in der Funktion mehrere goto 
error!

von Johannes M. (johnny-m)


Lesenswert?

crazy horse wrote:
> "Also BITTEBITTEBITTE kein goto in C-Programmen"
>
> jaja, das hört man immer wieder, dennoch setze ich es hin und wieder
> ein. Ganz ohne Gewissensbisse - nur dass "man es nicht macht" ist für
> mich kein Grund, es nicht zu tun.
Du kannst ja machen, was Du willst, aber erzähle hier keinem "Newbie", 
er solle ohne weiteres goto verwenden! goto hat im Normalfall in einer 
Hochsprache, deren großer Vorteil die Möglichkeit der strukturierten 
Programmierung ist, nichts verloren, und da kannst auch Du nichts dran 
ändern! goto macht nämlich genau diesen großen Vorteil zunichte.

> Die Sprache sieht es vor, [...]
...und selbst die Erfinder von C raten zu allergrößter Vorsicht bei der 
Verwendung und sagen, dass goto fast immer vermeidbar ist!

> [...] und es vereinfacht manche Sachen erheblich.
Aber nicht die Dinge, die die Vorteile eines C-Programms unter anderem 
ausmachen, nämlich Lesbarkeit und Wartung!

von Stefanie B. (sbs)


Lesenswert?

>Lesbarkeit und Wartung!
 in Verbindung mit C ist auch so ein Spezialfall ;-)

...

von Andreas (Gast)


Lesenswert?

okay leute, wie gesagt, das mit dem goto werd ich noch ausbessern...
die frage ist immernoch: WIESO geht das zuletzt gepostete programm 
nicht?
die ich habe schon getestet ob, wenn man die taste drückt, durch diese
1
do
2
  {
3
   port_b=PINB;
4
   port_c=PINC;
5
  }while(((port_b==0xFF)&&(port_c==0x3F)));
6
7
  do
8
  {
9
   b=port_b;
10
   c=port_c;
11
  }while(((b==PINB))&&((c==PINC)));

Schleifen kommt, das geht...
Das Problem ist, dass ich nicht weiß, was genau in der variable port_c 
steht.
könnte mir das jemand erklären bitte...
dankeschön ;)

von mehrfacher STK500-Besitzer (Gast)


Lesenswert?

>Das Problem ist, dass ich nicht weiß, was genau in der variable port_c
>steht.

In port_c kann jeder Wert stehen, wenn an Port B eine Taste gedrückt 
wurde.
Die Wahrscheinlichkeit ist aber sehr hoch, dass in diesem Fall immer 
noch 0x3F in der Variablen steht.
Wenn an Port C eine Taste gedrückt wurde, steht in port_c nicht mehr 
0x3F.

von Andreas (Gast)


Lesenswert?

genau, ich hab ja auch schon rausgefunden, dass in port_c nicht mehr 
0x3F steht, wenn ich die taste drücke...
nur weiss ich eben nicht, wie ich rausfinden kann, was denn nun in 
port_c drin steht... :( bin echt am verzweifeln

von Johannes M. (johnny-m)


Lesenswert?

Andreas wrote:
> genau, ich hab ja auch schon rausgefunden, dass in port_c nicht mehr
> 0x3F steht, wenn ich die taste drücke...
> nur weiss ich eben nicht, wie ich rausfinden kann, was denn nun in
> port_c drin steht... :( bin echt am verzweifeln
Nanana, nicht verzweifeln... Gib doch einfach den Wert von port_c an 
Port D aus, oder ist das ein so großes Problem?

von mehrfacher STK500-Besitzer (Gast)


Lesenswert?

>nur weiss ich eben nicht, wie ich rausfinden kann, was denn nun in
>port_c drin steht... :( bin echt am verzweifeln

Du könntest bitweise die Variable "zerlegen".
Dazu gibt es in C dieses Konstrukt: (1<<n), wobei n die Anzahl der 
Verschiebungen der 1 angibt (nichts anderes als ein Exponent).

Wenn du also testen willst, ob Bit 4 gesetzt ist, dann sieht das so aus:

if (port_c & (1<<4)) //Bit vier ist gesetzt
Mit etwas bool'scher Logik kann man dann auch den entgegengesetzten Fall 
prüfen.
Mehr dazu steht bestimmt in AVR-GCC-Tutorium...

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.