Anfängerfrage Atmega 16 - warum will Port C nur halb funktionieren? Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
Anfängerfrage Atmega 16 - warum will Port C nur halb funktionieren? Suche nach: atmega (406) |
|
|
|
|
BID = 688759
Teletrabi Schreibmaschine
Beiträge: 2317 Wohnort: Auf Anfrage...
|
|
Moin ihrs,
versuche mich zur Zeit ein wenig in die Programmierung von Atmels AVR hineinzufuchsen. Habe hier einen Atmega 16 auf Steckbrett. So wie er war eingesteckt, Takterzeugung läuft intern.
Ein wenig herumprogrammiert und Stelle fest, dass Port C irgendwie Probleme macht. Vernünftig angesteuert bekomme ich nur die jeweils oberen und unteren beiden beiden Pins.
Habe mir ein kleines Prog geschrieben, dass nen quadratureenconder ausliest und einfach nur ne Richtungs- und Fehleranzeige über drei LED rausschieben soll. Zunächst probiert mit C1, C2, C3 as Ausgang sowie C4 und C5 als Eingang - will nicht. C2 und C3 ergeben auf LED geführt auch kein vernünftiges Ausgangssignal, weder gegen Masse Strom aufnehmen nocht speisend.
FlipFlop basierend auf C6, C7 als Tastereingang sowie C0 und C1 als Ausgang läuft wunderbar.
Ist bei interner Taktquelle und wie-geliefert-Zustand irgendeine zweitbelegung auf den mittleren PortC-Pins aktiv, die ich erst ausstellen muss? Oder was hat es damit auf sich?!
Fragt sich,
Trabi
Code : |
#include <avr/io.h>
// Function prototypes
// LEDs an C0...C3; EIN-Taster an C6, AUS an C7
int LastState = 0;
int AktState = 0;
char Richtung = 'n';
int Zaehler = 0;
int main(void)
{
// Port C - untere pins als ausgang, obere als Eingang (0000.1111)
DDRC = 0x0f;
// Port C - obere pins pullup aktivieren (1111.0000)
PORTC = 0xf0;
AktState = ((PINC & 0b11000000)>>6); // Pin C7&C6 abfragen (1100.0000) und nach rechts schieben
for ( ; ; )
{
// FlipFlopSpass
//if (!(PINC & 0x80)) // Pin C7 abfragen (1000.0000)
//{
// PORTC = 0xf0; // LED aus, pullups bleiben aktiv (1111.0000)
//}
//if (!(PINC & 0x40)) // Pin C6 abfragen (0100.0000)
//{
// PORTC = 0b11111111; // LEDs an, pullups aktiv (1111.1111)
//}
// EncoderSpass
LastState = AktState;
AktState = ((PINC & 0b11000000)>>6); // Pin C7&C6 abfragen (1100.0000) und nach rechts schieben
if (LastState == AktState)
{
Richtung = 'n';
}
else if(LastState == 0b00000000)
{
if (AktState == 0b00000001)
Richtung = 'r';
else if (AktState == 0b00000010)
Richtung = 'l';
else Richtung = 'e';
}
else if (LastState == 0b00000001)
{
if (AktState == 0b00000011)
Richtung = 'r';
else if (AktState == 0b00000000)
Richtung = 'l';
else Richtung = 'e';
}
else if (LastState == 0b00000011)
{
if (AktState == 0b00000010)
Richtung = 'r';
else if (AktState == 0b00000001)
Richtung = 'l';
else Richtung = 'e';
}
else if (LastState == 0b00000010)
{
if (AktState == 0b00000000)
Richtung = 'r';
else if (AktState == 0b00000011)
Richtung = 'l';
else Richtung = 'e';
}
if (Richtung == 'r')
{
PORTC |= (1 << 0 ); // LED C1 an, pullups aktiv (xxxx.xx1x)
PORTC &= ~(1 << 1 ); // LED C2 aus, pullups aktiv (xxxx.x0xx)
}
// else
// {
// PORTC &= ~(1 << 1 ); // LED an, pullups aktiv (xxxx.xx0x)
// }
if (Richtung == 'l')
{
PORTC |= (1 << 1 ); // LED C2 an, pullups aktiv (xxxx.x1xx)
PORTC &= ~(1 << 0 ); // LED C1 aus, pullups aktiv (xxxx.xx0x)
}
// else
// {
// PORTC &= ~(1 << 2 ); // LED an, pullups aktiv (xxxx.x0xx)
// }
if (Richtung == 'e')
{
PORTC |= (1 << 2 ); // LED an, pullups aktiv (xxxx.1xxx)
}
}
return 0;
}
|
|
|
|
BID = 688761
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
|
Hallo
Du hast mit deiner Annahme 100% ins Schwarze getroffen. Diese Pins werden für das JTAG-Interface benutzt und sind standardmäßig aktiv:
Zitat :
|
The Port C pins with alternate functions are shown in Table 28. If the JTAG interface is
enabled, the pull-up resistors on pins PC5(TDI), PC3(TMS) and PC2(TCK) will be acti-
vated even if a reset occurs.
|
Siehe folgende Tabelle:
Hier sind die Standard-Konfigurationen der Fusebits zu sehen, das JTAG-Interface ist nach Auslieferungszustand aktiv:
Lösung:
Schalte es ab
Achja, versuche, Dualzahlen zu vermeiden. Ich weiß, der GCC kann es, aber andere oft nicht. Nimm stattdessen lieber direkt Hexadezimalzahlen (haste ja auch ), da sieht man eigentlich auch sofort, welche Bits gesetzt und welche nicht gesetzt sind
_________________
[ Diese Nachricht wurde geändert von: DonComi am 8 Mai 2010 6:40 ] |
|
BID = 688952
Teletrabi Schreibmaschine
Beiträge: 2317 Wohnort: Auf Anfrage...
|
Moin,
ja, auf die JTAG-geschichte bin ich beim stöbern nach dem posten auch noch gestoßen. Nur wie schaltr ich die korrekt ab? irgendwie hakt das bei mir immer noch. hatte jetzt versucht, das flipflop-gedöns auf die mitlren üins zu legen. funzt aber nich so wirklich
Code : |
#ifndef F_CPU
#define F_CPU 1000000UL /* interner Oszillator mit 1 Mhz */
#endif
#include <util/delay.h>
#include <avr/io.h>
// Function prototypes
// LEDs an C0...C3; EIN-Taster an C6, AUS an C7
int LastState = 0;
int AktState = 0;
char Richtung = 'n';
int Zaehler = 0;
int main(void)
{
// Port C - untere pins als ausgang, obere als Eingang (0000.1111)
DDRC = 0x0f;
// Port C - obere pins pullup aktivieren (1111.0000), LEDs aus
PORTC = 0xf0;
AktState = ((PINC & 0b11000000)>>6); // Pin C7&C6 abfragen (1100.0000) und nach rechts schieben
for ( ; ; )
{
//FlipFlopSpass
if (!(PINC & 0b00100000)) // Pin C5 abfragen (0010.0000)
{
PORTC &= ~(1 <<3); // LED aus, pullups bleiben aktiv (xxxx.1xxx)
}
if (!(PINC & 0b00010000)) // Pin C4 abfragen (0001.0000)
{
PORTB |= (1 << 3 ); // LEDs an, pullups aktiv (xxxx.0xxx)
}
// EncoderSpass
LastState = AktState;
AktState = ((PINC & 0b11000000)>>6); // Pin C7&C6 abfragen (1100.0000) und nach rechts schieben
if (LastState == AktState) // Zustand unverändert?
{
Richtung = 'n'; //keine Drehung
}
//Art der Zustandsänderung zur Richtungsbestimmung:
else if(LastState == 0b00000000)
{
if (AktState == 0b00000001)
Richtung = 'r';
else if (AktState == 0b00000010)
Richtung = 'l';
else Richtung = 'e'; //Fehlerhafte Zustandsfolge
}
else if (LastState == 0b00000001)
{
if (AktState == 0b00000011)
Richtung = 'r';
else if (AktState == 0b00000000)
Richtung = 'l';
else Richtung = 'e';
}
else if (LastState == 0b00000011)
{
if (AktState == 0b00000010)
Richtung = 'r';
else if (AktState == 0b00000001)
Richtung = 'l';
else Richtung = 'e';
}
else if (LastState == 0b00000010)
{
if (AktState == 0b00000000)
Richtung = 'r';
else if (AktState == 0b00000011)
Richtung = 'l';
else Richtung = 'e';
}
// Ausgabe der Richtung:
if (Richtung == 'r') //LED C0 für Rechtsdrehung
{
PORTC |= (1 << 0 ); // LED C0 an, pullups aktiv (xxxx.xx1x)
PORTC &= ~(1 << 1 ); // LED C1 aus, pullups aktiv (xxxx.x0xx)
}
if (Richtung == 'l') //LED C1 für Linksdrehung
{
PORTC |= (1 << 1 ); // LED C1 an, pullups aktiv (xxxx.x1xx)
PORTC &= ~(1 << 0 ); // LED C0 aus, pullups aktiv (xxxx.xx0x)
}
if (Richtung == 'e') // LED C2 als Fehlerindikator
{
PORTC |= (1 << 2 ); // LED an, pullups aktiv (xxxx.1xxx)
}
}
return 0;
}
|
|
|
BID = 688954
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Du musst die JTAG-Fusebits so setzen, dass das Interface deaktiviert wird.
Wie das mit deiner Software geht kann ich dir nicht sagen - ich nutze Ponyprog und da ist das schon nervenaufreibend genug...
Schau mal im Inet nach, wie man die Fuses setzen muss. Wichtig: Sperre dich bloß nicht aus. Eventuell ist der µC dann nicht mehr per ISP programmierbar.
Das Programm habe ich mir nicht angeschaut, da ich gerade extrem wenig Zeit habe.
Hast du es denn testweise mal mit einem anderen IO-Port, z.B. PortA versucht?
_________________
|
BID = 688962
Teletrabi Schreibmaschine
Beiträge: 2317 Wohnort: Auf Anfrage...
|
gerade auf Port D getestet - läuft. Unfd beim umschreiben auch den Fehler gefunden. Hatte sich ein Port B eingeschlichen.
|
BID = 689580
Teletrabi Schreibmaschine
Beiträge: 2317 Wohnort: Auf Anfrage...
|
Moin,
nochmal ein paar Fragen.
Braucht der AtMega zum Subtrahieren (bzw. simples Dekrementieren) deutlich länger als für Additionen? Oder für Schiebeoperationen nach links statt rechts?
Hatte mir was zum Einlesen von Daten aus einem PISO-Schieberegister gestrickt. Zunächst mit einer Schleifenvariable initialisiert mit j= 7 und j-- am Schleifenende, während hereinkommende Bits nach einer Maskierung mit (1<<j) das Eingangsbyte von links nach rechts füllen. Dabei reagiert der Controller jedoch subjektiv deutlich langsamer auf externe Ereignisse. Gut, zunächst lag es an einem Gewohnheits-j++ , sodass die Schelifendurchläufe in die falsche Richtung gezählt wurden, aber auch korrigiert erscheint mir die Version langsamer zu laufen als eine inkrementierende Schleifenvariable und Start- Maskierung mit 0b10000000, welche dann um j nach rechts geschoben wird?!
Völlig anderes Thema - was hat es mit Variablentypen wie "uint8_t" auf sich verglichen mit der 08/15-Variante "int"? Was ist der Vorteil der längeren Form, solange man im 8-bit-Bereich bleibt? Ist "int" auf 8 bit beschränkt oder einen anderen Standardwert oder entscheidet da der Compiler nach Gefühl, wieviel Platz er dafür vorsieht?
Woher stammt das Bit, mit dem bei Verschiebeoperationen die Randposition aufgefüllt wird? hatte eigentlich zunächst ein Füllen mit Nullen erwartet, das scheint aber nicht immer der Fall zu sein. wird da das carry-bit mit reingezogen? ist das 'nen zufallswert? (Sofern es sich nicht aus "int" = länger als 8 Bit erkärt)
|
BID = 689604
hajos118 Schreibmaschine
Beiträge: 2453 Wohnort: Untermaiselstein
|
Zitat :
Teletrabi hat am 12 Mai 2010 05:19 geschrieben :
|
Völlig anderes Thema - was hat es mit Variablentypen wie "uint8_t" auf sich verglichen mit der 08/15-Variante "int"? Was ist der Vorteil der längeren Form, solange man im 8-bit-Bereich bleibt? Ist "int" auf 8 bit beschränkt oder einen anderen Standardwert oder entscheidet da der Compiler nach Gefühl, wieviel Platz er dafür vorsieht?
|
int (uint) wird üblicherweise auf die interne Länge der Register des Prozessor gesetzt - wenn der Compiler explizit für einen Prozessor entwickelt wurde.
Im Falle von gnu - basierten Compilern ist ein int jedoch (meist) 16 bit breit - belegt also bei 8bittigen µC 2 Register und benötigt entsprechend mehr Zeit bei Berechnungen ect.
mit der Version "uint_8t" wird explizit ein 8 Bit breiter Datentyp definiert, welcher auch nur 1 Register im µC benötigt - und damit auch bei Berechnungen entsprechend "schneller" ist.
_________________
Interpunktion und Orthographie dieses Beitrags sind frei erfunden.
Eine Übereinstimmung mit aktuellen oder ehemaligen Regeln wäre rein zufällig und ist nicht beabsichtigt.
Wer einen Fehler findet, darf ihn behalten!
|
BID = 689629
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Zitat :
| Völlig anderes Thema |
Dann mach doch bitte einen neuen Thread mit entsprechender Überschrift auf.
Auch die vorangegangene Frage hatte schon nichts mehr mit mit dem ursprünglichen Thema zu tun.
Deshalb hier geschlossen.
|
|
Zum Ersatzteileshop
Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum
Datenschutz
Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland
gerechnet auf die letzten 30 Tage haben wir 22 Beiträge im Durchschnitt pro Tag heute wurden bisher 0 Beiträge verfasst © x sparkkelsputz Besucher : 182686771 Heute : 84 Gestern : 7485 Online : 429 7.1.2025 0:27 3 Besucher in den letzten 60 Sekunden alle 20.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0712661743164
|