Ports mit EODER verknüpfen

Gast #1619352
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?
#1619639
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!
Gast #1619700
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?
Gast #1619706
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?
#1619751
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.
Gast #1619913
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
Gast #1619973
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren