Hallo zusammen,
Das hier ist meine erstes projekt das ich in Assembler fertig stellen
möchte. ( Deshalb seit bitte nicht so streng mit mir )
Also ich habe in AVR-Bascom ein kleines Programm mit ca. 20 zeilen. Ich
möchte das Programm nun im AVR Studio mit Assembler benutzen und hab so
meine Probleme das Ganze zu Übersetzen.
Das Programm macht folgendes (ist eine RGB LED Steuerung, mit PWM):
Es empfängt über die serielle Schnittstelle einen String mit 3 werten
(Beispiel: "256 256 256" oder "145 45 220" oder "1 1 1"), die drei Werte
sind RGB Werte von 0 - 256. die werten werden dann weiter an die 3 PWM
Ports gegeben und Regeln diese.
Bascom Code:
1 | $regfile "m8def.dat"
|
2 | $crystal = 4000000
|
3 | $baud = 9600
|
4 |
|
5 | Ddrb = &B00001110
|
6 |
|
7 | Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
|
8 | Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1
|
9 |
|
10 | Dim Wert As String * 20 'Die Variable wo der Eingelesene Wert vom UART reinkommt
|
11 | Dim Farbe(3) As String * 20 'Das Array mit den durch SPLIT einzelnen Farben
|
12 | Dim Gruen As Integer 'Die Farben als Integer wo die String rein sollen
|
13 | Dim Rot As Integer
|
14 | Dim Blau As Integer
|
15 | Dim Bcount As Byte
|
16 |
|
17 | Do
|
18 | Input "" , Wert 'Hier wird der UART gelesen
|
19 | Bcount = Split(wert , Farbe(1) , " ") 'Hier wird der eingelesene String in 3 Teile nämlich R, G und B gesplittet
|
20 | Rot = Val(farbe(1)) 'Die Versuche einen String in ein Integer zu konvertieren
|
21 | Gruen = Val(farbe(2))
|
22 | Blau = Val(farbe(3))
|
23 | Compare1a = Rot 'Die PWM Kanäle
|
24 | Compare1b = Gruen
|
25 | Compare2 = Blau
|
26 | Loop
|
27 | End
|
So und jetzt möchte ich das ganze in AVR Assembler, hier mal was ich bis
jetzt zu sammen habe:
1 | .include "m8def.inc"
|
2 |
|
3 | .def temp = R16
|
4 |
|
5 | .equ F_CPU = 4000000 ; Systemtakt in Hz
|
6 | .equ BAUD = 9600 ; Baudrate
|
7 |
|
8 | ; Berechnungen
|
9 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden
|
10 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate
|
11 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille
|
12 |
|
13 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler
|
14 | .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
|
15 | .endif
|
16 |
|
17 | .org 0x00
|
18 | rjmp main
|
19 |
|
20 | .org URXCaddr ; Interruptvektor für UART-Empfang
|
21 | rjmp int_rxc
|
22 |
|
23 | ; Hauptprogramm
|
24 |
|
25 | main:
|
26 |
|
27 | ; Stackpointer initialisieren
|
28 |
|
29 | ldi temp, LOW(RAMEND)
|
30 | out SPL, temp
|
31 | ldi temp, HIGH(RAMEND)
|
32 | out SPH, temp
|
33 |
|
34 | ; Port D = Ausgang
|
35 |
|
36 | ldi temp, 0xFF
|
37 | out DDRD, temp
|
38 |
|
39 | ; Baudrate einstellen
|
40 |
|
41 | ldi temp, HIGH(UBRR_VAL)
|
42 | out UBRRH, temp
|
43 | ldi temp, LOW(UBRR_VAL)
|
44 | out UBRRL, temp
|
45 |
|
46 | ; Frame-Format: 8 Bit
|
47 |
|
48 | ldi temp, (1<<URSEL)|(3<<UCSZ0)
|
49 | out UCSRC, temp
|
50 |
|
51 | sbi UCSRB, RXCIE ; Interrupt bei Empfang
|
52 | sbi UCSRB, RXEN ; RX (Empfang) aktivieren
|
53 |
|
54 | sei ; Interrupts global aktivieren
|
55 |
|
56 | loop:
|
57 | rjmp loop ; Endlosschleife
|
58 |
|
59 | ; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
|
60 |
|
61 | int_rxc:
|
62 | push temp ; temp auf dem Stack sichern
|
63 | in temp, UDR ; empfangenes Byte lesen,
|
64 | ; dadurch wird auch der Interrupt gelöscht
|
65 | out PORTD, temp ; Daten ausgeben
|
66 | pop temp ; temp wiederherstellen
|
67 | reti ; Interrupt beenden
|
So momentan wäre ich schon froh wenn ich die Drei Werte in so was wie
einer variablen hätte oder noch besser wenn ich wüsste wie ich dies dann
an die 3 Hardware PWM Ports übergebe
Schon mal vielen Dank im Voraus für die Hilfe!!!
MFG Daniel