Forum: Compiler & IDEs Ports mit EODER verknüpfen


von Carlos (Gast)


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?

von Lord Z. (lordziu)


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!

von Stefan E. (sternst)


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.

von Chris L. (kingkernel)


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!

von Carlos (Gast)


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?

von Carlos (Gast)


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?

von Chris L. (kingkernel)


Lesenswert?

Die Eingangsregister, ja! Die Ausgangsregister mit PORTx
PINx nur bei Pin = Eingang!

von Lord Z. (lordziu)


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:
1
uint8_t pc0_aktiv = PINC & (1<<PC0);
2
uint8_t pc1_aktiv = PINC & (1<<PC1);
3
4
if(pc0_aktiv ^ pc1_aktiv)
5
{
6
    PORTD |= (1<<meinPin);
7
} else 
8
{
9
    PORTD &= ~(1<<meinPin);
10
}

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

von Carlos (Gast)


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

von ... (Gast)


Lesenswert?

Daniel war schon nah dran :)
1
uint8_t pc0_aktiv = (PINC & (1<<PC0)) != 0;
2
uint8_t pc1_aktiv = (PINC & (1<<PC1)) != 0;
3
4
if(pc0_aktiv ^ pc1_aktiv)
5
{
6
    PORTB |= (1<<meinPin);
7
} else 
8
{
9
    PORTB &= ~(1<<meinPin);
10
}

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.