Sida 2 av 2

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 14:35:58
av Nerre
Det vete f-n om det där var med pedagogiskt...:) Det blir ju helt klart mindre läsbart.

Nu vet jag inte hur syntaxen för den där assemblern ser ut, men nåt i stil med:

"\01\01LCD DEMO\00"
"\01\0A16F886\00"
"\02\04WWW.JESCAB.SE\00"
"\02\01(C)\00"

(i C behöver man ju inte nulltermina manuellt som jag gjort) hade nog varit klart tydligare. Fast fattar man inte hur ASCII fungerar så lär ju inget av förslagen hjälpa:)

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 14:47:10
av sodjan
Jag tror att man även kan skriva :

Kod: Markera allt

lcd_text1   data    d'1', d'1',  a'LCD DEMO',       h'00'
lcd_text2   data    d'1', d'10', a'167886',         h'00'
lcd_text3   data    d'2', d'4',  a'WWW.JESCAB.SE',  h'00'
lcd_text4   data    d'2', d'1',  a'(C)',            h'00'
Sen är det möjligt att man skulle använda "dw" istället för "data", jag
har inte kollat närmare på det...

Man skulle även kunna skriva :

Kod: Markera allt

lcd_text1   data    d'1', d'1',  a'LCD DEMO\n'
lcd_text2   data    d'1', d'10', a'167886\n'
lcd_text3   data    d'2', d'4',  a'WWW.JESCAB.SE\n'
lcd_text4   data    d'2', d'1',  a'(C)\n'
och testa för h'0A' ("line feed") som terminering.

Eller :

Kod: Markera allt

lcd_text1   data    d'1', d'1',  a'LCD DEMO\x00'
lcd_text2   data    d'1', d'10', a'167886\x00'
lcd_text3   data    d'2', d'4',  a'WWW.JESCAB.SE\x00'
lcd_text4   data    d'2', d'1',  a'(C)\x00',
om man fortfarade vill testa på "null" som terminering.

Man som sagt, otestat. Man behöver verifiera att data läggs på samma
sätt i flash...

Till slut så fungerar nog även :

Kod: Markera allt

lcd_text1   data    1, 1,  'LCD DEMO\x00'
lcd_text2   data    1, 10, '167886\x00'
lcd_text3   data    2, 4,  'WWW.JESCAB.SE\x00'
lcd_text4   data    2, 1,  '(C)\x00',
Man får bara se upp med radix för 10 ovan. Om radix är satt till hex så skiter det sig...

:-)

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 19:07:59
av Nerre
Men 16F886 blev 167886 i dina exempel:)

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 20:17:54
av PopUnoNkoK
Sodjan: Jag tyckte mig ha kollat koden ordentligt men justeringen av rad/pos värden hade jag missat. När jag kollade lite snabbt i koden kan jag inte riktigt säga att jag förstod den delen fullt ut men det ska jag nog få koll på.

Däremot hade jag INGEN koll på att ASCII tecken motsvarade ett värde, samma värde på "alla" processorer. Det var lite av en aha upplevelse. ASCII har alltid för mig bara varit "rena skrivtecken" typ som in ASCII-art. Jag har aldrig kollat upp det mer djupgående. Och utifrån det "naiva" synsättet så var din kod skriven på ett "speciellt" sätt. I alla för mig. Men nu förstår jag den biten i alla fall.


Ett av sätten att skriva ASCII i MPASM är alltså helt enkelt 'L' (Fnuttar före och efter) ett annat är a'L' (a för ASCII och sedan fnuttar)

Kul kul, tack för alla svar.

Vi ska se om det kommer några fler frågor här.

MVH Peter

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 21:04:23
av sodjan
OK.
Och hur 17 trodde du att t.ex ett "A" såg ut *inne* i datorn !? :shock:
Speciellt som alla datorer enbart förstår "ettor och nollor" ?

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 21:44:46
av PopUnoNkoK
En fråga som inte har med Trådtiteln att göra men berör samma kod.

Jag har nu börjat att sammanfoga min tidigare skrivna "klockkod" med den kod som denna tråd berör. Koden som främst är Sodjans HD44780 exempel som är omskriven till 16f690.

Processorn är alltså 16f690.

När jag "lagt till" (Är det det som heter Allokerat) mina minnen så ser det ut så här:

Kod: Markera allt

INT_VAR     UDATA_SHR    
w_temp      RES     1       ; variable used for context saving
status_temp RES     1       ; variable used for context saving
pclath_temp RES     1       ; variable used for context saving
tmr0_count res  1     ;Tilläggs räknare till TMR0 för att öka tiden  
sec   res  1     ;Råvärdet för sec, min hour, 2 siffror
min   res  1
hour  res  1
   
sec_one  res  1     ;Entalet i sekunderna, minuterna och timmarna
sec_ten  res  1     ;Tiotalet i sekunderna, minuterna och timmarna
min_one  res  1     
min_ten  res  1     
hour_one res  1     
hour_ten res  1 
    
t1   res  1
w2   res  1
getones  res  1 
VARL  res  1
VAR   res  1
När jag "Build all" så får jag detta error mess:

Kod: Markera allt

Error - section 'INT_VAR' can not fit the section. Section 'INT_VAR' length=0x00000012
Alltså det kan väl inte vara så att jag redan använt för många bytes att spara olika saker i? Jag är säker på att detta är en sådan sak som man kan hitta i Databladet men jag hittade inget där förutom detta:

GENERAL PURPOSE REGISTER FILE
The register file is organized as 256 x 8
Betyder det 256 Bytes eller 256 x 8 bytes? I vilket fall som helst så ligger jag ju låååång under det.

Tack på förhand.

MVH Peter

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 3 oktober 2011, 22:44:13
av sodjan
OK, då ska vi se. :-)

Först en liten detalj:

> Koden som främst är Sodjans HD44780 exempel som är omskriven till 16f690.

Notera också HD44780 filerna som ligger här : http://jescab2.dyndns.org/pub_docs/.
Det är i och för sig ganska små ändringar mellan 886 och 690, men i alla fall... :-)

Men till det fenomen som du har åkt på. Det är egentligen ganska enkelt.
När man förstår vad som händer. :-)

Du behöver sannolikt en kopia av databladet (41262E.PDF) öppnat för att hänga med.
Och gärna en kopia av MPASM manualen (33014K.PDF) också...

Först tar vi minnesmappen i en PIC16F690.
Se sidan 31 med "FIGURE 2-8: PIC16F690 SPECIAL FUNCTION REGISTERS".

Notera hur GPR'erna (General Purpose Registers) ser ut. Notera speciellt de sista
16 registren mellan 70h - 7Fh ! Som du ser så är det samma 16 register som
ligger mappade över alla 4 minnesbankerna. Detta områda kallas "shared memory"
eller ibland "unbanked memory). Nu ser du kanske också var "_SHR" kommer från i
UDATA_SHR. Alltså "User data in shared memory" ! OK ?

Fördelen med detta område är att man inte behöver bry sig om vilken bank som
för tillfället är vald (via t.ex BANKSEL), de är alltid tillgängliga. Alltså till skillnad
från de 80 bytes som ligger direkt innan i bank 0, 1 och 2.

Frågor så långt ?

Men, detta minnesområde är alltså bara *16* bytes och ska primärt användas till de
variabler som man vill ha snabb access till (man slipper BANKSEL). Eller om applikationen
inte har fler än 16 variabler, så kan man ju låta allt ligga där. Samt ett par variabler
som *måste* ligga i "shared memory", men det tar vi inte här...

Men man kan alltså aldrig allokera mer är *16* bytes med UDATA_SHR !

För minne utöver detta måste man använda UDATA. Detta allokerar
minne från "banked memory", alltså från de 3 x 80 bytes som ligger ovanför
70h i bank 0, 1 eller 2. Man har inte (och vill/behöver inte) ha någon kontroll
över vilken bank varje variabel hamnar i. Dock så allokeras alltid en hel "section"
(d.v.s allt som ligger under samma användning av UDATA, i samma bank, så en
viss styrningar har man i alla fall.

Så ditt exempel skulle kunna se ut så här t.ex :

Kod: Markera allt

UNBANKED_VAR     UDATA_SHR
; Här allokerar vi dels de variabler som *måste* ligga i shared memory,
; d.v.s de tre *_temp variablerna (varför det är så går vi inte in på här,
; men det har med hanteringen vid avbrott/interrupt att göra) men även
; andra variabler som vi vill ha snabbst möjliga access till (d.v.s utan BANKSEL).

w_temp      RES     1       ; variable used for context saving
status_temp RES     1       ; variable used for context saving
pclath_temp RES     1       ; variable used for context saving
tmr0_count res  1     ;Tilläggs räknare till TMR0 för att öka tiden 

TIME_VARS        UDATA 
; En section med data till tid/klock hanteringen.
; Eftersom hela TIME_VARS kommer att allokeras från samma bank, så
; behöver man inte BANKSEL så länge som man bara hanterar dessa.

sec   res  1     ;Råvärdet för sec, min hour, 2 siffror
min   res  1
hour  res  1
   
sec_one  res  1     ;Entalet i sekunderna, minuterna och timmarna
sec_ten  res  1     ;Tiotalet i sekunderna, minuterna och timmarna
min_one  res  1     
min_ten  res  1     
hour_one res  1     
hour_ten res  1
   

DIVERSE_VARS       UDATA
; Dessa variabler kommer kanske att allokeras från samma bank som
; TIME_VARS eller kanske från en annan bank. Det bestämmer MPLINK.

t1   res  1
w2   res  1
getones  res  1
VARL  res  1
VAR   res  1
Ovanstående är ett exempel. Nu är det ju inte fler varabler (d.v.s mindre än 80 st)
så du behöver så klart bara en UDATA. Och om det är så att man bedömmer att
klock-variablerna behövs ofta (och snabbt) så kan de ju också läggas i UDATA_SHR.

Se även kodexempel under "4.62 udata..." i MPASM manualen. Notera hur CLRF används
mot båda varablerna i samma UDATA section utan extra BANKSEL, eftersom de ändå alltid
kommer att ligga i samma bank.

> Jag är säker på att detta är en sådan sak som man kan hitta i Databladet men jag hittade inget där förutom detta:

När det gäller detaljer i MPASM så är det "MPASM/MPLINK User's Guide" du ska använda.
Om du t.ex tittar i kapitlet för "udata_shr", så står det bl.a :
This directive is used to declare variables that are allocated in RAM that is shared
across all RAM banks (i.e. unbanked RAM).
Ser du kopplingen från det till de sista 16 bytesen i minnes mappen ?

Summering:
-----------
1. Du kan aldrig allokera mer än 16 bytes med UDATA_SHR.
2. Använd UDATA för övriga variabler (och använd BANKSEL där det behövs).

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 4 oktober 2011, 08:13:18
av PopUnoNkoK
Tusen tack för svaret.

Så sjukt bra och uttömmande svar dessutom. :)

Detta ska förstås implementeras så fort som möjligt i koden, förhoppningsvis ikväll.

När du skriver att de gemensamma registren går fortare att komma åt (i och med att man slipper banksel). Vad handlar det om i praktiken? Kan man ens säga så? Allså om jag bara gör en klocka, ingen kritisk applikation. Spelar det någon roll att det går några fler (hur många?) klockcyklar medans man gör banksel?
Jag har så sjuukt svårt att sätta in dessa otroligt korta tider i praktiken.

Som sagt, tusen tack för svaret.

MVH Peter F

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 4 oktober 2011, 08:27:33
av Nerre
Nej, för en klocka (där du egentligen inte behöver göra något förrän en gång i sekunden) så spelar det ingen större roll.

Om fördröjningen hamnar på fel ställen så kan det kanske bli "artefakter" på displayen eller liknande, så generellt ska man ju försöka tänka igenom koden så att de bitar som eventuellt syns utåt så att säga görs snabbt.

Det är ju lite därför man grupperar variablerna i olika sektioner, man grupperar dem efter när man behöver komma åt dem. Har man t.ex. långa loopar i tidskritiska delar av koden så är det ju viktigt att inte behöva ha onödiga bankval där. Om du råkar ha variablerna i två olika banker istället för en så tar ju loopen kanske tre gånger så lång tid (du åker ju på att klämma in två banksel i varje varv).

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 4 oktober 2011, 10:14:21
av sodjan
> Spelar det någon roll att det går några fler (hur många?) klockcyklar medans man gör banksel?

Det är ju omöjligt att ge ett generellt svar på det.
BANKSEL <register> är ett macro som tittar på vilken bank <register>
ligger i och skapar två BSF/BCF kommandon för att sätta bankbitarna
(bit RP0 och RP1 i STATUS registret).

D.v.s att du själv manuellt kan göra exakt samma sak som BANKSEL, men
då måste du sitta med databladets minnesmapp och manuelt leta upp
varje register och se till att skriva rätt BCF/BSF kommandon. Med BANKSEL
så fixar MPASM det med automatik och det blir alltid rätt.

Dessutom, med UDATA så sker ju allokeringen till ett av 80 bytes områderna
i bank 0, 1 eller 2 med automatik, och det blir jäkligt besvärligt att försöka
hänga med med egna BSF/BCF. Med BANKSEL så anpassas det med automatik
från en build till en annan även om variablerna byter bank mellan build'erna.

Sen så tidsmässigt, så "kostar" en BANKSEL ju två instruktioner. Du kan själv
slå upp och översätta det till tid. Det beror ju även på vilken hastighet som
processorn körs i.

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 4 oktober 2011, 23:13:43
av PopUnoNkoK
Fungerade klockrent när jag testade ikväll.
Riktigt kul.

Jag gjorde bara UDATA_SHR och en UDATA, inte två som i sodjans exempel här ovan då jag är ganska säker på att jag kommer att hålla mig under 80 allokaliserade minnen.

Tack för hjälpen

Re: HD44780, Bokstäver istf binär kod, Sodjans exempelkod.

Postat: 4 oktober 2011, 23:22:08
av sodjan
Trevligt ! :-)

Sannolikt (verifiera i MAP filen) så kommer även UDATA sektionen
att läggas i första banken (bank0) så det fungerar även utan att
köra med BANKSEL som man kanske borde. Risken är att det växer
och så plötsligt när data-sektioner börjar allokeras till bank1, så
smäller det bara av... :-)

Jag rekomenderar generellt att titta lite i MAP filen, det ger bra info
om hur det hela har "byggts ihop" samt att man ser storlek på varje
separat CODE och UDATA/UDATA_SHR sektion.

En sak till slutligen, den riktigt *stora* fördelen med att köra relokerbart.

Antag att du har skrivit en liten generell rutin som gör något nyttigt som
du vill använda i olika program. När MPLINK "bygger" applikationen så tar
den ju hänsyn till alla CODE och UDATA i både själva applikationen och de
som finns i din biblioteksmodul. Så det blir aldrig några variabel-kollisioner.
Detta är näst intill omöjligt att hantera vid det gamla sättet att skriva kod
där man manuellt angav vilken adress olika variabler skulle ligga på (med EQU).
Det blir snabbt en helsike att hålla reda på allt...