ATMega328 553 Takte warten mit Inline Assembler

Gast #4095079
Hi,

ich würde gerne eine genaues Delay haben.
Man könnte dazu einen Timer nutzen aber ich würde gerne mal sehen wie 
man das mit Inline Assembler schafft.
553 x NOP würde gehen :) aber da gibt es sicherlich bessere 
Möglichkeiten die auch weniger Speicher verbrauchen.
Ich brauche also eine Warteschleife in ASM die ich C-Code nutzen kann 
(Inline Assembler).
Ich hoffe das hier schon mal jemand gemacht.

Danke
UnendlichHoherPotentialtopf
Gast #4095131
So ganz klappt es noch nicht.
Der Compiler schmeißt noch einen Fehler.
C:\Temp\ccTCJIsi.s:59: Error: garbage at end of line
1
asm volatile ("ldi  R24, HIGH(552)" "\n\t"
2
"ldi  R24, LOW(552)" "\n\t"
3
"WGLOOP0:  dec  R24" "\n\t" 
4
"brne WGLOOP0" "\n\t"
5
"nop");

UnendlichHoherPotentialtopf
Gast #4095401
Drei Fehler habe ich noch gefunden :)
Den High Wert muss ich in Register 25 schreiben.
HIGH und LOW mag der Compiler nicht.
sbiw anstatt dec.
Jetzt sieht das so aus
1
asm volatile ("ldi  R24, 0x28" "\n\t"
2
"ldi  R25, 0x02" "\n\t"
3
"WGLOOP1:" "\n\t" 
4
"sbiw  R24" "\n\t" 
5
"brne WGLOOP1" "\n\t"
6
"nop");

So geht das zwar durch den Compiler aber die LED ist fast aus.
Bei einem delay von 553 Takten (_delay_loop_2(553)) sieht man ein 
schönes Pulsen.

hier der ganze code
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <util/delay_basic.h>
4

5
void pwm_init()
6
{
7
    // Init TCCR0
8
    TCCR0A |= (1<<WGM00)|(1<<COM0A1)|(1<<WGM01);
9
    TCCR0B |= (1<<CS00);
10
    // PD6 als Ausgang
11
    DDRD |= (1<<PD6);
12
}
13
  
14
void main()
15
{
16
    uint8_t brightness;
17
  
18
    pwm_init();
19
  
20
    while(1)
21
    {
22
        // increasing brightness
23
        for (brightness = 0; brightness < 255; ++brightness)
24
        {
25
            OCR0A = brightness;
26
  
27
            //_delay_loop_2(553);
28

29
            asm volatile ("ldi  R24, 0x28" "\n\t"
30
            "ldi  R25, 0x02" "\n\t"
31
            "WGLOOP0:" "\n\t" 
32
            "sbiw R24,1" "\n\t"
33
            "brne WGLOOP0" "\n\t"); 
34
        }
35
 
36
        // decreasing brightness
37
        for (brightness = 255; brightness > 0; --brightness)
38
        {
39
            OCR0A = brightness;
40

41
            //_delay_loop_2(553);
42

43
            asm volatile("ldi  R24, 0x28" "\n\t"
44
            "ldi  R25, 0x02" "\n\t"
45
            "WGLOOP1:" "\n\t" 
46
            "sbiw R24,1" "\n\t"
47
            "brne WGLOOP1" "\n\t");
48

49
        }
50
    }
51
}

Jetzt kommt es aber total unerwartet für mich.
Wenn ich in der For Schleife (egal ob in decreasing oder increasing) das 
_delay_loop_2(553) nutze und den ASM Code auskommentiere funktioniert es 
auch.

UnendlichHoherPotentialtopf
Gast #4095431
S. Landolt schrieb:
> sbiw und brne benötigen jeweils 2 Takte.

OK, das habe ich geändert aber das ändert nichts an dem Problem, dass 
wenn ich beide ASM Teile aktiv habe, die LED nicht pulst sondern einfach 
nur ganz schwach glimmt.

UnendlichHoherPotentialtopf
Gast #4095450
So jetzt funktioniert es aber ein Erklärung habe ich nicht.
Also ich hatte bei Optimazation immer -Os.
Jetzt habe ich -O 0 genommen und jetzt funktioniert es.
Sieht für mich aus als würde der Compiler das wegoptimieren.
Warum aber nur wenn ich es zweimal nutze?

UnendlichHoherPotentialtopf

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 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.