Forum: Mikrocontroller und Digitale Elektronik Assembler Code in C


von Dimitris a. (dimitris)


Lesenswert?

Hallo Miteinander,

Hallo ich bin neu hier und mit der Hoffnung dass ihr mir helfen könnt.
obwohl das ich von Programmieung nicht so viel verstehen kann habe ich 
mir vor genommen in C-Code ein Assembler Code was ich hier gefunden habe 
zu integrieren.  Beitrag "AtTiny13 PWM Lauflicht"

habe schon im forum gelesen und davon weis ich teilweise ein Programm 
teilchen integrieren kann. Aber ein ganzes Programm unter Switch 
Case...???

Was meint ihr, ist es überhaupt möglich oder soll ich es sein lassen?

Vielen Dank im voraus.
Dimi

: Verschoben durch Moderator
von Oliver (Gast)


Lesenswert?

Ich sach mal, die Antwort lautet ja.

Oliver

von Dimitris a. (dimitris)


Lesenswert?

Danke für schnelle Antwort.

Wenn Ja, Wie? und was soll ich bei integration beachten?

Danke

von Fred S. (kogitsune)


Lesenswert?


: Bearbeitet durch User
von deathfun (Gast)


Lesenswert?

Hallo Dimitris,

gehen wird es schon - ob es hier sinnvoll ist bleibt aber zu bezweifeln.



Wenn du schon mit uC anfangen möchtest rate ich aber dringend zu dem 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial.
Was du suchst ist ein einfaches Lauflicht welches du zu hunderten hier 
im Forum, und bei Google,  auch in C finden kannst. Ich rate dir einfach 
bei einer Sprache zu bleiben und Assembler ist sicher eine gute Sprache, 
aber vielleicht nicht ganz einfach für Anfänger zu verstehen wie C.



Es ist wirklich alles andere als kompliziert und du hast davon deutlich 
mehr von als wenn du einen Code den du nicht genau verstehst mir einer 
Technik die du nicht beherrscht in einer gänzlich anderen Sprache 
aufrufst und hoffst, dass es irgendwie wohl funktioniert.



Gruß
Deathfun

PS:
http://www.google.de/cse?cx=partner-pub-1202612203358489%3Ajaffbdxotov&ie=UTF-8&q=Lauflicht&sa=Suche#gsc.tab=0&gsc.q=Lauflicht&gsc.page=1
https://www.google.de/search?q=atmega8+C+Lauflicht&ie=utf-8&oe=utf-8&rls=org.mozilla:de:official&client=firefox-a&gws_rd=cr&ei=wm1WUv_xN8_GswbHs4CYDg

von Oliver (Gast)


Lesenswert?

Dimitris ahoi schrieb:
> Wenn Ja, Wie?

Wie meine Vorposter schon schrieben: Ja, es geht, und ja, du sollst es 
sein lassen.

Oliver

von Dimitris a. (dimitris)


Lesenswert?

Hallo Leute,

Danke für eure antworten.

ich versuche es Ja seit Sonntag die ASM code zu integrieren klappts aber 
nicht. Es gibt Ja so viele punkte das ich nicht vertehen kann.

Aber dieser ASM code hat super sanfte überlauf und gefehlt. Es gefelt 
mir richtig gut. Leider in Assembler und nach menrere versuche habe ich 
nicht in C hin gekrigt. Die Assembler code könnte ich nicht lesen.

Gruss
Dimi

von Fred S. (kogitsune)


Lesenswert?

Warum möchtest Du das Programm aus einem C Programm aufrufen? Weshalb 
übernimmst Du nicht einfach das Assembler-Programm "solo"? Soll das 
Assembler-Programm als eine mehrerer Optionen laufen? Unter 
Berücksichtigung der Fakten im oben von mir genannten 3. Link  lässt 
sich das Assembler-Programm sicher so umschreiben, dass es aus C 
aufrufbar ist.

Ich schließe mich ansonsten den anderen an: Es ist bestimmt sinnvoll, Du 
lernst Assembler (um das Programm als *.S umzuschreiben oder um es zu 
verstehen und nach C zu portieren) -- oder Du bleibst bei C und 
versuchst zu begreifen, wieso Dein C Programm nicht optimal läuft.

von Dimitris a. (dimitris)


Lesenswert?

Hi,

weil ich in C programmieren kann und nicht in Assembler.
Natürlich wenn ich Assembler könnte wäre alles anderes als jetzt. 
Ausserdem eine Programmier sprace zu lernt man nicht in kürze zeit.
Ich tue mich sowieso mit C zuschwer.

Hab mich an euch gewendet mit der Hoffnung dass ihr mir Helfen könnt.
Ich denke für das C und Assemler könner kein Problem in C zu schreiben.
Ich will nicht anderes als zu vertehen wie in C dieser assembler code zu 
realisieren.

Danke
Dimi
1
.include "tn13def.inc"
2
3
.def TEMP   = r16
4
.def STORE  = r17     ; enthält Port-Wert für die aktuelle LED
5
.def STORE2 = r18     ; enthält Port-Wert für die nächsten LED
6
.def OUTER  = r19     ; fading Zähler
7
.def INNER  = r20     ; PWM Zähler
8
9
.equ wait = 20       ; Rotation geschwindikkeit
10
11
    ; I/O setup
12
    ; =========
13
  ldi TEMP, 30      ; switch PB0..PB5 to output
14
    out DDRB, TEMP
15
    ldi STORE,  30    ; Last Startwert (LED0 on)
16
    ldi STORE2, 29    ; Last nächste wert (LED1 on)
17
18
LOOP:
19
    inc  INNER         ; innere zähler Incrementieren
20
  cpi  INNER, wait  ; haben wir den maximalen WERT ereeicht?
21
22
  brne GO_ON         ; wenn ja, erhöhe die äußere
23
24
    clr  INNER         ; innere Zähler zurücksetzen
25
    inc  OUTER         ; erhöhe äußere(outer) Zähler
26
    cpi  OUTER, wait
27
    breq NEXT_PHASE    ; wenn es überläuft, gehe zur nächsten LED
28
29
GO_ON:
30
    cp   INNER, OUTER   ; inner > outer?
31
    brsh THIS_LED       ; if yes, the current LED needs to be on
32
33
    mov  TEMP, STORE2                            ; <-----
34
    com  TEMP                                     ; <-----
35
    out  PORTB, TEMP    ; else the next one       ; <-----
36
    rjmp LOOP           ; and start over
37
38
39
THIS_LED:
40
    mov  TEMP,STORE                             ; <----
41
    com  TEMP                                     ; <----
42
    out  PORTB, TEMP    ; switch on current LED   ; <----
43
    rjmp LOOP           ; and start over
44
45
46
47
NEXT_PHASE:
48
    clr  OUTER          ; Zähler reset
49
    mov  STORE, STORE2  ; nächste LED
50
51
    lsl  STORE2         ; aktuelle wert verschieben
52
    ori  STORE2, 1      ; die lsl macht die lsb 0, brauchen wir eine 1
53
    sbrs STORE2, 5      ; Rotieren
54
    ldi  STORE2, 30     ; Wenn Ja, Lade interne Wert
55
    andi STORE2, 31     ; Maske Bit 5 bis 7
56
57
    rjmp LOOP           ; gehe zu anfang

: Bearbeitet durch User
von F. F. (foldi)


Lesenswert?

Dimitris ahoi schrieb:
> Hallo Leute,
>
> Danke für eure antworten.
>
> ich versuche es Ja seit Sonntag die ASM code zu integrieren klappts aber
> nicht. Es gibt Ja so viele punkte das ich nicht vertehen kann.
>
> Aber dieser ASM code hat super sanfte überlauf und gefehlt. Es gefelt
> mir richtig gut. Leider in Assembler und nach menrere versuche habe ich
> nicht in C hin gekrigt. Die Assembler code könnte ich nicht lesen.
>
> Gruss
> Dimi

Um ASM richtig verstehen zu können, musst du auch wissen wie der µC 
funktioniert, wie die Hardware zusammen arbeitet.

Da ist es gut, wenn du dich zunächst auf einen µC "einschießt" und 
lernst das Datenblatt zu verstehen.
Vielleicht mache ich mich jetzt unbeliebt, aber mir hat der Debugger im 
Atmel Studio (ich benutze immer die neuste Version) sehr geholfen die 
Abläufe im µC und die Auswirkungen vom Programmcode besser zu verstehen.
Gleichwohl muss ich sagen, ich lerne immer noch.
Zum erlernen des gesamten Bereiches, habe ich mich auf den Tiny13 
festgelegt. Zum einen, weil der für viele kleinere Sachen ausreichend 
ist, das Datenblatt mit 176 Seiten noch recht überschaubar ist und zum 
anderen ist er recht günstig und man kann "in engen Grenzen" vielleicht 
mehr lernen , wenn man versucht noch hier und da etwas raus zu 
quetschen. Das zum Beispiel, wenn man das Programm oder Teile in 
Assembler schreiben wird.

von Peter D. (peda)


Lesenswert?

Dimitris ahoi schrieb:
> ich versuche es Ja seit Sonntag die ASM code zu integrieren klappts aber
> nicht.

Anfänger denken, es wäre leicht, Assembler in C zu integrieren. Das ist 
ein großer Irrtum!

Schmeiß den Assembler weg und schreibe es neu in C.
Es gibt wirklich nur sehr, sehr, sehr wenige Fälle, wo Assembler 
sinnvoll ist.

Ich hab einmal Assembler einbauen müssen, weil die original 64Bit lib 
(5kB) mir den Flash gesprengt hat.
Da kannst Du Dir ja mal ansehen, wie Assembler aussehen muß, damit er 
mit C zusammen gelinkt werden kann:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=113673&highlight=

von Fred S. (kogitsune)


Lesenswert?

Meine Vorredner haben Recht. Mit C allein bist Du besser beraten. 
Trotzdem lohnt es sich, Assembler zu lernen und vielleicht auch einmal 
ein Projekt mit einem aus C aufgerufenen Assembler-Programm zu 
realisieren.  Für Deinen Fall könnte das so aussehen (schnell 
umgeschrieben, keine Garantie; kompiliert unter Atmel Studio 6):
C (*.c):
1
extern void LEDS(void);
2
3
int main(void) {
4
    LEDS();
5
    while(1);
6
}
Assembler ("*.s"):
1
#ifndef __ASSEMBLER__
2
#define __ASSEMBLER__
3
#endif
4
#include <avr/io.h>
5
6
.global LEDS
7
8
#define TEMP   r18
9
#define STORE  r19     // enthält Port-Wert für die aktuelle LED
10
#define STORE2 r20     // enthält Port-Wert für die nächsten LED
11
#define OUTER  r21     // fading Zähler
12
#define INNER  r22     // PWM Zähler
13
14
#define wait   20       // Rotation geschwindigkeit
15
16
    // I/O setup
17
    // =========
18
LEDS:    ldi TEMP,30      // switch PB0..PB5 to output
19
    out _SFR_IO_ADDR(DDRB), TEMP
20
    ldi STORE,30    // Last Startwert (LED0 on)
21
    ldi STORE2,29    // Last nächste wert (LED1 on)
22
23
LOOP:
24
    inc  INNER         // innere zähler Incrementieren
25
    cpi  INNER,wait  // haben wir den maximalen WERT ereeicht?
26
27
    brne GO_ON         // wenn ja, erhöhe die äußere
28
29
    clr  INNER         // innere Zähler zurücksetzen
30
    inc  OUTER         // erhöhe äußere(outer) Zähler
31
    cpi  OUTER,wait
32
    breq NEXT_PHASE    // wenn es überläuft, gehe zur nächsten LED
33
34
GO_ON:
35
    cp   INNER, OUTER   // inner > outer?
36
    brsh THIS_LED       // if yes, the current LED needs to be on
37
38
    mov  TEMP, STORE2                            // <-----
39
    com  TEMP                                     // <-----
40
    out  _SFR_IO_ADDR(PORTB), TEMP    // else the next one       // <-----
41
    rjmp LOOP           // and start over
42
43
THIS_LED:
44
    mov  TEMP,STORE                             // <----
45
    com  TEMP                                     // <----
46
    out  _SFR_IO_ADDR(PORTB), TEMP    // switch on current LED   // <----
47
    rjmp LOOP           // and start over
48
49
NEXT_PHASE:
50
    clr  OUTER          // Zähler reset
51
    mov  STORE, STORE2  // nächste LED
52
    lsl  STORE2         // aktuelle wert verschieben
53
    ori  STORE2, 1      // die lsl macht die lsb 0, brauchen wir eine 1
54
    sbrs STORE2, 5      // Rotieren
55
    ldi  STORE2, 30     // Wenn Ja, Lade interne Wert
56
    andi STORE2, 31     // Maske Bit 5 bis 7
57
58
    rjmp LOOP           // gehe zu anfang

Du hast uns immer noch nicht erklärt, weshalb Du den Code aus C aufrufen 
willst (außer, dass er Dir gefällt und Du nur C kannst). Obigen Code 
habe ich einfach an die im dritten Link oben angegebenen Vorgaben 
angepassst, so dass er aus C aufgerufen werden kann.
Warnung: Ungetestet!
Du hast auch nicht beschrieben, wie bzw. ob es einen Rücksprung zu C 
geben soll.
Dies dient nur der Illustration und Ermutigung, Assembler und(!) C zu 
lernen.
Für Deinen Fall gilt: Mach es so, wie peda empfiehlt!

: Bearbeitet durch User
von snyder (Gast)


Lesenswert?

In dem Fall ist es ja einfach - in realistischeren Szenarien musst du 
dich auf jedem Fall mit den Aufruf Konventionen vertraut machen. Es ist 
sehr unwahrscheinlich, daß jemand in seinem reinen Assemblercode die 
Register so benutzt wie es dem c Compiler schmeckt.

Kann auch nur unterstützen so was nicht aus Spaß zu machen. Speziell 
wenn man doch c kann ist nicht mal der Zeitaufwand geringer wenn man 
fertigen Assembler Code benutzt.
Wie lange probierst du rum? Eben. Hättest du lieber ein C Projekt 
gestartet und wärst schon efrtig damit.

von Dimitris a. (dimitris)


Lesenswert?

Hi,

bin seit etwa 10 stunden dabei und verstehe immer noch BAHNHOF.

Ein Lauflicht ist in C gar kein Problem aber so ein Schönes wie im ASM 
Programm....

ich versuche in C so schön hin zu kriegen. Leider klappt es nicht. Ich 
verstehe die Logik bei ASM nicht.

Wie soll ich das Programm schreiben damit ich mindestens so schöne 
überlappende Lauflicht habe???

Gruss
Dimi

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Dimitris ahoib im Beitrag #3358829:
> Ich verstehe die Logik bei ASM nicht.


Die Logik eines Programms (der Algorithmus) ist ja nicht "in Assembler" 
oder "in C". Die Logik kann man auch in einer "Pseudosprache" 
ausdrücken:

z.B:

Wiederhole so oft bis (Abbruchbedingung erreicht)

  mache dieses
  mache jenes

  Beginn Sonderfunktion
    lese bestimmte Eingangs-Signale ein
    Falls eigangssignale = "ein bestimmter Wert"
       dann mache iregendwas
    Falls Eingangssignal "ein anderer bestimmter Wert"
       dann mache irgendwas anderes
    ansonsten mache ganz was anderes
  Ende Sonderfunktion

Ende der Wiederhol-Schleife


--> Da ist kein bischen "klassische" Progammiersprache (weder assember 
noch C) enthalten.

==> versuche, die innere Logik deiner PWM.Steuerung zu verstehen. Wenn 
du das verstanden hast, dann fäll es dir auch leicht(er), da in einer 
technischen Programmiersprache auszudrücken

von Amateur (Gast)


Lesenswert?

Hangel Dich doch mal bis zur Hilfe zu den C-Bibliotheken durch.
Da gibt es auch Beispiele zur Mischung von C und Assembler.
Des Weiteren gibt es bei den FaQ's, Hilfe zur internen Belegung der 
Register unter C.
Ob Dir das weiter hilft weis ich aber nicht.

von Karl H. (kbuchegg)


Lesenswert?

Dimitris ahoi schrieb:
> Hi,
>
> bin seit etwa 10 stunden dabei und verstehe immer noch BAHNHOF.

Macht nichts.
10 Stunden sind nicht viel.


Lad es in den Simulator und steppe es durch.

Zentraler Punkt ist das Label GO_ON
dort wird anhand der Werte in INNER bzw. OUTER entschieden, welche der 
beiden LED Konfigurationen brennen soll. Und diese beiden Werte, INNER 
und OUTER, protokollierst du einfach mal und verfolgst im Code, welche 
Aktionen davon abgeleitet werden.

Das ganze ist im Grunde einfach nur ein Wechselblinker, der abwechselnd 
2 LED-Konfigurationen anzeigt, wobei das zeitliche Verhältnis sich 
zwischen den beiden verschiebt. Und da diese Wechsel sehr schnell geht, 
sehen wir das nicht als Blinken, sondern als auf- bzw. abdimmende LED.


Am Anfang werden STORE und STORE2 mit den Werten 30 bzw. 29 geladen.
Schreibt man sich die Werte mal binär an, dann sieht man
1
          Dezimal    Binär
2
STORE     30         0001110
3
STORE     29         0001101

hier stecken die beiden LED drinnen, die leuchten sollen. Interessant 
sind nur die Bits 0 bis 5. Die 1-en da drinnen sind die 4 Stück LED die 
nicht leuchten sollen, die eine 0 ist die LED die leuchten soll.

Diese beiden Muster werden abwechselnd ausgegeben, wobei der zeitliche 
Anteil variiert. Ungefähr so
1
  while( 1 )
2
  {
3
     inner++;
4
     if( inner == wait )
5
     {
6
       outer++;
7
       if( outer == wait )
8
       {
9
          die beiden LED um 1 Stelle nach links weiter schieben
10
          wobei der berlauf' links berücksichtigt werden
11
          muss. Wenn eine LED links 'rausfällt' muss sie rechts
12
          wieder reinkommen.
13
       }
14
     }
15
16
     if( inner > outer )
17
       STORE ausgeben
18
     else
19
       STORE2 ausgeben
20
  }

inner steuert die PWM der beíden LED (die eine dimmt ab, die andere 
auf), wobei outer der PWM-Tastgrad ist, der sich nach jedem PWM 
Durchgang verändert. Ist der Tastgrad einmal durchgelaufen, wird auf die 
nächste LED weiterrotiert.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Dimitris ahoi schrieb:
> Ein Lauflicht ist in C gar kein Problem aber so ein Schönes wie im ASM
> Programm....

Ich finde ASM Programme garnicht schön, aber das ist wohl jedem sein 
Ding.

Meine Frage ist eher: willst du ein schönes Programm oder soll ein 
Programm etwas schönes machen?

Wenn du ein schönes Programm willst, wie muß ein Programm aussehen, 
damit es schön ist?

Wenn du ein Programm willst, daß etwas schönes macht, was soll es denn 
machen, was findest du schön?

MfG Klaus

von Dimitris a. (dimitris)


Lesenswert?

Hi,

Danke für euer antworten aber es klappt enfach nicht.

Mein leucht bild einfach zerhackt sich und leuft nicht so wie im video 
zusehen scheint. Schaut bitte an: rotary.avi

Beitrag "AVR-Lauflicht"

Danke
Gruß
Dimi

von Dimitris a. (dimitris)


Lesenswert?


von Stefan (Gast)


Lesenswert?

Wenn da wirklich nur zwei LED's abwechselnd ein und aus geblendet 
werden, könnte man das recht simpel mit einem einzigen PWM Ausgang 
machen:
1
PWM o---+---|>|---[===]---| GND
2
        |
3
        +---|<|---[===]---o VCC
Das programmierbare Tastverhältnis des PWM Signals bestimmt die 
Helligkeiten der beiden LED's, wobei die untere zwangsläufig immer genau 
anders herum leuchtet, als die obere.

255: oben hell, unten dunkel
128: beide leuchten halb
0:   oben dunkel,  unten hell

Du musst also nur noch den PWM Wert immer abwechselnd von 0 bis 255 
höher setzen und dann wieder von 255 bis 0 runter setzen. Zum Beispiel 
alle 2mS eine Stufe.

Jetzt schaust Du nur noch in irgendein Tutorial, wie man Timer im PWM 
Modus nutzt, und fertig bist du.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Wenn da wirklich nur zwei LED's abwechselnd ein und aus geblendet
> werden,

Es ist ein bischen trickreicher.
es sind 5 LED, die reihum aufleuchten und deren Übergänge mittels PWM 
geglättet werden.
Ich denke, es war ursprünglich mal als Simulation der Beleuchtung in 
einem Leuchtturm gedacht (Modelleisenbahn oder so).


Das Programm ist so schwer auch wieder nicht zu vestehen. Ich habe 
bewusst ein paar Dinge in der C Übersetzung nicht ausgeführt (die sind 
aber auch nicht sehr schwer zu realisieren), denn er soll ja auch was 
lernen. Lernen beginnt aber damit, dass man sich auf seinen Hosenboden 
setzt und analysiert. Davon, dass ihm jemand anderer ein Programm bis 
ins Detail vorkaut, davon hat er nichts.
Nur Mut, so schwer ist das nicht. Und nein, deine Anfrage kam am 10., 
heute ist der 17. Das ist immer noch keine Zeit.

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.