Forum: Mikrocontroller und Digitale Elektronik AT90USB162 PortC funktioniert nicht als Eingang


von Daniel (Gast)


Lesenswert?

Als Microcontroller-Anfänger kriege ich es nicht hin, die oberen 4 Bit 
vom PortC als Inputs (Taster) zu verwenden. Es scheint, als friert der 
Controller ein, wenn ich den PortC als Input benutzen will. Ich mach 
folgendes:

 int main(void) {
   DDRB = 0xff; // set Port PORTB to output
   PORTB = 0x00; // initial state: no channel is on

   DDRC = 0x0f; // upper nibble of PORTC as input, lower nibble as 
output
   PORTC &= 0x0f; // no pull-ups on upper nibble of PORTC

   uint8_t sel = 0;
   unsigned long cnt = 0;

   PORTB_SET(7); // set PB7 to 1

   // Channel Control Loop
   while(1) {
     sel = PINC & 0x70;

     ... do the channel magic stuff ...

     // Activity indicator, for debugging only
     ++cnt;
     if (cnt>40000UL) {
       cnt = 0UL;
       PORTB_INV(7); // let it blink
     }
   }
 }

Soviel habe ich bereits rausgefunden:
- benutze ich PortD statt C, läuft alles wie erwartet, will ich aber 
nicht, da ich PortD später für anderes brauche
- kommentiere ich die DDRC Zeile aus, läuft zwar der Kontroll-Blinker, 
aber etwa nur halb so schnell wie mit PortD

Irgendwo habe ich mal etwas über JTAG am PortC gelesen, das ist mir aber 
ein spanisches Dorf und brauche ich auch nicht, da ich ausschliesslich 
über den USB Bootloader arbeite. (Gibt's JTAG bei diesem Controller 
überhaupt?)

Vielleicht kann mir jemand den entscheidenden Hinweis geben...

von Phippu (Gast)


Lesenswert?

Hallo Daniel

Also bei so einem Fehler, ist die erste Anlaufstelle eigentlich immer 
das Datenblatt. Dort findest du die gesamte Dokumentation zu deinem 
verwendeten Mikrocontroller. Ich habe das unter folgendem Link 
heruntergeladen: http://www.atmel.com/Images/doc7707.pdf

Dort ist z.B. unter Kapitel 11.2.1 (S. 68) beschrieben, wie die DDxn 
PORTxn und PINxn geschaltet werden müssen um das gewünschte Verhalten zu 
erreichen.
Ich habe jetzt nicht extrem lange gesucht, kenne mich mit Atmel auch 
nicht besonders aus. Aber ich habe im Kapitel 11.4 (S. 82) gesehen, dass 
das PORTC und DDRC Register auf Bit 3 nur "Readable" sind. Du versuchst 
da zumindest beim DDRC eine "1" dahin zu schreiben, vermutlich hat dein 
Controller das nicht so gern.

Ansonsten sieht dein Code gut aus, sofern die Funktionen wie PORTB_INV() 
vorhanden sind, die kenne ich nicht.

Versuch das mal ansonsten fragst du nochmals.

Gruss
Phippu

von Daniel (Gast)


Lesenswert?

Hi Phippu

Ein guter Hinweis. Das Datenblatt hatte ich natürlich bereits zu Hilfe 
genommen, aber ich ging davon aus, dass das Bit3 ohne Funktion ist und 
beim Schreiben einer 1 diese einfach in Nirvana geht...

Ich habs jetzt mal entsprechend mit einer 0 versucht:

 DDRC = 0x07;
 PORTC &= 0x07;

aber das liefert das gleiche Resultat. Die while Schleife läuft nicht 
an...

von spess53 (Gast)


Lesenswert?

Hi

>(Gibt's JTAG bei diesem Controller überhaupt?)

Da du das Datenblatt anscheinend nicht kennst, frage ich mich ,auf 
welcher Basis du überhaupt programmierst? Copy & Paste?

>Aber ich habe im Kapitel 11.4 (S. 82) gesehen, dass
>das PORTC und DDRC Register auf Bit 3 nur "Readable" sind. Du versuchst
>da zumindest beim DDRC eine "1" dahin zu schreiben, vermutlich hat dein
>Controller das nicht so gern.

Nö. Ein PC3-Pin gibt es nicht. Interessiert den Gasmanm, was du auf 
diese Bits schreibst.

MfG Spess

von Daniel (Gast)


Lesenswert?

spess53 schrieb:
> Da du das Datenblatt anscheinend nicht kennst, frage ich mich ,auf
> welcher Basis du überhaupt programmierst? Copy & Paste?

Ich kenne das Datenblatt und arbeite auch damit, lese aber nicht erst 
ein 300-seitiges Datenblatt durch, bevor ich zu experimentieren beginne, 
sondern suche mir die benötigten Informationen gezielt raus. Und der 
Rest kommt wie bei uns allen hier mit der Erfahrung und etwas fremder 
Hilfe.

Zudem hat mir das Datenblatt beim vorliegenden Problem nicht 
weitergeholfen, oder ich habe die richtige Stelle noch nicht gefunden.

spess53 schrieb:
> Nö. Ein PC3-Pin gibt es nicht. Interessiert den Gasmanm, was du auf
> diese Bits schreibst.

Das bestätigt meine Annahme. Zusätzlich hat ein Versuch gezeigt, dass es 
daran nicht liegt.

von spess53 (Gast)


Lesenswert?

Hi

>lese aber nicht erst
>ein 300-seitiges Datenblatt durch, bevor ich zu experimentieren beginne,
>sondern suche mir die benötigten Informationen gezielt raus.

Noch so ein Trottel, der die Bedienungsanleitung von seinem Auto erst 
nach dem Unfall liest.

MfG Spess

von Daniel (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>lese aber nicht erst
>>ein 300-seitiges Datenblatt durch, bevor ich zu experimentieren beginne,
>>sondern suche mir die benötigten Informationen gezielt raus.
>
> Noch so ein Trottel, der die Bedienungsanleitung von seinem Auto erst
> nach dem Unfall liest.
>
> MfG Spess

Wenn Du nicht helfen willst oder vermutlicht nicht kannst, schweigst Du 
am besten. Das sind genau die Antworten, die keiner braucht.

Wenn Du das Datenblatt dieses Controllers schon so gut auswendig kennst, 
zeig mir mal die Stelle, wo das Thema JTAG behandelt wird, und inwiefern 
es zum vorliegenden Problem im Zusammenhang steht!

von Volker G. (voga2073)


Lesenswert?

>    DDRC = 0x0f; // upper nibble of PORTC as input, lower nibble as
> output
> Vielleicht kann mir jemand den entscheidenden Hinweis geben...

Lass mal die unteren vier Bits vom Port C in Ruhe, dann sollte das auch 
gehen.

Volker

von spess53 (Gast)


Lesenswert?

Hi

>Wenn Du das Datenblatt dieses Controllers schon so gut auswendig kennst,
>zeig mir mal die Stelle, wo das Thema JTAG behandelt wird, und inwiefern
>es zum vorliegenden Problem im Zusammenhang steht!

Wenn du das Datenblatt auch nur annähernd kennen würdest, wäre dir 
aufgefallen, das JTAG dort nicht vorkommt. Der AT90USB162 hat DW als 
Debuginterface. Und das läuft nicht über PortC.

MfG Spess

von Peter D. (peda)


Lesenswert?

Daniel schrieb:
> DDRC = 0x0f; // upper nibble of PORTC as input, lower nibble as
> output
>    PORTC &= 0x0f; // no pull-ups on upper nibble of PORTC

Tasten ohne Pullups, wie soll das gehen?

Daniel schrieb:
> ... do the channel magic stuff ...

Wir können nicht hellsehen, Du mußt schon den relevanten Code zeigen.

von Daniel (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Tasten ohne Pullups, wie soll das gehen?

Weil ich Pull-Downs an den Tastern habe.

Peter Dannegger schrieb:
> Wir können nicht hellsehen, Du mußt schon den relevanten Code zeigen.

Der relevante Code ist im ersten Post vollständig. Der "magic stuff" ist 
noch gar nicht vorhanden.
Das einzige, was ich nicht in den Post kopiert habe ist die Definition 
von PORTB_INV, das funktioniert aber einwandfrei.

von Peter D. (peda)


Lesenswert?

Daniel schrieb:
> Der "magic stuff" ist
> noch gar nicht vorhanden.

Dann wird ja PINC nirgends ausgewertet und kann also nichts 
beeinflussen.

von Daniel (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Dann wird ja PINC nirgends ausgewertet und kann also nichts
> beeinflussen.

Das ist soweit auch noch gar nicht nötig. Wie ich eingangs beschrieben 
habe, läuft die while Schleife nicht an, erkennbar daran, dass die LED 
am PortB Pin 7 nicht blinkt (siehe Abschnitt //Activity indicator im 
Source Code).

von Phippu (Gast)


Lesenswert?

@spess53: Solche leute wie du, machen das Forum nur kaputt. Wenn du 
zuhause Probleme hast, dann klär sie dort und trag sie nicht ins Forum. 
Danke

Also Daniel, du zählst mit cnt bis auf 40'000 das ergibt rein ohne die 
anderen Befehle miteinzuberechnen eine Blinkfrequenz bei f_clk = 16MHz 
16'000'000/40'000 = 400Hz. Kann es sein dass du sie gar nicht leuchten 
siehst? denn auch mit den anderen kurzen aufrufen wirst du immernoch im 
unsichtbaren Blinkbereich sein.

Zum anderen:

PORTC &= 0x0f;

PORTC ist im initial-Zustand 0x00. Und du machst eine Bitweise 
UND-Verknüpfung mit 0x0f, was folglich ergibt:

  0b0000'0000
& 0b0000'1111
--------------
  0b0000'0000
==============

Daher hast du Laut Table 11-1 von dem Datenblatt nun bei dem PORTC 
MSB-Nibble ein Input mit keinem Pull-up (Hoher Eingangswiderstand). Und 
beim PORTC LSB-Nibble Output mit Low am Ausgang.

Ich seh jetzt gleich auch nicht mehr, an was es liegen könnte. 
Vielleicht können dir ja die Herren die die Lösung schon zu kennen 
scheinen weiterhelfen.

von Daniel (Gast)


Lesenswert?

Phippu schrieb:
> Also Daniel, du zählst mit cnt bis auf 40'000 das ergibt rein ohne die
> anderen Befehle miteinzuberechnen eine Blinkfrequenz bei f_clk = 16MHz
> 16'000'000/40'000 = 400Hz. Kann es sein dass du sie gar nicht leuchten
> siehst? denn auch mit den anderen kurzen aufrufen wirst du immernoch im
> unsichtbaren Blinkbereich sein.

Da hast Du natürlich recht. Effektiv habe ich (im anderen Thread 
rausgefunden) aber nur 1MHz. Ich schätze mal ganz grob, dass die Befehle 
während eines Schleifen-Durchgangs ca. 10 Zyklen benötigen komme ich auf 
1MHz  40000  10 / 2 = 1.25s . Das kommt ziemlich genau an die effektiv 
beobachtete Blinkgeschwindigkeit meiner LED ran. (durch 2 weils einmal 
ein und einmal ausschaltet, also 2 Schleifendurchgänge benötigt).

Zumindest verhält es sich so, wenn ich den PortD als Eingang benutze, 
die LED leuchtet aber konstant, wenn ich PortC benutze.

Aber ein guter Gedanke von dir. :)

Phippu schrieb:
> PORTC &= 0x0f;
>
> PORTC ist im initial-Zustand 0x00. Und du machst eine Bitweise
> UND-Verknüpfung mit 0x0f, was folglich ergibt:
>   0b0000'0000

Das ist jetzt peinlich. Das ist ein Tipfehler. Sollte natürlich eine 
Zuwseisung sein.

Phippu schrieb:
> Daher hast du Laut Table 11-1 von dem Datenblatt nun bei dem PORTC
> MSB-Nibble ein Input mit keinem Pull-up (Hoher Eingangswiderstand). Und
> beim PORTC LSB-Nibble Output mit Low am Ausgang.

Das würde mich soweit aber noch nicht mal stören, da ich momentan nur 
bit4-7 ohne Pull-up als Eingang benutzen will.

Phippu schrieb:
> Ich seh jetzt gleich auch nicht mehr, an was es liegen könnte.
> Vielleicht können dir ja die Herren die die Lösung schon zu kennen
> scheinen weiterhelfen.

Das hoffe ich natürlich ;)

von Daniel (Gast)


Lesenswert?

Da hat's mir jetzt die Rechnung versaut, sollte lauten, halt mit : statt 
/ :

1MHz : 40000 : 10 : 2 = 1.25Hz

Und natürlich mit Hz statt Sekunden, bevor wieder jemand schreit. ;)

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.