Konvertera binärtal till Decimaltal på display?
- Klas-Kenny
- Inlägg: 11843
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Konvertera binärtal till Decimaltal på display?
Jag har funderat över det ett tag, om jag har tex. ett värde från ADC, 0000 0000 - 1111 1111, och vill skriva ut det som decimaltal 0 - 255 på en display av någon typ, tex. 3st 7-seg eller en HD44780, hur gör man detta enklast med en PIC (PIC16Fxxx, Assembly)?
Första jag kunde tänka mig är Lookup-table, men hur ska man kunna returnera de tre tecken (tre byte) som krävs för att skriva det som dec? Och det borde väl finnas effektivare metoder är en 256 rader lång lookup-table?
Första jag kunde tänka mig är Lookup-table, men hur ska man kunna returnera de tre tecken (tre byte) som krävs för att skriva det som dec? Och det borde väl finnas effektivare metoder är en 256 rader lång lookup-table?
Re: Konvertera binärtal till Decimaltal på display?
Jag har löst detta i assembler tidigare genom att först räkna antal hundratal, tiotal och ental.
Skriver ett exempel nedan i någon slags pseudokod(
):
sedan är det bara att lägga till ASCII offset för tecknet 0 och skriva ut (förutsatt alfanumerisk LCD).
Skriver ett exempel nedan i någon slags pseudokod(

Kod: Markera allt
hundratal=0
tiotal=0
ental=0
var=255
loop1:
IF var >= 100 {
INC hundratal
var=var-100
GOTO loop1
}
loop2:
IF var >= 10 {
INC tiotal
var=var-10
GOTO loop2
}
loop3:
IF var >= 1 {
INC ental
var=var-1
GOTO loop3
}
Re: Konvertera binärtal till Decimaltal på display?
> Jag har funderat över det ett tag, om jag har tex. ett värde från ADC, 0000 0000 - 1111 1111,
> och vill skriva ut det som decimaltal 0 - 255
Hur skulle du göra med enbart papper och penna ?
Gör sen på i princip samma sätt...
Hur många gånger kan jag minska ADC värdet med 100 utan
att det blir < 0 ? Antalet gånger är din 100-talssiffra. Spara resten.
Hur många gånger kan jag minska resten med 10 utan
att det blir < 0 ? Antelt gånger är din 10-talssiffra. Spara resten.
Resten är nu din entalssiffra.
Klart !
Väldigt onödigt, eller hur ? 
Det hela kan ersättas med
"ental" kommer *alltid* att bli detsamma som "var"...
> och vill skriva ut det som decimaltal 0 - 255
Hur skulle du göra med enbart papper och penna ?
Gör sen på i princip samma sätt...
Hur många gånger kan jag minska ADC värdet med 100 utan
att det blir < 0 ? Antalet gånger är din 100-talssiffra. Spara resten.
Hur många gånger kan jag minska resten med 10 utan
att det blir < 0 ? Antelt gånger är din 10-talssiffra. Spara resten.
Resten är nu din entalssiffra.
Klart !
Kod: Markera allt
loop3:
IF var >= 1 {
INC ental
var=var-1
GOTO loop3

Det hela kan ersättas med
Kod: Markera allt
ental = var
Re: Konvertera binärtal till Decimaltal på display?
Haha självklart!:) Får skylla på tidpunkten 

- Klas-Kenny
- Inlägg: 11843
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: Konvertera binärtal till Decimaltal på display?
>Hur skulle du göra med enbart papper och penna ?
"128+64+32+16+8+4+2+1 = 255", känns inte som att det hjälper så mycket just här?
Ett snabbt utkast taget ur huvudet:
Skulle någonting sådant kunna fungera?
Tack för bra svar!
Nu har jag lite att fundera på innan jag somnar, godnatt
"128+64+32+16+8+4+2+1 = 255", känns inte som att det hjälper så mycket just här?

Ett snabbt utkast taget ur huvudet:
Kod: Markera allt
kolla_hundratal
movlw 0x64
subwf ADC,f
incf hundratal,f
btfss STATUS,C
goto kolla_hundratal
addwf ADC,f
kolla_tiotal
movlw 0x0A
subwf ADC,f
incf tiotal,f
btfss STATUS,C
goto kolla_tiotal
addwf ADC,f
movfw ADC
movwf ental
Tack för bra svar!
Nu har jag lite att fundera på innan jag somnar, godnatt

Re: Konvertera binärtal till Decimaltal på display?
> movlw 0x64
> movlw 0x0A
Varför inte d'100' resp d'10' ?
Är inte det mycket tydligare ?
Men annars så ser det ju spontant inte helt fel ut.
Kör det i MPSIM så ser du direkt om det fungerar.
> movlw 0x0A
Varför inte d'100' resp d'10' ?
Är inte det mycket tydligare ?
Men annars så ser det ju spontant inte helt fel ut.
Kör det i MPSIM så ser du direkt om det fungerar.
Re: Konvertera binärtal till Decimaltal på display?
Jag byggde en batteritestare nyligen. Den använder en PIC12F689 som matar ut seriedata till en 74LS164, som i sin tur matar två LED-segment. Här är relevanta delar av koden, som du kan stjäla bäst du vill:Klas-Kenny skrev:Jag har funderat över det ett tag, om jag har tex. ett värde från ADC, 0000 0000 - 1111 1111, och vill skriva ut det som decimaltal 0 - 255 på en display av någon typ, tex. 3st 7-seg eller en HD44780, hur gör man detta enklast med en PIC (PIC16Fxxx, Assembly)?
Kod: Markera allt
; Bit-structure for the serial stream to the 74LS164
#define LED_A b'11111110'
#define LED_B b'11111101'
#define LED_C b'11111011'
#define LED_D b'11110111'
#define LED_E b'11101111'
#define LED_F b'11011111'
#define LED_G b'10111111'
#define LED_DP b'01111111'
; Building blocks for the segments
#define ZERO LED_A & LED_B & LED_C & LED_D & LED_E & LED_F
#define ONE LED_B & LED_C
#define TWO LED_A & LED_B & LED_G & LED_E & LED_D
#define THREE LED_A & LED_B & LED_G & LED_C & LED_D
#define FOUR LED_B & LED_C & LED_G & LED_F
#define FIVE LED_A & LED_C & LED_D & LED_F & LED_G
#define SIX LED_A & LED_G & LED_C & LED_D & LED_E & LED_F
#define SEVEN LED_A & LED_B & LED_C
#define EIGHT LED_A & LED_B & LED_C & LED_D & LED_E & LED_F & LED_G
#define NINE LED_A & LED_B & LED_C & LED_D & LED_F & LED_G
...
loop:
call read_adc
movfw ADC_VALUE
call split_ones_tenths ; split value to TENS and ONES
movfw TENS
call number_to_led
andlw LED_DP ; the left LED should have its dot lit
call spi_output ; send data to the '164
movlw LED1 ; hold the data on LED1 for a fixed amount of time
call led_delay
movfw ONES
call number_to_led
call spi_output
movlw LED2
call led_delay
goto loop
...
; Convert decimal values to "LED segment"-format
; Used for the '164
number_to_led
addwf PCL
retlw ZERO
retlw ONE
retlw TWO
retlw THREE
retlw FOUR
retlw FIVE
retlw SIX
retlw SEVEN
retlw EIGHT
retlw NINE
; This function split an integer into 'tens' and 'ones'. This is
; achieved by subtracting 10 from the value until a Borrow occurs.
split_ones_tenths
clrf TENS
movlw .10
remove_10
subwf resultat ; Remove 10
incf TENS
btfsc STATUS, C ; Borrow?
goto remove_10 ; No, continue
addwf resultat ; Yes, correct the values.
decf TENS
; Copy the remainder, and we're done.
movfw resultat
movwf ONES
return
- Klas-Kenny
- Inlägg: 11843
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: Konvertera binärtal till Decimaltal på display?
Har nu försökt mig på att simulera koden (Första gången jag gör det) i MPSIM, och det fungerar inte alls
STATUS,C verkar aldrig ändra sig, så den kommer aldrig ur loopen som kollar hundratal. Kan vara jag som gör fel när jag simulerar i och för sig...
Sen undrar jag hur jag kollar variablers värde i MPSIM? Hittar bara funktionsregisterna.
Hela koden just nu:
bos: Tack så mycket!

STATUS,C verkar aldrig ändra sig, så den kommer aldrig ur loopen som kollar hundratal. Kan vara jag som gör fel när jag simulerar i och för sig...
Sen undrar jag hur jag kollar variablers värde i MPSIM? Hittar bara funktionsregisterna.
Hela koden just nu:
Kod: Markera allt
list p=16f690 ; list directive to define processor
#include <P16F690.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;***** VARIABLE DEFINITIONS
cblock
ADC
ental
tiotal
hundratal
endc
;**********************************************************************
ORG 0x000 ; processor reset vector
main
movlw 0xFF
movwf ADC
kolla_hundratal
incf hundratal,f
movlw d'100'
subwf ADC,f
btfss STATUS,C
goto kolla_hundratal
addwf ADC,f
decf hundratal,f
kolla_tiotal
movlw d'10'
subwf ADC,f
incf tiotal,f
btfss STATUS,C
goto kolla_tiotal
addwf ADC,f
decf hundratal,f
movfw ADC ;Lägg ental i variabeln ental
movwf ental
END
bos: Tack så mycket!
Re: Konvertera binärtal till Decimaltal på display?
> Sen undrar jag hur jag kollar variablers värde i MPSIM? Hittar bara funktionsregisterna.
I WATCH. Du väljer "Add SFR" eller "Add Symbol".
I WATCH. Du väljer "Add SFR" eller "Add Symbol".
- Klas-Kenny
- Inlägg: 11843
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: Konvertera binärtal till Decimaltal på display?
I listan brevid "Add SFR" finns ingen av mina variabler, bara funktionsregisterna, och "Add Symbol" går inte att trycka på... 

Re: Konvertera binärtal till Decimaltal på display?
Du kan markera och sedan dra/släppa en variabel från kodrutan in i watch-fönstret.
Re: Konvertera binärtal till Decimaltal på display?
> I listan brevid "Add SFR" finns ingen av mina variabler...
Och vad finns i listan bredvid "Add Symbol " ????
Och vad finns i listan bredvid "Add Symbol " ????
Re: Konvertera binärtal till Decimaltal på display?
OK, testade med din kod. Jag har gjort ett par
justeringar och rättat några rena slarvfel...
Fungerar helt OK, får 2, 5 pch 5 i hundratal, tiotal och antal.
Notera också att CBLOCK skapar *konstanter*, så de är inte
speciellt intressanta att se i WATCH, de har alltid samma värde.
Troligtsivis därför de inte visas.
Du hade inte nollat variablerna (CLRF).
Du "backade" hundratal två gånger (slarvfelet).
justeringar och rättat några rena slarvfel...
Fungerar helt OK, får 2, 5 pch 5 i hundratal, tiotal och antal.
Notera också att CBLOCK skapar *konstanter*, så de är inte
speciellt intressanta att se i WATCH, de har alltid samma värde.
Troligtsivis därför de inte visas.
Du hade inte nollat variablerna (CLRF).
Du "backade" hundratal två gånger (slarvfelet).
Kod: Markera allt
list p=16f690 ; list directive to define processor
#include <P16F690.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;***** VARIABLE DEFINITIONS
udata
ADC RES 1
ental RES 1
tiotal RES 1
hundratal RES 1
;**********************************************************************
code 0x000 ; processor reset vector
main
movlw 0xFF
movwf ADC
clrf hundratal
clrf tiotal
clrf ental
kolla_hundratal
incf hundratal,f
movlw d'100'
subwf ADC,f
btfsc STATUS,C
goto kolla_hundratal
addwf ADC,f
decf hundratal,f
kolla_tiotal
movlw d'10'
subwf ADC,f
incf tiotal,f
btfsc STATUS,C
goto kolla_tiotal
addwf ADC,f
decf tiotal,f
movfw ADC ;Lägg ental i variabeln ental
movwf ental
END
Re: Konvertera binärtal till Decimaltal på display?
En sak till justerade jag...
Det ska vara btfsc, inte btfss.
Kan kännas bakvänt, men stämmer med databladet.
Från sidan där STATUS beskrivs har "C" biten en fotnot :
"Note 1: For Borrow, the polarity is reversed."
Det ska vara btfsc, inte btfss.
Kan kännas bakvänt, men stämmer med databladet.
Från sidan där STATUS beskrivs har "C" biten en fotnot :
"Note 1: For Borrow, the polarity is reversed."
- Klas-Kenny
- Inlägg: 11843
- Blev medlem: 17 maj 2010, 19:06:14
- Ort: Växjö/Alvesta
Re: Konvertera binärtal till Decimaltal på display?
Gör cblock konstanter? Det hade jag inte en aning om, jag har alltid använt cblock tidigare och det har inte varit några problem alls, där lärde man sig någonting nytt!
Tack för all hjälp, som vanligt!

Tack för all hjälp, som vanligt!

