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?
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!
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.
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!
>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?
>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?
Die Eingangsregister, ja! Die Ausgangsregister mit PORTx PINx nur bei Pin = Eingang!
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.