Ho letto un po' velocemente, ma c'è una cosa che non mi torna. d'accordo che il controller può pilotare display con caratteri 5x10, ma mi sembra che il datasheet dica che il tuo è un 5x7. Comincerei a correggere lì.
Non fai alcun riferimento al segnale R/W dove e come lo hai collegato?
Ciao.
Paolo.
P.S. Perché hai scelto una soluzione a 8 bit? Di solito si va sui 4 bit, per risparmiare pin...
Ciao.
Paolo.
PIC E DISPLAY LCD
Moderatore:
Paolino
0
voti
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
Sono riuscito a far comparire un stringa sull'LCD, inserendo un ritardo iniziale di circa 3s e di ritardi intermedi di 20ms nella routine di inizializzazione LCD_start; sono tempi estremi che provvederò a ridurre, ma era solo per capire la causa di questo problema. Ho cambiato altri ritardi come quello relativo all'enable.
C'è però un problema, terminata la scrittura per qualche motivo il display si reinizializza e ripete il programma, quindi immagino sia un problema di reset del PIC che non riesco a spiegarmi.
Si Paolino, mi sono dimenticato di specificare come è collegato R/W: è connesso direttamente a massa; per quanto riguarda le dimensioni del carattere sono 5x8dots (c'era un mio errore nel commento ed anche nella tabella del datasheet
)
Ho notato che effettivamente la maggior parte delle routine di questo tipo comanda gli LCD in modalità 4 bit, ma per capire a fondo la questione ho deciso di partire dalle basi.
Main.c
Estratto da LCD_2x16_8bit.c
C'è però un problema, terminata la scrittura per qualche motivo il display si reinizializza e ripete il programma, quindi immagino sia un problema di reset del PIC che non riesco a spiegarmi.
Si Paolino, mi sono dimenticato di specificare come è collegato R/W: è connesso direttamente a massa; per quanto riguarda le dimensioni del carattere sono 5x8dots (c'era un mio errore nel commento ed anche nella tabella del datasheet
Ho notato che effettivamente la maggior parte delle routine di questo tipo comanda gli LCD in modalità 4 bit, ma per capire a fondo la questione ho deciso di partire dalle basi.
Main.c
- Codice: Seleziona tutto
#include "init.h" // included by C-Wiz
#include <htc.h>
#include <stdio.h>
#include <delay.c>
#include <math.h>
#include <LCD_2x16_8bit.c>
void Delay250(unsigned char s); // Ritardo s volte 250ms
void
main(void)
{
init(); // Function call inserted by C-Wiz
TRISB=0; // PORTB impostati come output
TRISC=0; // PORTC impostati come output
Delay250(12);
LCD_start();
LCD_writestring("V=12,5V",1,1);
}
void Delay250(unsigned char s)
{
unsigned char i;
for(i=1;i<=s;i++)
DelayMs(250);
}
Estratto da LCD_2x16_8bit.c
- Codice: Seleziona tutto
/* Definizione delle funzioni */
void LCD_send(void) // Aquisizione dati
{// Impulso di abilitazione 0-1-0
EN=1;
DelayMs(20); // 20ms (min 0,22us)
EN=0;
}
void LCD_cls(void) // Cancellazione schermo LCD
{
RS=0;
data=cls;
LCD_send();
DelayMs(20); // 20ms (min 4,1ms)
}
void LCD_start(void) //Inizializzazione LCD
{
RS=0;
EN=0;
DelayMs(20); // 20ms (min 15ms)
data=0b00110000;
LCD_send();
DelayMs(20); // 20ms
LCD_send();
DelayMs(20); // 20mus (min 100us)
LCD_send();
DelayMs(20); // 20ms
data=0b00111100; // Interfaccia 8bit, display a 2 linee, caratteri 5x8dots
LCD_send();
DelayMs(20); // 20ms
data=0b00001111; // Display on, cursore on, lampeggio on
LCD_send();
data=0b00000110; //Set Entry mode
LCD_send();
DelayMs(20); // 20ms
LCD_cls(); // Pulitura display
DelayMs(20); // 20ms
}
Ciao ...NRG...
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
-

NRG Power
115 2 5 - Expert EY

- Messaggi: 302
- Iscritto il: 14 gen 2005, 23:04
- Località: Stoccarda, Germania
0
voti
Adesso funziona!!
Non era un problema di reset, bensì non avevo aggiunto un ciclo infinito for(;;) al termine del main. Il dubbio mi è venuto analizzando un programma d'esempio in dotazione al software di sviluppo.
Main.c
Onestamente non mi è comunque chiaro il motivo; c'è da dire che fino ad ora in quei pochi programmi che ho realizzato presentavano nel modulo principale un ciclo infinito: in assenza di questo, nel momento in cui viene eseguita l'ultima istruzione il PIC si reinizializza quindi? In teoria non dovrebbe essere così, ma perché precedentemente si resettava in assenza del ciclo infinito?...C 'è qualcosa che non mi torna....
Main.c
- Codice: Seleziona tutto
#include "init.h" // included by C-Wiz
#include <htc.h>
#include <stdio.h>
#include <delay.c>
#include <math.h>
#include <LCD_2x16_8bit.c>
void Delay250(unsigned char s); // Ritardo s volte 250ms
void
main(void)
{
init(); // Function call inserted by C-Wiz
TRISB=0; // PORTB impostati come output
TRISC=0; // PORTC impostati come output
Delay250(12);
LCD_start();
LCD_writestring("V=12,5V",1,1);
for(;;); // AGGIUNTO CICLO INFINITO!!!!!
}
void Delay250(unsigned char s)
{
unsigned char i;
for(i=1;i<=s;i++)
DelayMs(250);
}
Onestamente non mi è comunque chiaro il motivo; c'è da dire che fino ad ora in quei pochi programmi che ho realizzato presentavano nel modulo principale un ciclo infinito: in assenza di questo, nel momento in cui viene eseguita l'ultima istruzione il PIC si reinizializza quindi? In teoria non dovrebbe essere così, ma perché precedentemente si resettava in assenza del ciclo infinito?...C 'è qualcosa che non mi torna....

Ciao ...NRG...
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
-

NRG Power
115 2 5 - Expert EY

- Messaggi: 302
- Iscritto il: 14 gen 2005, 23:04
- Località: Stoccarda, Germania
0
voti
Dopo l'ultima istruzione valida, il registro Program Counter si incrementa di un indirizzo e punta a... fuffa! In sostanza si trova davanti a una istruzione e alle successive che cerca di eseguire ma che non rappresentano niente. Se la program memory è sporca a tal punto da creare degli errori in grado di generare overflow dello stack pointer, non è improbabile che la CPU venga resettata.
Ciao.
Paolo.
Ciao.
Paolo.
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
Paolino ha scritto:Dopo l'ultima istruzione valida, il registro Program Counter si incrementa di un indirizzo e punta a... fuffa! In sostanza si trova davanti a una istruzione e alle successive che cerca di eseguire ma che non rappresentano niente. Se la program memory è sporca a tal punto da creare degli errori in grado di generare overflow dello stack pointer, non è improbabile che la CPU venga resettata.
Grazie Paolino, ma questo comportamento si può ritenere diciamo "normale" (in particolare con programmi di questo tipo con chiamate a subroutine) od è sintomo di qualcosa che non va a livello circuitale o di programmazione: ti riferisci a program memoy "sporca", cosa intendi esattamente ?
Grazie di nuovo
Ciao ...NRG...
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
-

NRG Power
115 2 5 - Expert EY

- Messaggi: 302
- Iscritto il: 14 gen 2005, 23:04
- Località: Stoccarda, Germania
0
voti
però un PIC non si resetta per un overflow dello stack
"Computers, operating systems, networks are a hot mess. They're barely manageable, even if you know a decent amount about what you're doing. Nine out of ten software engineers agree: it's a miracle anything works at all."
@fasterthanlime
@fasterthanlime
0
voti
E chi può dire cosa accade quando lo stack va in overflow? Se viene pescato dallo stack (per errore) un'istruzione di reset (roba sporca presente in program memory) o un jump all'indirizzo di reset vector, allora la CPU può far cose strane. Magari anche resettarsi! Non sono in grado di dire cosa potrebbe accadere ai bit del registro di stato: il comportamento diventa imprevedibile.
La cosa più probabile, almeno questo è quanto si sperimenta senza il while(1) a fine codice, è che il PIC sembra addormentato. Anche se ho avuto modo di vedere firmware che facevano proprio quello che dice NRG: continui ed inspiegabili reset.
Ciao.
Paolo.
La cosa più probabile, almeno questo è quanto si sperimenta senza il while(1) a fine codice, è che il PIC sembra addormentato. Anche se ho avuto modo di vedere firmware che facevano proprio quello che dice NRG: continui ed inspiegabili reset.
Ciao.
Paolo.
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
Sto riscrivendo la routine per la scrittura di un numero decimale su LCD: la funzione scompone il numero nella parte intera e frazionaria, memorizzandole in due vettori tipo char (vettore_parte_intera[] e vettore_parte_decimale[]); successivamente, attraverso un ciclo for stampa ogni elemento numerico del vettore (che ricordo essere di tipo char) su LCD attraverso la semplice routine per la scrittura di un carattere che riporto nuovamente qui sotto:
Il problema, che ritengo stupido risiede proprio in quest'ultima fase, ed è legato al fatto che non riesco a far acquisire correttamente l'elemento numerico tipo char come carattere.
Supponiamo per es. che un elemento del vettore, sia il numero 4 (vettore_parte_intera[0]=4), devo far acqusire il carattere '4', ovvero nella funzione LCD_writechar, la variabile character dovrà essere pari al codice ASCII corrispondente ossia 52 . Si tratta dunque di convertire un tipo char (in tal caso numerico) nel corrispondente codice ASCII.
Ho provato ad effettuare una conversione di dato,
Ma stranamente niente da fare, restituisce nuovamente dei caratteri indefinibili. Immagino che abbia visualizzato il codice ASCII corrispondente al numero 4 (che ad onor del vero nella tabella dei caratteri dell'LCD non è definito), come accadeva prima in assenza di conversione di dato.
Se ad esempio scrivo:
ovviamente funziona, analogamente se scrivo il numero 4 come carattere,
- Codice: Seleziona tutto
void LCD_writechar(unsigned char character,unsigned char row, unsigned char col) // Scrittura carattere su LCD
{
LCD_gotoxy(row,col); // Posizionamento cursore alle coordinate (row, col) specificate
LCD_write(character); // Scrittura carattere
}
Il problema, che ritengo stupido risiede proprio in quest'ultima fase, ed è legato al fatto che non riesco a far acquisire correttamente l'elemento numerico tipo char come carattere.
Supponiamo per es. che un elemento del vettore, sia il numero 4 (vettore_parte_intera[0]=4), devo far acqusire il carattere '4', ovvero nella funzione LCD_writechar, la variabile character dovrà essere pari al codice ASCII corrispondente ossia 52 . Si tratta dunque di convertire un tipo char (in tal caso numerico) nel corrispondente codice ASCII.
Ho provato ad effettuare una conversione di dato,
- Codice: Seleziona tutto
LCD_writechar((int)vettore_parte_intera[0],row,col);
Ma stranamente niente da fare, restituisce nuovamente dei caratteri indefinibili. Immagino che abbia visualizzato il codice ASCII corrispondente al numero 4 (che ad onor del vero nella tabella dei caratteri dell'LCD non è definito), come accadeva prima in assenza di conversione di dato.
Se ad esempio scrivo:
- Codice: Seleziona tutto
LCD_writechar(52,row,col);
ovviamente funziona, analogamente se scrivo il numero 4 come carattere,
- Codice: Seleziona tutto
LCD_writechar('4',row,col);
Ciao ...NRG...
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
-

NRG Power
115 2 5 - Expert EY

- Messaggi: 302
- Iscritto il: 14 gen 2005, 23:04
- Località: Stoccarda, Germania
0
voti
Ciao NRG.
Prova con:
In questo modo ti "sposti" sulla tabella ASCII e vai a puntare al carattere '0' cui vai a sommare il dato che vuoi visualizzare. Pertanto, se vuoi visualizzare il carattere 4, facendo '0'+4 il compilatore ha come risultato il codice ASCC di '0' (che è 48) + 4 = 52.
In alternativa, puoi anche fare:
Spero sia stato chiaro
Ciao.
Paolo.
Prova con:
- Codice: Seleziona tutto
void LCD_writechar(unsigned char character,unsigned char row, unsigned char col) // Scrittura carattere su LCD
{
LCD_gotoxy(row,col); // Posizionamento cursore alle coordinate (row, col) specificate
LCD_write(character+'0'); // Scrittura carattere
}
In questo modo ti "sposti" sulla tabella ASCII e vai a puntare al carattere '0' cui vai a sommare il dato che vuoi visualizzare. Pertanto, se vuoi visualizzare il carattere 4, facendo '0'+4 il compilatore ha come risultato il codice ASCC di '0' (che è 48) + 4 = 52.
In alternativa, puoi anche fare:
- Codice: Seleziona tutto
void LCD_writechar(unsigned char character,unsigned char row, unsigned char col) // Scrittura carattere su LCD
{
LCD_gotoxy(row,col); // Posizionamento cursore alle coordinate (row, col) specificate
LCD_write(character+48); // Scrittura carattere
}
Spero sia stato chiaro
Ciao.
Paolo.
"Houston, Tranquillity Base here. The Eagle has landed." - Neil A.Armstrong
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-------------------------------------------------------------
PIC Experience - http://www.picexperience.it
-

Paolino
32,6k 8 12 13 - G.Master EY

- Messaggi: 4226
- Iscritto il: 20 gen 2006, 11:42
- Località: Vigevano (PV)
0
voti
[100] Re: PIC E DISPLAY LCD
Paolino ha scritto:Ciao NRG.
Prova con:
- Codice: Seleziona tutto
void LCD_writechar(unsigned char character,unsigned char row, unsigned char col) // Scrittura carattere su LCD
{
LCD_gotoxy(row,col); // Posizionamento cursore alle coordinate (row, col) specificate
LCD_write(character+'0'); // Scrittura carattere
}
In questo modo ti "sposti" sulla tabella ASCII e vai a puntare al carattere '0' cui vai a sommare il dato che vuoi visualizzare. Pertanto, se vuoi visualizzare il carattere 4, facendo '0'+4 il compilatore ha come risultato il codice ASCC di '0' (che è 48) + 4 = 52.
Metodo maleficus
Grazie veramente
. Quando terminerò l'intero codice anche per la versione a 4bit, lo riporterò in questa discussione.
Ciao ...NRG...
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
« Un giorno la paura bussò alla porta, il coraggio andò ad aprire ma non trovò nessuno » - J.W. Goethe
-

NRG Power
115 2 5 - Expert EY

- Messaggi: 302
- Iscritto il: 14 gen 2005, 23:04
- Località: Stoccarda, Germania
Torna a Realizzazioni, interfacciamento e nozioni generali.
Chi c’è in linea
Visitano il forum: Nessuno e 6 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)
