www.mikrocontroller.net

Forum: Compiler & IDEs Ports mit EODER verknüpfen


Autor: Carlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mich gerade in C. Ich habe einen Rechteckgenerator laufen 
der zwei Rechtecke am PORTC erzeugt, zusammen mit einem externen PLL.
PINC0 hat die halbe Frequenz von PINC1. Beide Ports möchte ich intern 
mit einem logischem EODER verknüpfen um ein um 90 Grad versetztes 
Rechteck am PORTB zu bekommen. Ich bekomme aber immer nur zwei 
phasengleiche Rechtecke am Ausgang. Hier der Programmauszug:

.............

Freq=TCNT0;

if(Freq >= 128){
   PORTC &= ~(1<<PC1);
    }
else
   {
  PORTC |= (1<<PC1);
   }


if(Freq >= 256){
if(PINC & (1<<PC0))
   {
  PORTC &= ~(1<<PC0);
   }
else
  {
  PORTC |= (1<<PC0);
  }

PORTB ^= PC0 ^ PC1; //Hier sollte ein um 90 Grad Phasenverschobenes
                    //Rechteck zu PC0 rauskommen!

........
Was mache ich falsch?

Autor: Lord Ziu (lordziu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass mich mal versuchen zu verstehen, was du eigentlich willst...

Carlos schrieb:
> Hallo,
>
> ich versuche mich gerade in C. Ich habe einen Rechteckgenerator laufen
> der zwei Rechtecke am PORTC erzeugt, zusammen mit einem externen PLL.

Du schaltest also zwei PINS(!) des Portes C ein und aus, um somit an den 
Pins ein Rechtecksignal zu erzeugen?

> PINC0 hat die halbe Frequenz von PINC1. Beide Ports möchte ich intern
> mit einem logischem EODER verknüpfen um ein um 90 Grad versetztes
> Rechteck am PORTB zu bekommen.

Und wo am Port B? Du hast da 8 Pins zur Verfügung.

> .............
>
> Freq=TCNT0;
>
> if(Freq >= 128){
>    PORTC &= ~(1<<PC1);
>     }
> else
>    {
>   PORTC |= (1<<PC1);
>    }
>
>
> if(Freq >= 256){

Ich kenne deinen Controller nicht, aber bist du sicher, dass TCNT0 
jemals größer 255 werden kann? (8-bit oder 16-bit Counter)

> if(PINC & (1<<PC0))
>    {
>   PORTC &= ~(1<<PC0);
>    }
> else
>   {
>   PORTC |= (1<<PC0);
>   }
>
> PORTB ^= PC0 ^ PC1; //Hier sollte ein um 90 Grad Phasenverschobenes
>                     //Rechteck zu PC0 rauskommen!

Das ist natürlich Käse wenn du einen PIN(!) schalten willst. Schau dir 
mal in einer Logiktabelle an, was dabei rauskommt.

>
> ........
> Was mache ich falsch?

Als erstes würde ich sagen, dass du gar nicht weißt, wie Ports und Pins 
zusammenhängen und wie man sie benutzt (obwohl in den if-Abfragen hast 
du es ja richtig gelöst). Daher -> AVR-Tutorial lesen!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Carlos schrieb:

> Was mache ich falsch?

Zu denken, dass PC0 und PC1 den Zustand der Portpins widerspiegeln 
würde. Das sind nur Zahlen, die die Pin-Nummer angeben.

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PC0 und PC1 sind nur defines, die angeben, womit du die Pins ansprechen 
kannst. Die werte sind Statisch udn haben keinen Bezug auf den Zustand 
der Pins!

Autor: Carlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Du schaltest also zwei PINS(!) des Portes C ein und aus, um somit an den
>Pins ein Rechtecksignal zu erzeugen?
Richtig. Ein PIN (PC0)geht zum Eingang an einen externen PLL-Teiler 
(CD4046). Der Andere (PC1)an den Ausgang des PLLs.

>Und wo am Port B? Du hast da 8 Pins zur Verfügung.
Egal. Darf irgendeiner sein.

>Ich kenne deinen Controller nicht, aber bist du sicher, dass TCNT0
>jemals größer 255 werden kann? (8-bit oder 16-bit Counter)
Ein Atmega8. TCNT0 kann natürlich größer werden. Dafür gibt es eine IR 
in meinem Programm die den Überlauf zählt und später mit dem gezählten 
Wert 'verrechnet'. Aber für meine gestellte Frage scheint es mir 
unwichtig zu sein.

>Das ist natürlich Käse wenn du einen PIN(!) schalten willst. Schau dir
>mal in einer Logiktabelle an, was dabei rauskommt.
Ich verstehe nicht was beim An/Ausschalten Eines PORT-Pins Käse sein 
soll? Wenn ich die besagten Pins außerhalb direkt an ein EX-OR (z.B. 
CD4030) anschließe, funktioniert ja alles wie vorgesehen.

Ich missbrauche den AVR nur als Teiler bzw. 8-bit Addierer für eine 
externe PLL-Schaltung z.B. CD4046 und möchte mir dadurch ne Menge 
CD40..-Bausteine einsparen.

Meine Frage: ist es möglich den Schaltzustand der PortPins auszulesen, 
sie intern logisch verknüpfen und dann das Resultat auf einen anderen 
freien Port ausgeben?

Autor: Carlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Zu denken, dass PC0 und PC1 den Zustand der Portpins widerspiegeln
>würde. Das sind nur Zahlen, die die Pin-Nummer angeben.

>PC0 und PC1 sind nur defines, die angeben, womit du die Pins ansprechen
>kannst. Die werte sind Statisch udn haben keinen Bezug auf den Zustand
>der Pins!

Dann ließt man also die Ports mit PINCx aus?

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Eingangsregister, ja! Die Ausgangsregister mit PORTx
PINx nur bei Pin = Eingang!

Autor: Lord Ziu (lordziu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Carlos schrieb:
>>Das ist natürlich Käse wenn du einen PIN(!) schalten willst. Schau dir
>>mal in einer Logiktabelle an, was dabei rauskommt.
> Ich verstehe nicht was beim An/Ausschalten Eines PORT-Pins Käse sein
> soll? Wenn ich die besagten Pins außerhalb direkt an ein EX-OR (z.B.
> CD4030) anschließe, funktioniert ja alles wie vorgesehen.

Nicht die Sache ansich ist Käse, sondern was du da geschrieben hast.

Ich drösle es mal ein bisschen für dich auf:
uint8_t pc0_aktiv = PINC & (1<<PC0);
uint8_t pc1_aktiv = PINC & (1<<PC1);

if(pc0_aktiv ^ pc1_aktiv)
{
    PORTD |= (1<<meinPin);
} else 
{
    PORTD &= ~(1<<meinPin);
}

Hab ich nur eben schnell zusammengeklöppelt, können durchaus 
Flüchtigkeitsfehler drin sein. Dient in erster Linie deinem Verständnis.

Autor: Carlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daniel,

so wie du geschrieben hast sieht es gut aus (auch wenn es nicht in 
meiner Schaltung funktioniert). Ich werde mich ein bisschen mehr mit 
dieser Programmiersprache befassen.
Auf jeden Fall danke an allen. Wenn ich Neuigkeiten haben sollte melde 
ich mich wieder.
Gruß Carlos

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel war schon nah dran :)
uint8_t pc0_aktiv = (PINC & (1<<PC0)) != 0;
uint8_t pc1_aktiv = (PINC & (1<<PC1)) != 0;

if(pc0_aktiv ^ pc1_aktiv)
{
    PORTB |= (1<<meinPin);
} else 
{
    PORTB &= ~(1<<meinPin);
}

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.