www.mikrocontroller.net

Forum: Compiler & IDEs Pin an PortC


Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich finde den Fehler in folgendem Code einfach nicht:

DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2);  //Port C Ausgänge

PORTC |= (1<<PC2);

Der Pin geht nicht auf High :-(

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist da der jtag drauf und muß deaktiviert werden

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist ein ATmega8

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird der genannte Code denn überhaupt erreicht?  Vielleicht startet ja
deine Applikation immer wieder von Neuem, weil ein Interrupt zieht,
der keinen Vektor definiert hat?

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int main(void) {

  DDRB = (1 << DDB1) | (1 << DDB2) | (1 << DDB3);

  DDRC = (1 << DDC0) | (1 << DDC1) | (1 << DDC2);

  PORTC |= (1<<PC2);
...

Natürlich wird er erreicht.
Interrupts gibt's im Programm keine und die Beschaltung habe ich auch
schon überprüft :-(

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann ist dein Ausgangstreiber von PORTC2 kaputt...

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Errm, AVcc hast du aber beschaltet, ja?

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVCC ist beschaltet.
Wie muss ich die Fusebits setzen?
Kann eines davon Einfluss auf den ADC Port haben?
Oder muss man noch irgendwas in einem ADC Kontrollregister einschalten
/ ausschalten?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, die Fusebits haben keinen Einfluss auf den ADC.  Da du an den
ADC-Registern nichts getan hast, ist das auch alles erstmal
abgeklemmt.

Wenn wirklich das von dir genannte Einfachst-Progrämmchen das nicht
tut (und nicht gerade deine externe Hardware einen Kurzschluss am
Portpin hat ;-), dann ist dein Controller breit.

Autor: Stefan Sczekalla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du alternativ mal einen anderen Port, bzw einen anderen Pin
probiert ?

Grüße,

Stefan

Autor: Alexander (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe genau das gleiche Problem.
Wenn ich allerdings nachdem setzen des Pins eine Warteschleife aufrufe,
ist der Pin solage gesetzt, wie diese Schleife braucht.

Kann diese Verhalten bei verschiedenen Pins nachvollziehen und bin echt
verzweifelt. Es ist als ob er vergessen würde die Spannung am Pin zu
halten, da er was anderes zu tun bekommt.

mfg
Alex

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

tja die main routine sollte immer eine endlosschleife sein. Der µc
rennt ins nirvana ohne richtigen quellcode.

mfg
dirk

Autor: Alexander (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das Problem an der Sache ist allerings, dass er davor und danach
weitermacht als ob es den Befehl "Pin auf HIGH" nie gegeben hätte.
Endlosschleife ist natürlic drin. Was wär das denn sonst für n
sinnloses Programm??

mfg
Alex

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider bin ich noch ablosluter Anfänger in C...
Doch gestern hatte ich ein ähnliches Problem. So wie es aussieht willst
Du ja den dritten Pin an Port C (PC2) auf high setzen, oder?

PORTC |= (1<<PC2);

Ich bin mir jetzt leider nicht mehr sicher ob es so funktioniert, da
ich meinen Code nicht hier habe. Aber ein versuch ist es Wert...
(oder die Profis fangen zum schimpfen an... :-))

PORTC |= (4<<PC2);
(der 3. Pin wird mit einer binären 4 auf high gesetzt)

Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das funktioniert bei mir:

#include "stdafx.h"

#define PC2 1

int main(void)
{
  char portc = 0;
  portc |= (2 << PC2); // Die 2 setzt die Bitposition des PORTC fest
  printf("\nportc = %X\r\n", portc);
  return 0;
}

Ich habe das kleine Program soeben in MS C++ getestet und funktioniert.
PORTC wird als 4 ausgegeben.

Gruss,
Gerhard

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhhh....
Eigentlich dachte ich der erste Pin wird mit 1, der zweite mit 2, der
dritte mit 4 angesteuert.
Aber vielleicht fängst Du ja nicht bei PC0 sondern bei PC1 zum zählen
an...

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> PORTC |= (4<<PC2);
Pfui ;-)

PORTC |= (1<<PC2); ist schon richtig, wenn PC2 den Wert 2 hat. Damit
wird die "1" (die links in "1<<PC2" steht) um 2 (Binär-)Stellen (da
PC2 den Wert 2 hat) nach links geschoben. Damit ergibt wird dann aus
(1<<PC2) -> die Zahl 0b00000100 =0x04 =4dez. Das wird dann auf PORTC
verodert und schon passt das.

> portc |= (2 << PC2); // Die 2 setzt die Bitposition des PORTC fest
Riesenzufall! Dein 'Prinzip' funktioniert so aber wirklich nur für
PC4 - nicht bei anderen Bitpositionen. Und wieso schreibst du PC2 in
den Sourcecode obwohl du PC4 setzen willst? Unlogisch. Wie das richtig
geht, siehe Erklärung oben.

> Aber vielleicht fängst Du ja nicht bei PC0 sondern bei PC1 zum zählen
an...
Das, oder er hat AGND und/oder Aref nicht angeschlossen?!? Anschluss
von AVCC hat ja oben schon bestätigt.

----, (QuadDash).

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich zitiere mich mal selbst:
> Und wieso schreibst du PC2 in den Sourcecode obwohl du PC4 setzen
willst?

Ich habe erst eben gesehen, daß du noch was ganz seltsames defined
hast:
> #define PC2 1
damit setzt du PortC auf 0x04 (wie du schreibst), nicht PORTC4 auf 1
(wie ich fälschlicherweise annahm). Aber das ist ja genauso verbockt
und führt nur zu Problemen, da dein Konzept nicht durchgängig
konsistent ist. (z.B. Wie würdest du PC0 auf 1 setzen?). Also lieber
die 'mitgelieferten' PCn defines belassen.
Aber wenn du von PortC nur das Bit2 (=PC2) setzen willst, dann kannst
du auch gleich PORTC|=0x04; schreiben, dann hat sich die Bitschieberei
sowieso erledigt.
Das Bitschieben hat sich doch nur eingebürgert, da es leichter zu lesen
ist, da ja der PinName drin vorkommt und man nicht weiter nachdenken
muß.

----, (QuadDash).

Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt sehe ich meinen Fehler - Danke!. Da habe ich aber sehr  blamiert!
PCx bestimmt die Bitposition, wo x dann zwischen 0 und 7 legen darf. so
muesste es gehen:

PORTC |= (1 << Portbitnummer);
Ruecksetzen
PORTC &= (1 << ~Portbitnummer);

Ich setze meine Bits sonst auch wie bei Dir genannt: PORTC |= 0x04;
oder ruecksetzen PORTC &= ~0x04; . Ich mag das Bitschieben auch nicht.
Gruss,
Gerhard

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon fast gut.
Beim Rücksetzen noch die Tilde an die richtige Stelle:
PORTC &= ~(1 << Portbitnummer);

Beispiel: Portbitnummer = 4:
 (1 << Portbitnummer)  entspricht dann 0x10 hex oder 00010000 binär
~(1 << Portbitnummer)  entspricht dann 0xEF hex oder 11101111 binär
Im PORTC wird durch das &= also Bit 4 gelöscht, alle anderen behalten
den alten Wert.

Ich benutze übrigens lieber das Makro _BV() (Bit-Value), das sieht dann
nicht so kryptisch aus.

Falls Du doch lieber den direkten Weg nehmen willst, also:
PORTC |= 0x04;
dann ersetze 0x04 möglichst durch
#define Portbitmaske 0x04  // nur 1* machen, am Besten in einem.h-File
PORTC |= Portbitmaske;

oder besser (Bsp. zum Setzen einer LED):
#define Ledbitmaske 0x04
#define Ledport     PORTC
Ledport |= Ledbitmaske;

Falls Du jemals eine Änderung in Deiner Hardware hast, dann ist die
Anpassung dann sehr einfach - nur an einer Stelle muss geändert
werden.

Viele Grüße, Stefan

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na bevor ich "Ledport |= Ledbitmaske;" schreiben würde, würde ich eher
zu:
SetLed(n);
greifen. Wobei:
#define SetLed(x)     (x ? PORTC|=0x04 : PORTC&=~0x04)
ggf. die beiden Ausdrücke nochmal auflösen/definen...

Oder vom "Compilerhersteller" fordern, daß er Bitvariablen für
Portzugriffe bereitstellt... :-) Aber das hatten wir ja alles schon...
dann wärs nämlich nur:
#define SetLed(x)     (PORTC_PC1=x)
oder so ähnlich.

_BV() finde ich persönlich unschön, da ich das bisher nur bei
AVR-GCC-Code gesehen habe...
Aber wie immer im Leben... alles Geschmackssache.

----, (QuadDash).

Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

nochmals vielen Dank zum Thema und der Richtigstellung meines letzten
Fehlers (Gebrauch der TILDE beim Ruecksetzen und Bitschieben). Zu
meiner Entschuldigung moechte ich bemerken, dass ich bis vor kurzem nur
mit dem PIC CCS Compiler gearbeitet habe, wo direkte Portoperationen
eingebaut sind.

Mann kann natuerlich wie beim AVR die PORTS aehnlich ansprechen wenn
man will. Folgend ist ein kurzes Beispiel vom CCS Compiler:

Um ein LED einzuschalten braucht man nur:

#use fast_io(b)
#define PORT_B_MASK  0b11111110  // 0=Output, 1=Input

#define LED PIN_RB0  // Led zwischen PIN_B0 und 5V angeschlossen
#define EIN 0
#define AUS 1

void main()
{
    set_tris_b(PORT_B_MASK);  // Port B Datenrichtungsspeicher

    // Beispiele einiger eingebauten Port Funktionen
    output_low(LED);    // LED ein
    delay_ms(100);
    output_high(LED);   // LED aus
    delay_ms(100);
    output_bit(LED, EIN);
    output_bit(LED, ON);
    delay_ms(100);

    while (1)
    {
        output_toggle(LED); // LED langsam blinken (Normal wuerde ich
                            // das mit Interrupt und timer machen)
        delay_ms(500);
    }

}

Warscheinlich kennt Ihr das sowieso. Wie gesagt das mit dem Bitschieben
ist mir ungewohnt.

Viele Gruesse,
Gerhard

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.