Pins schnell schalten

Gast #181534
Moin Moin

Bin gerade dabei mir einen Digitalen Rechteckgenerator zu bauen.
Nun suche ich eine schnelle Möglichkeit einen Pin zu tickern.

Mit einem 10MHz Quarz komme ich mit diesem Code...

for(;;)
PORTD = ~PORTD;

...auf ca. 1MHz an PORTD.

Allerdings brauche ich das Ganze für nur einen Pin an PORTD.
Mit folgendem Code funktionert es zwar aber die Frequnez fällt auf ca.
110KHz ab.

for(;;){
  if((PORTD&0x40)==0x00)
    PORTD += 0x40;
  else
    PORTD -= 0x40;
}

Wie schaffe ich es nun den Pin möglichst schnell zu tickern ?

MFG
Timo O.
Gast
Soll der Controller nichts anderes machen?
Noch schneller geht es unter Umständen mit inline-Assembler. Ich an
deiner Stelle würde mir einen externen Schaltkreis dafür nehmen. Bei
dir darf in einem späteren Programm weder ein Interrupt noch Code in
die Hauptschleife kommen, ohne das es dir das Signal versaut.
Welchen Frequenzbereich musst du abedecken?
Gast
Ich würde versuchen das ganze in assembler zu schreiben.
aber möchtest du nicht lieber einen timer mit pwm verwenden?

hab schon lange keinen AVR mehr programmiert, kann es sein das er den
wert 0x40 jedes mal aus dem speicher liest? oder ist der schon im
befehl integriert? wenn nicht würde ich ein register nehmen mit dem
wert, dadurch sparst du dir nochmals einen cyclus in dem du nur eine
fixe variable ladest.

for(;;){
    PORTD += 0x40;
    nop();
    nop();
    PORTD -= 0x40;
}
so hast du zwar eine längere auszeit als einzeit, aber das könntest du

mit ein paar nop angleichen.


allerdings wenn dir jetzt ein interrupt in die quere kommt kannst du
deine frequenz vergessen. bzw. kannst du derzeit nichts nebenbei
machen.

mfg Azrael
Gast
Erstmal danke für eure Antworten.
Die Idee von Azrael ist natürlich top. Das ich da nicht selber drauf
gekommen bin. So eine Schande. :-(
Aber das Posting von Jörg beschreibt genau das wonach ich gesucht
habe.
Mit diesem befehl komme ich wieder auf ca. 1MHz.

Besten Dank
Timo O.
Gast
> müsste einen Takt (compiliert mit -O2) von 3,33MHZ erzeugen wenn der
> AVR mit 10MHZ getaktet wird.

Ich komme dabei auf 6 Takte pro Iteration (CBI,CBI,BRxx brauchen je 2
Takte). Ergibt bei 10MHz Takt also 1,67MHz. Besser wird's mit

    h = PIND | 1<<6;
    l = PIND & ~(1<<6);
    for (;;) {
      PORTD = h;
      PORTD = l;
    }

da komme ich auf 4 Takte = 2,5MHz.
Gast
Hmm, du hast Teilweise recht. Ich hatte cbi und sbi mit 1 Takt
Ausführungszeit in Erinnerung, sind aber wie du sagst zwei. Dann müsste
meine Routine 2MHZ erzeugen. Der Compiler scheint die Schleife teilweise
zu entrollen, so dass sbi-cbi zwei mal ausgeführt werden bevor der
Sprung erfolgt. Wenn der Compiler deinen Quelltext genau so entrollt,
müsste deiner dann aber 3,33MHZ ausgeben.
Gast
Also, im Datenblatt zu meinem uC steht bei den Timern, dass man 1/4 vom
Clock maximal erhalten kann; das wären bei meinen 20MHz immerhin 5MHz.
Aber eben mit dem Timer und natürlich dem dazu gehörigen
Timer-Ausgangs-Pin.

Weiterer Vorteil der Timer ist, dass sie vollkommen autonom laufen; sie
benötigen nur beim ersten Verwenden die Initialisierung. Danach ist die
CPU frei für andere Aufgaben.

Stephan.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.