Forum: Mikrocontroller und Digitale Elektronik I/O Ports ATmega16


von Andreas Strobel (Gast)


Lesenswert?

Hallo.

Ich wollte einen Chip mit dem ATmega16 programmieren. Die
Datenleitungen hängen an PORTC.0 bis .7

Wenn ich nun etwas über die Ports ausgeben will, setze ich den Port auf
Ausgang (DDRC=0xFF) und setze eine 0x80. Also: PORTC=0x80;
Wenn ich nach dem Befehl eine endlosschleife setze, zeigt das Oszi auch
5V am PIN7. Alles richtig!

Danach will ich über die gleichen Leitungen lesen. Also schalte ich den
PORTC auf Eingang (DDRC=0x00) und gebe den PORT über die UDR aus.

UDR = PINC;

Hier zeigt er mir wieder die 0x80 an, die ich gerade geschickt habe.
Aber es sollte eine 0x00 anliegen, was das Oszi auch bestätigt. Es
liegt 0V an PINC7 an. Trotzdem gibt er mir eine 0x80 aus.

Weiß jemand woran das liegen könnte?

Auch beim Einschalten des Chips und Ausgabe über UDR gibt er eine =xFF
an, obwohl nirgendwo 5V liegen sondern schönste 0V?!?!? Bin ratlos ;)

Andreas

von Winfried Jaeckel (Gast)


Lesenswert?

Welche Funktion trägt der PIN noch?

Eventuell musst du erst die standartmässig eingestellte JTAG
Schnittstelle abschalten oder eine andere Doppelnutzung/Mehrfachnutzung
des Pins

Ich hatte was Ähnliches im Datenblatt des ATMega32 entdeckt

von Andreas Strobel (Gast)


Lesenswert?

Hallo Winfried,

du hast recht! An dem Port hängt wirklich der JTAg und auch der
serielle Bus. Hmm, muss ich mal genau schauen ob das aktiviert ist,
obwohl ich mir gar nich vorstellen kann, wie ich das gemacht haben
könnte ;)

Andreas

von Pete da Heat (Gast)


Lesenswert?

An PortC ist zwar die JTAG-Schnittstelle, die beinflusst aber Pin7
nicht.
Wann legst Du denn Deine 0V an Pin7 an und wann sendet Dein UART? Wenn
Du nämlich erst nach 3 Sekunden die 0V oder so anlegst, hat Dein UART
u.U. schon lange den noch alten Wert geschickt. Nur mal so ne
Vermutung, Dein Code wäre hilfreich...

Pete

von Pete da Heat (Gast)


Lesenswert?

>>du hast recht! An dem Port hängt wirklich der JTAg und auch der
>>serielle Bus. Hmm, muss ich mal genau schauen ob das aktiviert ist,
>>obwohl ich mir gar nich vorstellen kann, wie ich das gemacht haben
>>könnte ;)
Wie gesagt, das JTAG tut dem Pin7 nix, ist aber standardmäßig
aktiviert, d.h Du mußt da gar nix für tun...
Kannst Du über die JTAGEN-Fuse deaktivieren, wird Dir aber hier wohl
nicht helfen.

Pete

von Andreas Strobel (Gast)


Lesenswert?

Hallo Pete,

der Code sieht im Grunde folgendermaßen aus:

DDRC=0x00;
portd.6 = 1; // NCS high
portd.4 = 1; // NRD high
portd.5 = 1; // NWR high
portd.0 = 0; // output address 1
portd.1 = 0; // output address 2
portd.2 = 0; // output address 3
wait();      // zwischen address stable und fallender Flanke von NRD
mindestens 30 ns,
portd.6 = 0; // chip select pulse, NCS low
portd.4 = 0; // start read pulse, NRD low
wait();      // hier müssen mindestens 65 ns vergehen,
UDR = PINC;   // byte einlesen
portd.4 = 1; // und read pulse beenden, NRD = 1
portd.6 = 1; // chip select wieder wegnehmen

Also ich muss bei dem anderen Chip einen Read-Impuls auslösen was ich
über PORTD mache. Über PortD wird auch die Addresse eingestellt. Und
dann lese ich einfach PINC ein. Das passiert sofort als erstes (direkt
nach dem Reset oder einschalten)Und da kommt 0xFF, obwohl nirgendwo was
anliegt nach Oszi. Wenn ich erst etwas anderes schreibe, lese ich sofort
danach (ohne Verzögerung) den Wert den ich da gerade geschrieben habe.
Kann der ATmega defekt sein? ich kanns mir nicht erklären.

Andreas

von Winfried Jaeckel (Gast)


Lesenswert?

http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf


also ich lese im datenblat tosc2
aber wenn du nen anderen hast als der zum datenpblatt also mit jtag ,
dann ist jtag standartmäsig aktiv und dder portpin abgeschaltet . das
habe ich schon durch

ich glaube da war was mit nem doppelt auszugebendem registerbefehl um
jtag abzuschalten.


ich suche das mal raus

von Andreas Strobel (Gast)


Lesenswert?

Hallo Winfried,

ich benutze den gesamten PortC. Du hast Recht. An pin7 von PORTC ist
TOSC2. An pin6 ist TOSC1 und dann kommt JTAG und die serielle. Aber bei
mir scheint ja der gesamte PORT zu spinnen. Es sei denn ich bin zu doof,
was ich hier keineswegs ausschließen möchte ;)

Andreas

von Winfried Jaeckel (Gast)


Lesenswert?


von Winfried Jaeckel (Gast)


Lesenswert?

nein du bist nicht doof die mehrfachbelegung der Pins erfordert eine
umsichtige zweckentsprechende chipinitialiesierung. da braucht es eine
weile bis man durch 250 seiten datasheet durch ist.

CVAVR hat nen gut funktionierenden codewizardavr , welcher das alles
für dich erledigt und nen gutes programmgerüst erstellt. wenn du willst
kann ich das mal durchlaufen lasen und dir den itiialisierungscode
entsprechen deinen bedingungen erstellen und mailen.

von Andreas Strobel (Gast)


Lesenswert?

@Winfried

Das wär super. Könnt ich dann gleich (morgen) mal ausprobieren. Wie
gesagt bräuchte ichnur hilfe bei dem PORTC, die restlichen scheinen ja
soweit zu laufen.

Andreas

von Winfried Jaeckel (Gast)


Lesenswert?

also

PC2-PC5 beinhalten die standartmäßig eingeschaltete JTAG ohne die
auszuschalten läuft auf portc2-5 nichts !

MFG winne

von Winfried Jaeckel (Gast)


Angehängte Dateien:

Lesenswert?

Achte vorallem auf die doppelte beschreibung von MCUCR

von Winfried Jaeckel (Gast)


Lesenswert?

Hallo?

von Andreas Strobel (Gast)


Lesenswert?

hallo winfried,

sorry, musste mal kurz weg. leider kann ich das erst morgen
ausprobieren.

wieso hast du eigentlich den portc auf ausgang gesetzt? wenn ich was
lesen will sollte der doch auf eingang stehen...

hmm, ich hoffe das funktioniert dann ;) ist echt ein stressiger
fehler..

Andreas

von thkais (Gast)


Lesenswert?

Ich schalte das JTAG einfach per Fuse ab, dann muss ich nicht mit dem
MCUCR herumpopeln.
Die Zweitfunktionen der Portpins sind defaultmäßig abgeschaltet, man
muss also nicht alles explizit abschalten.

von winne (Gast)


Lesenswert?

sorry mein fehler

ddrc kanst du schalten wie du willst,
wichtig ist nur mcucr zweimaunmittelbar hintereinander zu beschreiben
und so/dabei das jtagenable bit zu löschen. die fuses mag ich nicht
ärgern hab mich damit aus meinem ersten 32erausgeperrt.
in dm ich  ispenable gelöscht habe. heul

von Andreas Strobel (Gast)


Lesenswert?

ach herjeh... das klingt ja heftig. werd morgen mal schauen, aber ich
hab so im hinterkopf, dass ich das JTAG auch aus habe. mit dem MCUCR.
aber wieso kann ich PORTC mit DDRC schalten wie ich will? dachte wenn
ich über UDR ausgeben will, was in den Port reingeht sollte das DDRx
schon auf Eingang, also 0x00 stehen. glaub ich ;) so gesehen also nicht
ganz egal.  werd auf jeden fall noch einen zweiten atmega probieren.
nich das der kaputt ist.

sollte ich die beiden chips über widerstände an jedem beinchen
miteinander verbinden, oder einfach so? im moment hab ich 4,7kohm
dran.

Andreas

von Winfried Jaeckel (Gast)


Lesenswert?

Ich Empfehle für Versuche Pufferwiderstände (1Kohm)  um bei
Kurzschlüssen durch Programmierfehler nicht die Ports hochzujagen. Ich
habe das hinter mir.

Oder erst im Steckbrett die einzelnen µCs nebst Software zu testen
bevor man sie zusammenschaltet.

der mögliche Gau: zwei Ausgänge liegen auf einem Potential, einer low
einer high ....... -> exitus für 2 Ports

von Andreas Strobel (Gast)


Angehängte Dateien:

Lesenswert?

hallo,

ich habe mal den atmega getauscht und lese jetzt an dem gesamten port c
eine 0x00. nur leider sollte jetzt (mit oszi gemessen) an bein 3,4 und 6
 ein "high" anliegen. da sind nämlich schönste 5V zu messen. Das wäre
nach meiner Rechnung eine 0xB2. Trotzdem behauptet der stur es würde
eine 0x00 anliegen.

Hab mal mein prog als txt file mit hochgeladen. Vielleicht hat jemand
ne Idee?!?

Andreas

von johnny.m (Gast)


Lesenswert?

Musst beim löschen eines Portpins Klammern setzen um das 1<<XY. bildest
sonst nur das Komplement von 1 (~1). Muss heißen ~(1 << XY)!

Gruß

Johnny

von Andreas Strobel (Gast)


Lesenswert?

Hi Johnny,

jup Danke. Hab ich grade geändert. Nur leider bringt mich das bei
meinen Datenleitungen auf PORTC nicht weiter.Das Problem besteht immer
noch. Das merkwürdige ist auch, dass der mir 0x00 zweimal ausgibt,
obwohl ich den doch nur einmal an die UDR übergebe...

Andreas

von Wolfram (Gast)


Lesenswert?

Nimm mal den Chip am PortC weg und schließe an PINC7 nur einen Pullup
oder Pulldown Widerstand (10K) an. Lass die ganzen Initialisierungen
weg.(mit ausnahme der USART) und probiere den Zustand zu lesen
also ungefähr
int main()
{
uartinit
UDR=PINC;
}

Nicht das du probierst den hochohmigen Zustand eines Chips auszulesen.
(Du schreibst auf PortC an einen Chip und änderst dann am
Mikrocontroller die Leserichtung bist du dir sicher das du es dem Chip
auch mitteilst???
NRD(value) { if(value) PORTD |= 1<<PB5; else PORTD &= ~1<<PB5;
kann es sein das deine RD/WR etc leitungen zur Ansteuerung des Chips
alle auf PortB liegen? (du greifst aber auf PORTD zu!)
außerdem: ~1<<PB5 ;also ich kann die Vorzeichenregeln nicht aus dem FF
aber mit ~(1<<PB5) bin ich mir sicher was passiert.

von Andreas Strobel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

danke für eure Hinweise. ich hab das jetzt alles mal umgesetzt. Ich
habe PINC.7 mit 10k auf masse gelegt. Er ließt immernoch 0x00. Aber
alle Pins die mit JTAG zu tun haben PC2 bis PC5 sind laut Oszi auf
"high". Trotzdem ließt der eine 0x00. Ist das so richtig? Der chip
ist nicht mehr an PortC angeschlossen (alles offen außer eben PINC7).

Andreas

von Andreas Strobel (Gast)


Lesenswert?

Also ich bin jetzt mal mit meinen Datenleitungen auf PORTA umgezogen. Da
lese ich ebenfalls 0x00. (durch oszi bestätigt) Dann habe ich mit einem
10k auf "high" an PINA.7 eine "1" angelegt. Trotzdem wird 0x00
ausgegeben?!?!?!? Bin jetzt echt ratlos!

Andreas

von Karl H. (kbuchegg)


Lesenswert?

Du kannst also machen was Du willst, es wird immer
0x00 augegeben? Dann wuerde ich doch meinen Verdacht
mal auf die Ausgabe legen. Die konnte ich im uebrigen
in Deinem Program nicht entdecken.
Da steht nur

   while( 1 )
   {
   }

Also eine Endlosschleife, in der absolut nichts passiert.
Und da ich auch keine Interruptfunktionen in Deinem Pgm
gesehen habe, macht dann der µC auch genau dieses: absolut
nichts.

von Andreas Strobel (Gast)


Lesenswert?

Naja, über der while schleife steht:

UDR=PINC (ist jetzt PINA) bin ja umgezogen...

Das ist meine Ausgabe.

von Karl H. (kbuchegg)


Lesenswert?

Dann solltest Du mal testen, ob Dein UART
grundsaetzlich funktioniert. Da gibt es
viele Moeglichkeiten, was da alles schief
gehen kann.


Also irgendwas in der Form

   while( 1 ) {
     UDR = 'A';
   }

und am angeschlossenene Terminal muessen dann
lauter 'A' auftauchen. Erst wenn dieses funktioniert,
wuerde ich mir mal Gedanken darueber machen, wie
ein Port-Wert uebertragen werden kann.

von Karl H. (kbuchegg)


Lesenswert?

>    while( 1 ) {
>      UDR = 'A';
>    }

Das ist natuerlich keine vollstaendige IMplementierung
einer Uebertragung. Vorher sollte man testen, ob der
UART ueberhaupt bereit zum Senden ist, usw.
STeht aber alles im AVR-gcc Tutorial im Abschnitt
ueber UART.

von Wolfram (Gast)


Lesenswert?

UBRRL=67 für 9600 Baud? Wie kommst du auf diesen Wert?
Welche Taktfrequenz hat die MCU?

von Andreas Strobel (Gast)


Lesenswert?

auf die UBRRL=67 komme ich nich selber, sondern der Codevision AVR
compiler mit dem man sich so ein programmgerüst erzeugen lassen kann.

Der Atmega läuft mit 16MHz.

von Pete da Heat (Gast)


Lesenswert?

Dein UART funktioniert aber, oder wie? Wenn ich ins Datenblatt (S.169)
schau, steht da nämlich UBRR=103 bei 9600 Baud @ 16MHz (U2X=0)

Pete

von johnny.m (Gast)


Lesenswert?

Und was ist 103d in hex??? Zufällig genau 67!!! Das stimmt schon, im
Programmcode weiter oben stehts drin.

von Pete da Heat (Gast)


Lesenswert?

Stimmt natürlich, hab mir den Code gar nicht mehr angeschaut, sondern
nur Wolfram's Post gelesen...

von Wolfram (Gast)


Lesenswert?

Du weisst aber schon das bei 16MHz es zu Übertragungsfehlern kommt?
Siehe Datenblatt.
Das merkt man zwar nicht am Einzelzeichen aber bei so 10 Zeichen am
Stück kann schon mal eins umfallen.
Da ist 8 Datenbits ein Stopbit schon sehr mutig. Also wenn es schon
unbedingt sein muss, dann wenigstens 2 Stopbits ,sonst provoziert man
ja regelrecht den Framebreak.

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.