Forum: Mikrocontroller und Digitale Elektronik [ASM] Fragen zum Projektaufbau und vordefinierten Templates


von Stephan W. (stipo)


Lesenswert?

Nabend zusammen,

ich hatte bis jetzt nur mit dem ATmega8 rumgespielt, da der im Tutorial 
genutzt wird und da der Code nicht erst noch groß angepasst werden muss.
Zum grundlegenden Programmieren und lernen in Assembler fand ich das bis 
jetzt besser, da ich mich dann nicht mit den Unterschieden der einzelnen 
µC herum ärgern musste.

Da ich mir nun aber den AVR Dragon geleistet habe, musste natürlich auch 
ein neuer µC Typ her, der das debuggen unterstützt. Da ist dann die Wahl 
auf den ATmega88 gefallen, da der PIN-Kompatibel zum ATmega8 ist.

Als erstes habe ich mal versuchsweise ein bestehendes ATmega8 Projekt 
für den ATmega88 ohne anpassung kompilieren wollen. Das ist natürlich 
wie zu erwarten erstmal gründlich in die Hose gegangen. Somit bestätigte 
sich die aussagen im Forum, das man nicht einfach bestehenden Code auf 
einen anderen µC umstellen kann. Gut das soll auch nicht das Problem 
sein, denn so bin ich nun gezwungen mich noch besser und intensiver mit 
dem Datenblatt des ATmega88 auseinander zu setzen, was einem den 
Controller und die Technik noch besser in das Gehirn meiselt.

Da ich in dem ATmega8 Projekt einen ADC drinne habe und das natürlich 
gleich vom Kompiler am meisten bemeckert wurde, musste auch gleich das 
Kapitel in dem Datenblatt herhalten. Dort sind mir dann auch ein paar 
Unterschiede schon aufgefallen.

Mein Ziel ist es nun, das ich den ATmega88 und eventuell den ATmega168 
als allround Controller nutzen möchte. Da aber Assembler ja keine so 
schönen Libs bietet, wie es in C der fall ist, ist es natürlich 
erstrebenswert wiederverwertbaren Code zu schreiben.

Das soll mal zum einstand gewesen sein. Nicht das ich euch noch 
Informationen vorenthalte :-). Nun aber weiter zu dem Thema wo ich 
eigentlich hin möchte.

Wie handhabt Ihr das? Ich denke ja nicht, das Ihr bei jedem Projekt, was 
Ihr anfangen wollt, immer bei Null mit dem Code beginnt. Ich denke da 
schon eher, das Ihr da irgendwelche Templates zurecht gebaut habt, die 
euch das Grundgerüst zur verfügung stellen.
Gibt es da zufällig nette Beispiele, wie so ein Grundgerüst aufgebaut 
sein kann, oder gibt es da auch schon fertiges im Internet, was man am 
besten verwenden sollte. Das soll jetzt nicht bedeuten, das ich mir das 
einfach per Copy&Paste kopieren möchte und dann nach mir die sinnflut 
und ich will schnelle erfolge haben, sondern ich möchte einfach 
inspirationen haben, wie ich mir meine eigenen Grundgerüste aufbauen 
kann.

Wenn man Klassenorientiert programmieren kann, möchte man immer alles in 
kleine teilbereiche zerlegen. Da finde ich im moment noch sehr schlecht 
den Anfang. Zum Beispiel möchte ich mir jetzt eine Include Datei 
erstellen, in der ich die Grundfunktionen des ADC fertig anlege. Also 
das Initialisieren, den PORT-PIN auswählen zu können, den man Samplen 
möchte usw.

Genau da habe ich nun auch im Datenblatt gelesen, das man den ADV im 
Stromsparmodus explizit ausschalten soll. Das ist dann in meinen Augen 
eine eigene Methode, die meine Include anbieten soll.

Hier mal etwas exemplarischen Code, wie ich mir den vorstelle.
1
ADC_ON:
2
     ldi r16, (1<<ADEN)
3
     out ADCSRA, r16
4
     ret
5
6
ADC_OFF:
7
     ldi r16, (0<<ADEN)
8
     out ADCSRA, r16
9
     ret
10
11
ADC_INIT:
12
     rcall ADC_ON
13
     ...
14
     ret
15
16
ADC_SLEEP:
17
     rcall ADC_OFF
18
     ...
19
     ret
20
21
usw...

Wie Ihr seht, schwirren mir da gerade sehr viele Gedanken durch den 
Kopf. Ich komme eben aus der C# Welt und da ist alles in Klassen 
versteckt. Da ist Assembler schon ein hartes Stück zum sich umgewöhnen.

Ich würde mich daher sehr freuen, wenn Ihr ein bisschen aus dem 
Nähkästchen plaudert, wie Ihr das Professionell handhabt.

Grüße
Stephan

von spess53 (Gast)


Lesenswert?

Hi

>Wenn man Klassenorientiert programmieren kann, möchte man immer alles in
>kleine teilbereiche zerlegen. Da finde ich im moment noch sehr schlecht
>den Anfang. Zum Beispiel möchte ich mir jetzt eine Include Datei
>erstellen, in der ich die Grundfunktionen des ADC fertig anlege. Also
>das Initialisieren, den PORT-PIN auswählen zu können, den man Samplen
>möchte usw.

Kann man machen, wenn man lang genug mit Assembler programmiert hat und 
dabei bleiben will.

Vor allem sollte man sein Werkzeug kennen:

>ADC_ON:
>     ldi r16, (1<<ADEN)
>     out ADCSRA, r16
>     ret

Zum einen machst du damit alle anderen Bits in ADCSRA platt und 'out' 
funktioniert für ADCSRA beim ATMega8 aber nicht z.B. beim ATMega88.

MfG Spess

von Sam .. (sam1994)


Lesenswert?

Für I/O nutzt man am besten Makros: 
http://www.mikrocontroller.net/articles/AVR_Assembler_Makros#I.2FO
Die Defines von Atmel sind schon relativ portabel solange man keinen 
größeren Umstieg von älteren zu neueren µCs macht. Von Atmega8-88 muss 
man leider ein paar Register ändern. Von Atmega88-644 keine falls man 
die I/O Makros benutzt hat.

von Stephan W. (stipo)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Wenn man Klassenorientiert programmieren kann, möchte man immer alles in
>>kleine teilbereiche zerlegen. Da finde ich im moment noch sehr schlecht
>>den Anfang. Zum Beispiel möchte ich mir jetzt eine Include Datei
>>erstellen, in der ich die Grundfunktionen des ADC fertig anlege. Also
>>das Initialisieren, den PORT-PIN auswählen zu können, den man Samplen
>>möchte usw.
>
> Kann man machen, wenn man lang genug mit Assembler programmiert hat und
> dabei bleiben will.
Für mich steht jetzt schon fest, das ich wohl bei Assembler bleiben 
werde. Auch wenn C eine verlockende schnelligkeit bietet um da etwas in 
den Controller zu bekommen, hat es mir Assembler mehr angetan.

> Vor allem sollte man sein Werkzeug kennen:
>
>>ADC_ON:
>>     ldi r16, (1<<ADEN)
>>     out ADCSRA, r16
>>     ret
>
> Zum einen machst du damit alle anderen Bits in ADCSRA platt und 'out'
> funktioniert für ADCSRA beim ATMega8 aber nicht z.B. beim ATMega88.
Danke für den Hinweis. Dann weiß ich gleich wo ich noch weiter lesen 
muss.

von Stephan W. (stipo)


Lesenswert?

Samuel K. schrieb:
> Für I/O nutzt man am besten Makros:
> http://www.mikrocontroller.net/articles/AVR_Assembler_Makros#I.2FO
> Die Defines von Atmel sind schon relativ portabel solange man keinen
> größeren Umstieg von älteren zu neueren µCs macht. Von Atmega8-88 muss
> man leider ein paar Register ändern. Von Atmega88-644 keine falls man
> die I/O Makros benutzt hat.

Auch Dir danke. Das mit den Makros muss ich mir dann mal noch genau 
ansehen.

von Stephan W. (stipo)


Lesenswert?

@spess53,

>Vor allem sollte man sein Werkzeug kennen:

>>ADC_ON:
>>     ldi r16, (1<<ADEN)
>>     out ADCSRA, r16
>>     ret

>Zum einen machst du damit alle anderen Bits in ADCSRA platt und 'out'
>funktioniert für ADCSRA beim ATMega8 aber nicht z.B. beim ATMega88.

Ich habe darüber nochmal nachgedacht, was Du gesagt hast.
Hier mal ein Stück Code was die anderen Bits nicht überschreiben sollte.
Als erstes muss ich das Register auslesen, das ich die alten zustände 
erhalten kann um dann ein Bit ändern zu können.
Liege ich da richtig?
1
ADC_ON:
2
    in r16, ADCSRA
3
    ori r16, (1<<ADEN)
4
    out ADCSRA, r16

Lediglich das 'out' bekomme ich da nicht weg. Ich habe da im moment 
keine Ahnung was es noch für einen Befehl dafür geben soll.

Grüße
Stephan

von spess53 (Gast)


Lesenswert?

Hi

>Lediglich das 'out' bekomme ich da nicht weg. Ich habe da im moment
>keine Ahnung was es noch für einen Befehl dafür geben soll.

IO-Register mit Adressen >= $60 werden wie RAM-Adressen mit lds/sts 
statt in/out angesrochen. Kann man aber, wie schon gesagt auch durch ein 
Macro erledigen:

   .macro _out
     .if @0<$60
       out @0,@1
     .else
       sts @0,@1
     .endif
   .endmacro

Wird wie out benutzt:

   _out ADCSRA, r16

Dazu gibt es auch eine AppNote von Atmel:

http://www.atmel.com/Images/doc2550.pdf
http://www.atmel.com/Images/AVR001.zip

MfG Spess

von Stephan W. (stipo)


Lesenswert?

Danke Spess,
das lese ich mir sofort durch. Habe den Code von oben eben getestet, was 
ein Fehler gebracht hat.
Aber mit deiner Info kommt da schon Licht in sicht.

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.