Sida 3 av 6
Re: PIC16F886 lookup tables
Postat: 24 maj 2009, 22:55:02
av Swech
Har man en linjär funktion så är det inte svårt.
y = kx + m
Du vet att värde 0 skall ge 10
Max värde 255 skall ge 255
Du har alltså 245 "steg" som skall fördelas på 255 värden
Formeln blir 10 + 245*x / 255 (x är ditt AD värde)
Att dela med 255 är lite jobbigt. Däremot att dela med 256 är lätt
Har man ett word (2 bytes) så tar man bara den höga byten så vips har man
delat med 256
Vi justerar därför formeln lite
Vi säger istället att max värde är 256 och skall ge 256
Då får vi 246 steg fördelade på 256 värden
Formeln blir 10 + 246*x / 256 (x är ditt AD värde)
Vilket innebär endast 1 multiplikation samt en 256 division som är mycket lätt
Jag är dock imponerad av Phyton programmet som använder sig av mängder med
flyttal.... en mardröm för små microprocessorer
Swech
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 00:45:56
av Scorpiion
Hm.. :/ Har försökt att få till det här nu ett tag men det går lite knackigt framåt..

Så här ser koden ut just nu... Eller ja, en utvald del av den...
Kod: Markera allt
write_lcd
movlw d'3'
movwf x
call PRESSURE_CALC
movlw b'11110000'
addwf PRESSURE_RES
bcf STATUS,C
rrf PRESSURE_RES,f
rrf PRESSURE_RES,f
rrf PRESSURE_RES,f
rrf PRESSURE_RES,f
call binary_convert
call lcd_send_data
call delay_1s
movlw b'00000001' ; Clean screen
call lcd_send_cmd
goto write_lcd
PRESSURE_CALC
CLRF PRESSURE_RES
movlw d'246'
movwf y
PRESSURE_CALC_LOOP
MOVF X,W
BTFSC Y,0
ADDWF PRESSURE_RES
BCF STATUS,C
RRF Y,F
BCF STATUS,C
RLF X,F
MOVF Y,F
BTFSS STATUS,Z
GOTO PRESSURE_CALC_LOOP
RETURN
Men när jag gjort om det och anpassat till mina behov så kom jag ju på att "((Värde * 246) / 256) +10" innebär att den första delen "(Värde * 246) kommer ju att bli större än vad som ryms i 8 bitars register... Och då vart det helt plötsligt svårare igen..

Som det syns i koden "trodde" jag att det var ett 8 bitars tal jag skulle fixa med men det var de ju inte.. hm...
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 01:28:44
av bearing
Använd en multiplikationsfunktion som tar två 8-bitars tal som argument och ger ett 16-bitars tal.
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 06:38:11
av Swech
Din beräkning räknar ju ut de 8 lägsta bitarna och struntar i de 8 högsta.
Det är de 8 högsta du vill ha.....
Som bearing sade. Leta upp en "riktig" multiplikation som ger 16 bitar
Swech
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 13:51:43
av Scorpiion
Puh... nu har jag fixat så jag har en "riktig" multiplikations funktion iallafall och det funkar bra dom på tal jag testat hittils iallafall... Men sen är det den här j**vla tabellen som krånglar till det nu igen... Jag la till koden för med de macrot för att sända text men då började tabellen krångla.. Så då tänkte jag att jag strunat i de och skriver ut rakt av bara, siffra för siffra eftersom det inte är så mycket text... Men... Då sabbar tabellen till det igen.. Det funkar med att ha en siffra innan jag skriver ut värdet men efter de så hoppar tabell jätte konstigt och det blir bara skit på skärmen..
Kod:
Kod: Markera allt
;
; Write to display...
;
write_lcd
movlw d'233'
movwf X
movlw d'246'
movwf Y
call mpy_F ; The result of X*Y is in locations H_byte & L_byte
movlw b'00001010'
addwf H_BYTE,W
movwf PRESSURE_RES
call PRESSURE_SPLIT
; *** Write "Tryck:" ***
movlw b'01010100' ; T
call lcd_send_data
movlw b'01110010' ; r
call lcd_send_data
movlw b'01111001' ; y
call lcd_send_data
movlw b'01100011' ; c
call lcd_send_data
movlw b'01101011' ; k
call lcd_send_data
movlw b'00111010' ; :
call lcd_send_data
movfw PRESSURE_HNDS
banksel binary_convert
pagesel binary_convert
call binary_convert
pagesel write_lcd
banksel write_lcd
call lcd_send_data
movfw PRESSURE_TENS
call binary_convert
call lcd_send_data
movfw PRESSURE_ONES
call binary_convert
call lcd_send_data
call delay_1s
movlw b'00000001' ; Clean screen
call lcd_send_cmd
goto write_lcd
Jag har som det syns försökt lägga in banksel och pagesel men det verkar inte hjälpa... Här är tabellen:
Kod: Markera allt
binary_convert
addwf PCL,f
retlw b'00110000' ; 0
retlw b'00110001' ; 1
retlw b'00110010' ; 2
retlw b'00110011' ; 3
retlw b'00110100' ; 4
retlw b'00110101' ; 5
retlw b'00110110' ; 6
retlw b'00110111' ; 7
retlw b'00111000' ; 8
retlw b'00111001' ; 9
retlw b'00110110' ; :
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 13:56:34
av sodjan
Om din tabell "binary_convert" ligger över en page-gräns så
går det snett. Du måste hantera PCLATH korrekt.
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 14:01:40
av Scorpiion
Och hur vet jag om den gör det då?
Och hur mer exakt menar du med att "hantera PCLATH korrekt", trodde jag gjorde det med "banksel" och "pagesel" ? hm.. :/
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 15:24:55
av sodjan
> Och hur vet jag om den gör det då?
MAP filen. Förutsättningen är att du har eget CODE block
för varje tabell, men det är ganska vettigt i alla fall...
Som sagt, det finns en app-note som beskriver det, jag har för mig att
du sa att du hade läst om det. Hur som helst, AN556 är det :
http://ww1.microchip.com/downloads/en/A ... 00556e.pdf
Exempel 5 är det som beskriver tabeller som ligger över page-gränser.
Alternativet är att du lägger tabbeln så att den inte spänner över
en page gräns, t.ex med en hårdkodad adress i CODE blocket som
innehåller tabellen.
Men, som jag också har sagt, en riktig flash-read är bättre...
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 19:50:25
av Scorpiion
Hallå igen.. håller på med en liten klocka nu till displayen, har inte letat efter något färdigt utan bara försökt göra själv och den bygger på ett refresh på displayen varje sekund och sen så ökas värdet också varje gång displayen refreshas...
Den funkade jätte bra med bara sekunder, men när jag la till att jag kollade för minuterna (eller koll för 59 sek) så försvan nästan allt på displayen (dvs halva översta och hela nedre raden men "Tryck:" står kvar..)
Så här ser min lilla klocka ut:
Kod: Markera allt
; *** Clock ***
clock
incf s1,1
goto sec_check1
goto min_check1
return
; *** Sec_check ***
sec_check1
btfsc s1,3
goto sec_check2
return
sec_check2
btfsc s1,1
goto sec_check3
return
sec_check3
btfsc s1,0
goto sec_turn
return
sec_turn
clrf s1
incf s2
return
; *** Min_check ***
min_check1
btfsc s2,2
goto min_check2
return
min_check2
btfsc s2,1
goto min_check3
return
min_check3
btfsc s1,3
goto min_check4
return
min_check4
btfsc s1,1
goto min_turn
return
min_turn
clrf s1
clrf s2
incf m1
return
Jag kör kommandot "call clock" varje gång displayen refreshas som är en gång per sekund... Som sagt om jag sätter "min_check1" till att bara göra "return" så funkar klockan med sekundrarna men när jag lägger till koden som den står här så blir det konstigt.. Några idéer varför?
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 22:56:16
av bearing
Varför behövs tabellen?
Genom att addera '0' till siffran får den ASCII-värdet för siffran.
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 23:01:49
av sodjan
För att förtydliga, det är alltså a'0' som bearing menar.
Eller d'48' eller h'30'. vilket är samma sak, men om man
menar ett ASCII-tecken, så är det enklare att använda
a'x' så slipper man leta i ASCII tabellena efter dec eller
hex värdet...

Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 23:11:49
av Swech
Det behöver styras upp lite grand
Du gör några tankevurpor samt är ute på fel spår
Första felet.
GOTO - du kommer inte tillbaks då den är klar
Kod: Markera allt
clock
incf s1,1
goto sec_check1
goto min_check1 Hit kommer vi aldrig!!!!!
return
Sen har du massa bittest, jag antar att du vill se om talet blivit 59 eller 60.... är för rörigt för
att lura ut.
Om du kört någon form av högnivå så hade du väl skrivit
if x > 59 then x = 0
Det finns möjligheter att jämföra hela tal i assembler också
(nåja de minsta PIC processorerna är ...host.. inte de mest logiska vad gäller denna biten)
Hursomhelst.. på PIC så subtraherar du ditt tal som du vill jämföra med och ser om du fick
overflow eller inte....
Läs på om detta så skall du se att det blir lättare.
Du måste lära dig detta innan du fortsätter. Annars blir det lätt oerhört krångliga lösningar.
Kämpa på, känner på mig att du snart får en AHA upplevelse och det mesta faller på plats
Swech
Re: PIC16F886 lookup tables
Postat: 25 maj 2009, 23:26:27
av bearing
Kod: Markera allt
; *** Write "Tryck:" ***
movlw b'01010100' ; T
call lcd_send_data
Här verkar det enklare att skriva a'T' istället för b'01010100'.
Kod: Markera allt
call mpy_F ; The result of X*Y is in locations H_byte & L_byte
movlw b'00001010'
addwf H_BYTE,W
Att använda d'10' istället för b'00001010' verkar lämpligare här. Blir enklare att förstå att siffran kommer ifrån formeln.
Re: PIC16F886 lookup tables
Postat: 26 maj 2009, 00:45:06
av Scorpiion
> Här verkar det enklare att skriva a'T' istället för b'01010100'.
Men alltså antyder inte det att det är ASCII? Och där jag har tittat så är ASCII inte samma som vad det är för hd44780 displayen jag använder... Det är därför jag skriver så.. Men förmodligen så har jag väl fel..

Eftersom ni säger så.. Men har bara inte hittat nått bevis på det, när jag söker på det så får jag ju upp så här:
Kod: Markera allt
http://www.asciitabell.se/
http://www.asciitable.com/
Men jag kanske har fått den biten om bakfoten.. På nått sätt..
@Swech
Just ja det var så man gjorde..

Jag satt och funderade på det där ett bra tag men kom inte på hur man jämförde tal så ska nog göra om den biten nu!

Re: PIC16F886 lookup tables
Postat: 26 maj 2009, 00:59:59
av bearing
De allra flesta tecknen är samma i displayen som i ASCII-tabellen.