Archiv verlassen und diese Seite im Standarddesign anzeigen : Wert < 255 teilen
Hi,
Ich versuche verzweifelt einen gemessenen Spannungswert (<255)
mit dem PIC16F819 zu teilen ( / 1,2)
Der Wert ist so in dem Bereich 200 - 300 mV und wird in 2 Speicherzellen gespeichert.
Untere 8 Bit und obere 2 Bit (Vom 10Bit AD Wandler)
Ich will nun die Spannung durch 1,2 teilen und wieder in 2 Speicherzellen speichern.
Wie kann ich in Assembler soetwas lösen?
Assembler ist die einzige Programmiersprache, die ich nutzen kann.
Nicht c oder andere Sprachen.
Gruß
Lennart
Edit: Vref= 1V
kalledom
08.06.2006, 12:12
Hallo Lennart,
in der AN617 und AN526 gibt es Mathematik-Routinen in Assembler.
Du müßtest zuerst eine 16 mal 8/16-Bit-Multiplikation mit 10 durchführen und anschließend das Ergebnis mit einer 16 durch 8-Bit-Division (UDIV1608L) durch 12 teilen (U=unsigned = vorzeichenlos).
Vielen Dank für deine Hilfe
Hab jetzt mal dort reingeschaut aber die PICs sind ja nicht 16F sondern 16C.. ist das nicht ein Unterschied?
kalledom
08.06.2006, 13:34
Ja, der 16F hat ein F wie Flash-Speicher, den Du einige tausend mal löschen und wieder 'brennen' kannst, den 16C kannst Du nur ein mal 'brennen'.
SprinterSB
08.06.2006, 15:39
Wozu willst du das dividieren?
Eine Division durch 1.2 entspricht einer Multiplikation mit (etwa) 213 und danach einer Division durch 256. Die Division durch 256 ist trivial und mit 213 multiplizieren kannst du wahrscheinlich schon.
Falls es noch genauer sein muss (genauer zu sein als die Genauigkeit deiner Darstellung (Ganzzahl) ist Käse), geht es auch mit
54613 / 63356, also nach der Mult mit 54613 noch 16 Rechts-Shifts.
<< n bedeute hier links-Schieben um n Positionen (also Multiplikation mit 2^n).
Dann ist
213*x = (x << 7) + 5*x + ((5*x) << 4)
5*x = (x << 2) + x
Du Brauchst also nur 13 Links-Shifts, 8 Rechts-Shifts und 3 Additionen!
Noch einfacher geht's wohl kaum :-)
Noch einfacher geht's wohl kaum
.........mit zahlen zu arbeiten die größer als 255 sind...
Ich sitz irgendwie fest
SprinterSB
09.06.2006, 11:09
Schieben und Addieren/Subtrahieren geht warscheinlich über das Carry.
z.B. shift left: (HI und LOW-Teil)
HHHHHHHH LLLLLLLL
76543210 76543210
Erst wirl der LOW-Teil nach Links geschoben und rechs eine 0 nachgefüttert, Carry = L7
LLLLLLL0
6543210
Dann wird HI mit Carry nach links geschoben, danach ist Carry=H7
HHHHHHHL
65432107
Addition etc geht analog
Falls die Architektur kein Carry hat, dann musst du es selber ausrechnen.
LIST P=16F84A R=DEC ; Auswahl des PIC-Typs
#include <P16f84A.INC>
#include <MATH16.INC>
bsf STATUS, RP0 ; Bank 1
movlw B'00000000' ; PortA und PortB alle outputs
movwf TRISB
movwf TRISA
bcf STATUS, RP0 ; Bank 0
movlw D'10'
movwf AARG
movlw D'10'
movwf BARG
call UDIV1608L
self
goto self
INCLUDE <FXD68.A16>
end
So sieht mein Programm jetzt aus.. es kommen aber 100.000 fehlermeldungen das die variablen undefined sind.. aber sie sind doch in den entsprechenden INC dateien definiert oder nicht?
Häng wieder fest
Hallo,
heissen die Variablen nicht AARGBx und BARGBx (x=0..3)?
Vergleich das mal mit den werten inder INC-Datei. Dann checke bei den Fehlermeldungen ob er die *.inc Datei überhaupt einbindet.
Ach ja, oben weiter schreibst Du dass Du einen 16F819 benutzen willst. Im Programm bist Du der Meinung dass es ein 16F84A ist. Das sollte schon auch zusammenpassen!
Ciao
Mario
Ja, benutz zum testen den 16F84A.. aber sollte ja bei beiden funktionieren.
#include P16F84A.INC
B0 equ 0
B1 equ 1
B2 equ 2
B3 equ 3
B4 equ 4
B5 equ 5
B6 equ 6
B7 equ 7
MSB equ 7
LSB equ 0
#define _C STATUS,0
#define _Z STATUS,2
orgx00
ACCB7 equ 0x20
ACCB6 equ 0x21
ACCB5 equ 0x22
ACCB4 equ 0x23
ACCB3 equ 0x24
ACCB2 equ 0x25
ACCB1 equ 0x26
ACCB0 equ 0x27
ACC equ 0x27
;
SIGN equ 0x29
;
TEMPB3 equ 0x30
TEMPB2 equ 0x31
TEMPB1 equ 0x32
TEMPB0 equ 0x33
TEMP equ 0x33
AARGB7 equ 0x20
AARGB6 equ 0x21
AARGB5 equ 0x22
AARGB4 equ 0x23
AARGB3 equ 0x24
AARGB2 equ 0x25
AARGB1 equ 0x26
AARGB0 equ 0x27
AARG equ 0x27
;
BARGB3 equ 0x2B
BARGB2 equ 0x2C
BARGB1 equ 0x2D
BARGB0 equ 0x2E
BARG equ 0x2E
REMB3 equ 0x20
REMB2 equ 0x21
REMB1 equ 0x22
REMB0 equ 0x23
LOOPCOUNT equ 0x34
movlw B'00001001'
movwf AARGB0
movlw B'00000011'
movwf BARGB0
call UMUL1616L
sleep
UMUL1616L
MOVLW 0x08
MOVWF LOOPCOUNT
LOOPUM1616A
RRF BARGB1, F
BTFSC _C
GOTO ALUM1616NAP
DECFSZ LOOPCOUNT, F
GOTO LOOPUM1616A
MOVWF LOOPCOUNT
LOOPUM1616B
RRF BARGB0, F
BTFSC _C
GOTO BLUM1616NAP
DECFSZ LOOPCOUNT, F
GOTO LOOPUM1616B
CLRF AARGB0
CLRF AARGB1
RETLW 0x00
BLUM1616NAP
BCF _C
GOTO BLUM1616NA
ALUM1616NAP
BCF _C
GOTO ALUM1616NA
ALOOPUM1616
RRF BARGB1, F
BTFSS _C
GOTO ALUM1616NA
MOVF TEMPB1,W
ADDWF AARGB1, F
MOVF TEMPB0,W
BTFSC _C
INCFSZ TEMPB0,W
ADDWF AARGB0, F
ALUM1616NA
RRF AARGB0, F
RRF AARGB1, F
RRF AARGB2, F
DECFSZ LOOPCOUNT, F
GOTO ALOOPUM1616
MOVLW 0x08
MOVWF LOOPCOUNT
BLOOPUM1616
RRF BARGB0, F
BTFSS _C
GOTO BLUM1616NA
MOVF TEMPB1,W
ADDWF AARGB1, F
MOVF TEMPB0,W
BTFSC _C
INCFSZ TEMPB0,W
ADDWF AARGB0, F
BLUM1616NA
RRF AARGB0, F
RRF AARGB1, F
RRF AARGB2, F
RRF AARGB3, F
DECFSZ LOOPCOUNT, F
GOTO BLOOPUM1616
end
Im Picsim gibt er mir nur die Zahl 9 in 0x26 raus
Verstehe nicht warum?! Was mache ich falsch?
kalledom
16.06.2006, 18:00
orgx00 ist ein LabelName.
So fängt ein PIC-Programm bei mir an:
org 0x0000 ; 00h Reset-Vektor
Reset
clrf STATUS ; 00h Page 0, Bank 0
goto Init ; 01h Initialisierung / ProgrammBeginn
goto Reset ; 02h Reset-Vektor
goto Reset ; 03h Reset-Vektor
goto Interrupt ; 04h Interrupt-Vektor
Der Rest steht unter: http://www.domnick-elektronik.de/picasm.htm
Mag ja alles stimmen.. nur erscheint mir das jetzt ziemlich egal bei meinem kleinen programm.
Jedenfalls versteh ich immernoch nicht wie die Funktion anzuwenden ist
Lennart,
in Deinem Programm möchtest Du zwei 16-Bit zahlen multiplizieren. Du initialisierst aber nur 8Bit. Jeweils (AARGB0, AARGB1) und (BARGB0, BARGB1) bilden einen 16-Bit wert.
Also: (AARGB0 -> 0, AARGB1 -> 9)
(BARGB0 -> 0, BARGB1 -> 3)
Ich denke "0" ist das high-byte und "1" ist das low-byte.
Gruß
Mario
P.S.: Als kleiner Tipp, immer genau formulieren wo das Problem ist (Anfangs Multiplikation, dann Fehlermeldungen und nun Anwendung der AN-Routinen ?!?).
Als kleiner Tipp, immer genau formulieren wo das Problem ist (Anfangs Multiplikation, dann Fehlermeldungen und nun Anwendung der AN-Routinen ?!?).
Sorry.. versuch es naechstesmal besser :)
Probier es mal aus danke :)
gruß lennart
Edit:
Habs probiert auf diese weise:
#include P16F84A.INC
B0 equ 0
B1 equ 1
B2 equ 2
B3 equ 3
B4 equ 4
B5 equ 5
B6 equ 6
B7 equ 7
MSB equ 7
LSB equ 0
#define _C STATUS,0
#define _Z STATUS,2
orgx00
ACCB7 equ 0x20
ACCB6 equ 0x21
ACCB5 equ 0x22
ACCB4 equ 0x23
ACCB3 equ 0x24
ACCB2 equ 0x25
ACCB1 equ 0x26
ACCB0 equ 0x27
ACC equ 0x27
;
SIGN equ 0x29
;
TEMPB3 equ 0x30
TEMPB2 equ 0x31
TEMPB1 equ 0x32
TEMPB0 equ 0x33
TEMP equ 0x33
AARGB7 equ 0x20
AARGB6 equ 0x21
AARGB5 equ 0x22
AARGB4 equ 0x23
AARGB3 equ 0x24
AARGB2 equ 0x25
AARGB1 equ 0x26
AARGB0 equ 0x27
AARG equ 0x27
;
BARGB3 equ 0x2B
BARGB2 equ 0x2C
BARGB1 equ 0x2D
BARGB0 equ 0x2E
BARG equ 0x2E
REMB3 equ 0x20
REMB2 equ 0x21
REMB1 equ 0x22
REMB0 equ 0x23
LOOPCOUNT equ 0x34
movlw B'00000000'
movwf AARGB0
movlw B'00000000'
movwf BARGB0
movlw B'00001001'
movwf AARGB1
movlw B'00000011'
movwf BARGB1
call UMUL1616L
sleep
UMUL1616L
MOVLW 0x08
MOVWF LOOPCOUNT
LOOPUM1616A
RRF BARGB1, F
BTFSC _C
GOTO ALUM1616NAP
DECFSZ LOOPCOUNT, F
GOTO LOOPUM1616A
MOVWF LOOPCOUNT
LOOPUM1616B
RRF BARGB0, F
BTFSC _C
GOTO BLUM1616NAP
DECFSZ LOOPCOUNT, F
GOTO LOOPUM1616B
CLRF AARGB0
CLRF AARGB1
RETLW 0x00
BLUM1616NAP
BCF _C
GOTO BLUM1616NA
ALUM1616NAP
BCF _C
GOTO ALUM1616NA
ALOOPUM1616
RRF BARGB1, F
BTFSS _C
GOTO ALUM1616NA
MOVF TEMPB1,W
ADDWF AARGB1, F
MOVF TEMPB0,W
BTFSC _C
INCFSZ TEMPB0,W
ADDWF AARGB0, F
ALUM1616NA
RRF AARGB0, F
RRF AARGB1, F
RRF AARGB2, F
DECFSZ LOOPCOUNT, F
GOTO ALOOPUM1616
MOVLW 0x08
MOVWF LOOPCOUNT
BLOOPUM1616
RRF BARGB0, F
BTFSS _C
GOTO BLUM1616NA
MOVF TEMPB1,W
ADDWF AARGB1, F
MOVF TEMPB0,W
BTFSC _C
INCFSZ TEMPB0,W
ADDWF AARGB0, F
BLUM1616NA
RRF AARGB0, F
RRF AARGB1, F
RRF AARGB2, F
RRF AARGB3, F
DECFSZ LOOPCOUNT, F
GOTO BLOOPUM1616
end
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.