Newsgroup: it.hobby.elettronica.digitale
Titolo: PIC16F84 e tabelle in pagina <> 0

Ciao a tutti, vengo subito al sodo:
Ho un PIC16F84 collegato con un display 2x16 caratteri. Dovendo visualizzare
diverse scritte, sono ricorso alle tabelle, che ho posto nella pagina 3
della memoria flash.
In fase di debug, ho scritto una routine per ogni tabella. Adesso vorrei
scrivere una routine che legge tutte le tabelle fornendogli la parte bassa
dell'indirizzo. In pratica:
    movlw    LOW Tabella1 ;Sposta in AddrTable la parte bassa
    movwf    AddrTable    ;dell'indirizzo della tabella1
    call     ShowTable
    ;
    ; snip
    ;
ShowTable
    ;
    ;snip
    ;
    movlw    03H          ;Pagina in cui sono le tabelle
    movwf    PCLATH       ;Indirizza a quella pagina
    goto     AddrTable    ;Salta all'indirizzo contenuto
                          ;in AddrTable, ma a pagina 03H
"A bocca" dovrebbe funzionare, ma nella realta' no. Qualcuno sa spiegarmi
dove sbaglio, o se non e' possibile? Almeno mi metto il cuore in pace.
PaoloS

                          ;



Allora proprio non mi sono spiegato 8-/. L'application note AN556 di
Microchip parla proprio di indirizzamento dei GOTO e CALL per leggere una
tabella, anche se di 16Cxxx, ma non spiega 8-< come leggere piu' tabelle
sulla stessa pagina con una sola routine, passandogli solo l'indirizzo di
inizio. E negli esempi si parla di page0 con indirizzo 080H e di page3 con
indirizzo 0320H. Le routine che uso per leggere le tabelle (1 per tabella)
si differenziano solo per la parte bassa dell'indirizzo, che inizia da 0300H
e termina (ovviamente per un 16F84) entro 03FFH. Nel PCLATH, come avevo
spiegato nel messaggio precedente, ci metto la parte ALTA dell'indirizzo di
inizio della tabella, che e' uguale per tutte le tabelle cioe' 03H. A questo
punto, facendo un GOTO, non salta nella stessa pagina, ma a pagina 3.
Ordunque, se sostituisco, come destinazione del GOTO, l'etichetta con il
valore BASSO dell'indirizzo, che puo' essere un numero o una costante,
perche' non funziona?
Se non mi sono ancora spiegato, sono qui e aspetto domande o, meglio 8-)
risposte.
PaoloS

>
Ho capito il problema:
Chiamiamo allora pagina i 256 byte consecutivi a partire dalle locazioni
b'xxxxx00000000'.
Ricordo che il program counter del PIC e' a 13 bit quindi in grado di
indirizzare fino ad un massimo di 8Kbyte (sarebbe piu' corretto parlare di
8KWord in quanto le istruzioni sono a 14 bit).
All'interno dei 2KWord non ci sono problemi di salto GOTO o di CALL in
quanto queste due istruzioni possono saltare ovunque all'interno di 2KW.
Il PCLATH<4,3>  entra in gioco quando la memoria di programma e' maggiore di
2Kw  per cui deve essere divisa in BANCHI (quello che io intendevo per
pagina). Per l'appunto il PIC16F84 ha solo 1Kw per cui nelle istruzioni GOTO
e CALL non entra in gioco il PCLATH. Le pagine che gestisce PCLATH sono i
BANCHI e sono di 2Kw.
Inoltre i bit di BANCO sono il 3 e 4 di PCLATH per cui, ammesso di voler
selezionare il quarto banco di program memory (cioe' dai 6Kw a 8Kw nel
PIC16F877), il PCLATH deve essere PCLATH=b'11000' e non a h'03'.
IL PCLATH viene invece utilizzato dalle istruzioni che hanno come operando
il PCL cioe' direttamente il byte basso del program counter.
goto AddrTable ???
GOTO non puo' avere una variabile come argomento!!!! Accetta solo una
etichetta.
Quello che vuoi fare tu e':
movlw    03h
movwf    PCLATH
movfw    AddrTable
movwf    PCL
In questo caso il PC salta alla pagina 03h all'indirizzo contenuto in
AddrTable.
Cioe' vengono combinati i byte PCLATH + PCL e il risultato e'
AddrTable = 34h
PCLATH   = 03h
PC = 0334h
La prossima istruzione eseguita, cioe' Tabella1, si trovera' alla locazione
0334h.
Ricordati che la etichetta Tabella1 deve essere nella quarta pagina (03h e'
la quarta non la terza ricordati che comincia da 0) altrimenti non funziona.
in questo caso sarebbe meglio scrivere:
movlw    HIGH Tabella1
movwf    PCLATH
movfw    AddrTable
movwf    PCL
In questo modo il PCLATH viene settato automaticamente in maniera giusta
dovunque viene posizionata tabella1
Scusami per l'incomprensione e spero di esserti stato di aiuto.
Ciao Andrea

Scusate l'intromissione ma il discorso "tabelle" merita un discorso :
Il puntamento del PC (Program Counter) del PIC č di 14 bit quindi per la
memoria programma non ci sono problemi in quanto si indirizza linearmente
tutto il range del PIC (si possono puntare al massimo 16k di rom).
Il dicorso delle pagine rigurda solo la ram FSR in quanto l'architettura del
PIC ha la memoria del programma separata dalla memoria dei dati e, mentre il
contatore della rom č a 14 bit, quello della ram č di soli 8 bit (la
dimensione massima di un registro) e quindi punta un qualsiasi indirizzo
compreso tra 0x00 e 0xFF.
Per ovviare a questo č stato aggiunto aulche bit (RP0,RP1) che perň viene
gestito manualmente e serve per estendere il range del puntatore della ram.
Ovviamente non stň parlando dei pic serie 17cXX.
Per questo motivo č saggio realizzare sia la tavola, che la routine di
gestione, all'interno dello stesso banco che č idealmente definito
dall'intervallo 0x00...0xFF o suoi multipli, in maniera da poter ignorare il
bit di pagina (ricordo che quando nella tavola si salva il PC si salvano
solo i bit dallo 0 al 7).
Se cosě non fosse si dovrebbe provvedere a gestire anche i bit supplementari
oltre l'ottavo, in modo da far "saltare" correttamente il PC alla locazione
desiderata (č piů conveniente e semplice operare con il primo caso).
In questo modo si puň puntare piů tavole all'interno dello stesso banco
passando alla routine di gestione un parametro iniziale che rappresenta  la
locazione iniziale della tavola in oggetto.
Spero di essere stato d'aiuto e non aver complicato ulteriormente le cose.
Sempre disponibile per chiarimenti.
Ciao, Botte!

 Spero di essere stato d'aiuto e non aver complicato ulteriormente le cose.
Speriamo di no.
--
Ciao Andrea
Togliere il trattino per rispondere in e-mail

 tutto il range del PIC (si possono puntare al massimo 16k di rom).
E` vero che la program memory contiene word di 14 bit, ma il program counter e`
a 13 bit. Ma c'e` di piu`: chiaramente un'istruzione contiene anche l'opcode
oltre al displacement, quindi - essendo i PIC delle CPU RISC, quindi una
word=una istruzione - non puoi indirizzare tutta la program memory in
un'istruzione. Ad esempio GOTO contiene un numero con segno a 10 bit, quindi
puoi fare dei salti al massimo di +/- 512 word.
--
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/

Grazie Andrea.
Non credevo di scatenare un flame, anche se ridotto. Pero' ho capito dove
sbagliavo, e dire che adesso sembra cosi semplice. Non si usa una variabile
per i GOTO, ma e' sufficiente spostarne il valore in PCL.
Grazie ancora. Stasera provo.
PaoloS

 puoi fare dei salti al massimo di +/- 512 word.
Quì però non sono d'accordo!!!!!
I data sheet all'istruzione GOTO parlano dei bit dal 10 allo 0 quindi in
totale 11.
Se non mi sbaglio questo vuol dire esattamente 1023 byte di range (tutta la
memoria del PIC16X84).
Se così non fosse il mio timer del caricabatteri non dovrebbe assolutamente
funzionare mentre in realtà và che è una bomba!?!?!?!?
Sono io che 'canno' oppure....?
Ciao, Botte!

 Speriamo di no.
Il tema della discussione era il PIC16X84 e i riferimenti erano proprio a
questo PIC, non ai fratelli maggiori anche se l'architettura è la stassa per
tutti, anche se quì qualche bit è scollegato.
Ti ringrazio per la correzione e non trattenerti dal replicare o contestare,
trovo che sia il miglio metodo per imparare.
Ciao, Botte!


Direttamente dai data sheets del 16F84, così chiudiamo la discussione :
*********
The PIC16F83 and PIC16CR83 have 512 words of pro-gram
memory. The PIC16F84 and PIC16CR84 have
1K of program memory. The CALL and GOTO instruc-tions
have an 11-bit address range. This 11-bit address
range allows a branch within a 2K program memory
page size. For future PIC16F8X program memory
expansion, there must be another two bits to specify
the program memory page. These paging bits come
from the PCLATH<4:3> bits (Figure 4-1). When doing a
CALL or a GOTO instruction, the user must ensure that
these page bits (PCLATH<4:3>) are programmed to
the desired program memory page. If a CALL instruc-tion
(or interrupt) is executed, the entire 13-bit PC is
"pushed" onto the stack (see next section).
**********
Ciao
Marco d'Ambrosio  
m.dam...@tiscalinet.it
http://utenti.tripod.it/razzimodellismo
    ACME I-RM-05
http://web.tiscalinet.it/mda


E' questo il vero spirito del NG e non una mera bacheca di annunci !!!
Ciao Andrea

 wrote in message 86knrr$dot$1...@nslave2.tin.it...

Quando si scatena un flame (non conoscevo questo termine, grazie) significa
che l'argomento e' interessante e quindi e' naturale che alimenti un'accesa
discussione. Ritengo che questo sia veramente proficuo per tutti noi.
Grazie a te.
Andrea

 funzionare mentre in realtà và che è una bomba!?!?!?!?
Tutti questi problemi non ci sono con il PIC16F84 perche' ha solo 1Kword di
program memory e un banco di ram utente, ma se ti volessi cimentare con i
fratelli maggiori e' meglio che ti chiarisci questi concetti.
Ciao Andrea


Scusa Andrea, ma mi rimangio il ringraziamento 8-).
Per fare un GOTO si sposta il valore della locazione nel PCL,
ma per le CALL come si fa?
Qui ci sta' pure lo stack, che non e' leggibile o scrivibile direttamente.
Hai o avete qualche idea?
Altrimenti, se mi basta la memoria, faccio una subroutine
per ogni tabella, come in effetti avevo gia implementato.
PaoloS

 totale 11.
Giusto, ho toppato a calcolare la potenza. :-)
Intendevo: un numero a 10 bit PIU` il bit di segno, ma 2^10 fa appunto 1024.
E fra l'altro per scrupolo sono andato a dare un'occhiata al datasheet del
PIC16F84, e ho "scoperto" che l'indirizzo nei GOTO e` assoluto, non e` un
offset come capita per i microprocessori x86. Quindi ho scritto una doppia
stupidaggine.
Ecco i vantaggi dell'utilizzare l'assembly: non ti devi preoccupare del formato
degli opcodes... ;-)


 ma per le CALL come si fa?
Rischiando di dire un'altra stupidata, cosi` a naso direi che "non si fa". :)
Sul datasheet e` indicato esplicitamente che lo stack non e` scrivibile e
leggibile, ed e` controllato unicamente via hardware...
Se provi ad eseguire un RETURN quando lo stack e` vuoto, ti rimanda
all'indirizzo zero.


 per ogni tabella, come in effetti avevo gia implementato.
No e' molto piu' semplice :-)
Se qualcuno ha trovato un metodo piu' semplice, io ho fatto il primo
passo...
Ciao a tutti.
;***************************************************************************
; SUBRUOTINE:
;
; Str_Var:      Questa ruotine invia la stringa puntata da w sull'LCD nella
;               posizione corrente, la stringa deve terminare con 0x00.
;               E' comodo usare l'etichetta circa uguale al nome della
;               stringa.
;
; Chiamata      movlw    low    STR_1
;               call     Str_Var1
;
;***************************************************************************
Str_Var1 movwf   Reg0          ; Puntatore alla stringa
SV1_1    movlw   PCH_STR_VAR1  ; \Predisponi PCLATH
         movwf   PCLATH        ; /
         movfw   Reg0          ; \
         call    Tab_Str_Var1  ; |
         andlw   h'FF'         ; |Leggi il carattere
         skpnz                 ; |e scrivilo sull'LCD
         return                ; |
         call    Put_Char      ; |
         inc     Reg0          ; |
         b       SV1_1         ; /
;***************************************************************************
; TABELLE DELLE STRINGHE numero 1
;
; Questa tabella per funzionare deve essere espansa in una pagina ROM
; da xxxx0000 a xxxxFFFF, per evitare errori viene fatto un controllo in
; fase di compilazione.
; Se la condizione non viene rispettata si ha un messaggio di errore di
; fuori pagina
;
; Le ruotine di gestione si trovano nel file LCD.inc
;***************************************************************************
TAB_STR_VAR1    MACRO
                CONSTANT        PCH_STR_VAR1=(HIGH $)
Tab_Str_Var1    movwf   PCL     ;Stringhe
;........................................... Stringhe esempio
STR_1           dt      "Stringa 1",0
STR_2           dt      "Stringa 2",0
STR_3           dt      "Num. 3",0
STR_4           dt      "Num. 4",0
STR_5           dt      "ecc.. ecc... ecc...",0
;.............................................................
        IF      (HIGH ($-1))!=PCH_STR_VAR1
                ERROR "Tabella STRINGHE 1 fuori dalla pagina"
        ENDIF
;.............................................................
                ENDM
Ciao Andrea

 all'indirizzo zero.
Il simulatore di MPLAB :-) ....
--
Ciao Andrea
http://www.geocities.com/SiliconValley/Bay/6146/index.htm

 "pushed" onto the stack (see next section).
Scusa, ma io l'ho detto in italiano perchč l'inglese per me č arabo.
Ciao, Botte!


Scusa ma ho solo detto che per il PIC in questione (il tema era "PIC16F84 e
tabelle in pagina <> 0") non ci si doveva complicare la vita, mica che
questa era una legge assuluta di tutta la famiglia.
Hai ragione ma il concetto era chiaro (almeno nel vuoto della mia testa)
solo che mi riferivo strettamente al PIC in questione.
Il tuo commnento è cqm giustissimo.
Ciao, Botte!

Grazie, pensavo che il mio italiano fosse cosě schifoso che nessuno mi
capiva e cominciavo a pensare che in tutto questo mondo l'unico che non
capiva un tubo ero io, che solitudine.
Ciao, Botte!

 ovviamente non tutti i PIC possiedono tutta questa memoria ma il PICF877.
Quello che volevo dire in sostanza è che i famosi bit IRP da una parte,
RP0+RP1 dall'altra, rappresentano solo un off-set per il puntatore della ram
(o FSR) che nel primo caso (indirizzamento diretto) si compone di soli 7 bit
e quindi necessita di due unità supplementari mentre nel secondo, è un
intero registro di 8 bit quindi basta un solo bit aggiunto.
Ciao, Botte!

 Il simulatore di MPLAB :-) ....
In realta` cosa succede? Ho sempre cercato di evitarlo... :)



OK
"Una delle cose piu' belle della vita e' avere una visione chiare dei nessi
esistenti fra le cose"
A.Einstein


 In realta` cosa succede? Ho sempre cercato di evitarlo... :)
Lo stack e' circolare se superi la fine ti ritrovi all'inizio, viceversa se
scendi sotto l'inizio ti ritrovi alla fine.
In pratica salta sulla locazione memorizzata nella posizione 8 dello stack
... un bel crash!
Ciao Andrea

 Errore lo stack rimane carico!!!!! [...]
Aaaaaah, non avevo letto la prima parte del programma!
Ora ho capito, finalmente. Ultimamente dormo troppo poco. :)


Se devo essere sincero, ho ancora qualche dubbio, ma oggi e' domenica e ci
pensero' nei ritagli di tempo di domani.
Grazie a tutti per la considerazione del mio problema e per la
disponibilita'.
PaoloS

 PaoloS
Ciao!
Se guardi tra i vecchi post anch'io avevo avuto il tuo stesso problema.
Basta che carichi nei due bit piu' significativi dei dieci di PCLATH (i
bit 8 e 9) la pagina dove e' contenuta la tabella, prima della somma
dell'offset con PCLATH.
Ovviamente la tabella non puo' stare a cavallo di due pagine.
CIAO!
-- 
    _/
   _/                                        /"\
  _/     _/_/_/ _/_/_/ _/_/_/                \ /
 _/     _/  _/ _/     _/_/                    X ASCII RIBBON CAMPAIGN
_/_/_/ _/_/_/ _/     _/_/_/                  / \ AGAINST HTML MAIL
Lorenzo Raschi
ICQ #48357220
Fidonet: 2:332/403.0
PGP Key Fingerprint = 71 10 68 82 50 7B 6F C7  A2 07 26 3D 10 60 45 72
Per favore non utilizzate ne' tag html ne' accentate. Grazie.
Inoltre non mandate attachment a questo indirizzo... usate invece
lorenzo...@bo.nettuno.it

Yuppie!!
Finalmente sono riuscito a realizzare qualcosa di piu' complesso dei soliti
LED lampeggianti.
Voglio ringraziarvi tutti, in particolare Andrea Barbadoro che, con il suo
ultimo messaggio, mi ha illuminato sulle tabelle.
Grazie ancora.
PaoloS
P.S.
Adesso sto' testando tutto, ma quando sara' pronto mi farebbe piacere
metterlo in rete. Qualcuno ha un po' di posto, visto che io non ho una home
page?
Si tratta di un contatore con display LCD, 7 pulsanti, gli ingressi Check e
Pulse e le uscite Motor e Brake. Ma se siete interessati, ditemelo che ve ne
parlero' meglio.

 wrote in message 87bsrr$4pe$1...@nslave1.tin.it...

Di posto ne ho a volonta', e' il tempo che mi manca, come puoi vedere dal
mio scarno sito.
http://www.geocities.com/SiliconValley/Bay/6146/index.htm
Se prepari la pagina completa te la pubblico volentieri.
Comunque ci sono anche gli amici di He2 che saranno senz'altro contenti di
pubblicare il tuo lavoro.
http://www.tanzilli.com/users/he2/index_italiano.html
Ciao Andrea.