mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hilfe beim übersetzen von AVR-Bascom nach AVR-Assembler


Autor: Daniel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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:
$regfile "m8def.dat"
$crystal = 4000000
$baud = 9600

Ddrb = &B00001110

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1

Dim Wert As String * 20                                     'Die Variable wo der Eingelesene Wert vom UART reinkommt
Dim Farbe(3) As String * 20                                 'Das Array mit den durch SPLIT einzelnen Farben
Dim Gruen As Integer                                        'Die Farben als Integer wo die String rein sollen
Dim Rot As Integer
Dim Blau As Integer
Dim Bcount As Byte

Do
  Input "" , Wert                                           'Hier wird der UART gelesen
  Bcount = Split(wert , Farbe(1) , " ")                     'Hier wird der eingelesene String in 3 Teile nämlich R, G und B gesplittet
  Rot = Val(farbe(1))                                       'Die Versuche einen String in ein Integer zu konvertieren
  Gruen = Val(farbe(2))
  Blau = Val(farbe(3))
  Compare1a = Rot                                           'Die PWM Kanäle
  Compare1b = Gruen
  Compare2 = Blau
Loop
End


So und jetzt möchte ich das ganze in AVR Assembler, hier mal was ich bis 
jetzt zu sammen habe:
.include "m8def.inc"
 
.def temp = R16
 
.equ F_CPU = 4000000                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate
 
; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif
 
.org 0x00
        rjmp main
 
.org URXCaddr                                   ; Interruptvektor für UART-Empfang
        rjmp int_rxc
 
; Hauptprogramm
 
main:
 
    ; Stackpointer initialisieren
 
    ldi     temp, LOW(RAMEND)
    out     SPL, temp
    ldi     temp, HIGH(RAMEND)
    out     SPH, temp
 
    ; Port D = Ausgang
 
    ldi     temp, 0xFF
    out     DDRD, temp
 
    ; Baudrate einstellen
 
    ldi     temp, HIGH(UBRR_VAL)
    out     UBRRH, temp
    ldi     temp, LOW(UBRR_VAL)
    out     UBRRL, temp
 
    ; Frame-Format: 8 Bit
 
    ldi     temp, (1<<URSEL)|(3<<UCSZ0)
    out     UCSRC, temp
 
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
    sbi     UCSRB, RXEN                     ; RX (Empfang) aktivieren
    
    sei                                     ; Interrupts global aktivieren
    
loop:
    rjmp loop                               ; Endlosschleife
 
; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde
 
int_rxc:
    push    temp                            ; temp auf dem Stack sichern
    in      temp, UDR                       ; empfangenes Byte lesen,
                                            ; dadurch wird auch der Interrupt gelöscht
    out     PORTD, temp                     ; Daten ausgeben
    pop     temp                            ; temp wiederherstellen
    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

Autor: Winfried (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stell lieber eine konkrete Frage, wo genau du nicht weiterkommst. Ein 
Teilproblem, was man schnell überblicken kann. Sich in dein ganzes 
Projekt einzudenken ist sehr zeitraubend... Wer hat schon Lust dazu?

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mir wäre schon sehr geholfen wenn ich wüsste wie ich in Assembler 
eine Zeichen kette also

"145 45 220"

Die als Trennzeichen ein Leerzeichen hat in 3 einzelne Variablen bekomme 
->

"145"
"45"
"220"

Die dann später an die PWM übergeben werden kann.

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Zeichenkette z. b. von einem Terminalprogramm kommt, nimmst Du 
ein Zeichen zur Synchtonisation (z. B. "#").

Im Assemblerprogramm wartest Du auf dieses Zeichen, nullst Du einen 
Zähler.

1. Nun schreibst Du die 3 folgenden ASCII-Zeichen in eine Variable. Die 
3 Zeichen müssen vorher von ASCII in Dezimal umgewandelt werden:

2. "ASCII-Zeichen" - $30 (Offset) = Wert

3. Die 3 folgenden Werte jeweils mit der Wertigkeit multiplizieren 
(100-10-1) und addieren.

Mit erreichen des Blank erhöhst Du den Zähler (der als Zeiger auf die 
Specherzelle dient) und wiederholst den Vorgang ab 1.

Otto

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Also mir wäre schon sehr geholfen wenn ich wüsste wie ich in Assembler
>eine Zeichen kette also...

Als erstes musst du herausfinden, wie das Stringende gekennzeichnet 
wird. Üblicherweise CR($0D), LF($0A).
Dann brauchst du einen Puffer im RAM:

         .dseg
puffer:  .byte 20

In den werden die Zeichen, die die UART empfängt, bis zum Stringende 
gespeichert. Bei Stringende ein Flag setzen, das deiner 'loop' mitteilt, 
das ein String empfangen wurde. In der 'loop' bastelst du aus den 
ASCII-Zeichen die Werte und lädst die in die Register.

Was mir allerdings etwas schleierhaft ist: Timer1 ist ein 16-Bitter 
(0..65535) und Timer2 ein 8-Bitter (0..255).

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ignoriere bitte den letzten Satz. Ich hatte die Zeile übersehen:

>Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm ....

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.