Assembler in BASCOM / ATMega88 Funktionsgenerator

(Firma: Bastler aus Mönchengladbach) Persönliche Seite #1914632
Lesenswert?

Hallo,
bin neu hier im Forum und arbeite mich hobbymässig in die Programmierung 
der ATMega88 ein.
Ich habe zwar mal E-Technik/Elektronik studiert (Dipl.Ing.), ist aber 
schon über 30 Jahre her und habe eigentlich immer im kaufmännischen 
gearbeitet.
Daher bin ich nicht mehr so besonders firm in der aktuellen Technik.
Als Rentner beschäftige mich mit jetzt zum ersten mal mit 
Microprozessoren.

Jetzt zum Thema:
Ich habe mit einem ATMega88-20 (8 MHz interner Takt) einen digitalen 
Funktiongenerator auf einem Steckbrett erstellt.
Über den Port D gebe ich die Werte einer Sinus-Tabelle auf ein R/2R 
Widerstandsnetzwerk aus (als D/A-Ersatz).
Das funktioniert auch wunderbar - siehe auch die Dateianhänge.
Aber:
Da alles in BASCOM-Basic programmiert ist, komme ich mit meiner 
Sinusfrequenz nicht über 1 kHz hinaus.
Daher wollte ich die zeitbestimmende Schleife, also der While-Wend Teil, 
mit Inline-Assembler beschleunigen (kompl. Programm im Dateianhang).

Do
  While I < C
    Incr I
    Portd = A(i)
  Wend
  I = 0
Loop

Falls sich einer wundert warum ich eine While-Wend Schleife benutzt habe 
- die war etwas schneller als ein For-Next Konstrukt.

Da Assembler für mich böhmische Dörfer sind, eine Bitte:
Vieleicht kann mir jemand da auf die Sprünge helfen ?

Das Ganze möchte ich mit weiteren Funktionen zu einem kompletten 
einfachen Funktionsgenerator für Testzwecke ausbauen.

Gruss Albert
Angehängte Dateien:
Gast #1914686
Lesenswert?

Das hier sollte mit 10 Zyklen auf 800kHz kommen. Würden die Sinus-Werte 
aus dem SRam gelesen, wären's nur 2 Zyklen weniger. Man kann's sicher 
auch anders schreiben, aber so ist's automatisch glitch-free.
1
Loadwordadr Sine
2
!MOVW    XL,     ZL
3
!CLR     R17
4
!CLR     R18
5
!start_loop:
6
!LPM     R16,    Z
7
!OUT     PortD,  R16
8
!INC     R17
9
!MOVW    ZL,     XL
10
!ADD     ZL,     R17
11
!ADC     ZH,     R18
12
!RJMP    start_loop
Code ist nicht getestet.
Gast #1914822
Lesenswert?

MWS schrieb:
> Code ist nicht getestet.

Code funktioniert und braucht 10 Zyklen.

Das hier:
> auf 800kHz kommen.

war natürlich ein Schmarrn, das ist die Durchlaufgeschwindigkeit der 
Routine, entspricht natürlich nicht der Frequenz des Sinus.

Nachfolgender Code macht's glitch-free in 8 Zyklen, 8MHz div 8 div 256 = 
3906Hz, das sollte das höchste der Gefühle mit 256 Stufen Auflösung 
sein. Ein bisserl wenig für einen Funktionsgenerator.
Außerdem wäre die Frequenzeinstellung schon sehr grob, denn ein NOP 
dazu, also ein Zyklus mehr ergibt nur noch 3472Hz.

Weniger Stützpunkte ergeben eine höhere Frequenz, zum Thema gibt's unter 
dem Stichwort "DDS" ausreichend Information.
1
Loadadr A(1) , Z
2
!MOVW    XL,     ZL
3
!CLR     R17
4
!start_loop:
5
!LD      R16,    Z+
6
!OUT     PortD,  R16
7
!INC     R17
8
!BRNE    not_zero
9
!MOVW    ZL,     XL
10
!not_zero:
11
!RJMP    start_loop
(Firma: Bastler aus Mönchengladbach) Persönliche Seite #1915359
Lesenswert?

Danke für eure hilfreichen Antworen, das bringt mich schon mal weiter.
Ich werde mich wohl doch mal in Assembler einarbeiten.
Wahrscheinlich ist mein Ansatz aber wegen der relativ niedrigen 
möglichen Ausgangsfrequenz trotz Inline-Assembler wohl doch nicht der 
richtige.
Werde mir daher mal die DDS Threads ansehen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren