Vi pongo il problema:
A scuola stiamo preparando un bel progetto che comprende microcontrollori, trasduttori, meccanica, display appunto e altre diavolerie.....io ho il compito di creare delle funzioni e codici in C col PIC Pierin per poter scrivere dei dati su questo piccolo schermo.
Il modello è LGM12864B-NSW-BBS.
Dopo vari tentativi, guide, ecc... mi devo arrendere e cercare l'aiuto di qualche buona anima perché non avendo mai avuto una minima esperienza in questo campo non so proprio come fare!!!
Il datasheet penso di saperlo a memoria (anche perché molto breve)....ecco il codice che ho scritto in MPLAB-IDE
- Codice: Seleziona tutto
// File di definizione dei registri del micro.
#include "p18f47j53.h"
// File di configurazione dei fuses
#include "configurazione.h"
// Mappatura delle interrupt
#include "mappa_int.h"
// Header del main
#include "main.h"
//Dichiaro del funzioni dase per LCD Display
//////////////////////////////////////////////////////////////////////////////////////// SCRITTURA/LETTURA
//scrittura
#define GLCD_CS1(n) LATBbits.LATB0 = (n)
#define GLCD_CS2(n) LATBbits.LATB1 = (n)
#define GLCD_RS(n) LATBbits.LATB2 = (n)
#define GLCD_RST(n) LATBbits.LATB5 = (n)
#define GLCD_RW(n) LATBbits.LATB3 = (n)
#define GLCD_E(n) LATBbits.LATB4 = (n)
#define GLCD_D0(n) LATDbits.LATD0 = (n)
#define GLCD_D1(n) LATDbits.LATD1 = (n)
#define GLCD_D2(n) LATDbits.LATD2 = (n)
#define GLCD_D3(n) LATDbits.LATD3 = (n)
#define GLCD_D4(n) LATDbits.LATD4 = (n)
#define GLCD_D5(n) LATDbits.LATD5 = (n)
#define GLCD_D6(n) LATDbits.LATD6 = (n)
#define GLCD_D7(n) LATDbits.LATD7 = (n)
//lettura
#define GLCD_D0_Read PORTDbits.RD0
#define GLCD_D1_Read PORTDbits.RD1
#define GLCD_D2_Read PORTDbits.RD2
#define GLCD_D3_Read PORTDbits.RD3
#define GLCD_D4_Read PORTDbits.RD4
#define GLCD_D5_Read PORTDbits.RD5
#define GLCD_D6_Read PORTDbits.RD6
#define GLCD_D7_Read PORTDbits.RD7
/////////////////////////////////////////////////////////////////////////////////////////////// DEFINIZIONE TRIS SOLO OUT
#define GLCD_TRIS_CS1 TRISBbits.TRISB0 = 1
#define GLCD_TRIS_CS2 TRISBbits.TRISB1 = 1
#define GLCD_TRIS_RS TRISBbits.TRISB2 = 1
#define GLCD_TRIS_RST TRISBbits.TRISB5 = 1
#define GLCD_TRIS_RW TRISBbits.TRISB3 = 1
#define GLCD_TRIS_E TRISBbits.TRISB4 = 1
/////////////////////////////////////////////////////////////////////////////////////////////// DEFINIZIONE TRIS IN/OUT
#define GLCD_TRIS_D0_IN TRISDbits.TRISD0 = 1
#define GLCD_TRIS_D1_IN TRISDbits.TRISD1 = 1
#define GLCD_TRIS_D2_IN TRISDbits.TRISD2 = 1
#define GLCD_TRIS_D3_IN TRISDbits.TRISD3 = 1
#define GLCD_TRIS_D4_IN TRISDbits.TRISD4 = 1
#define GLCD_TRIS_D5_IN TRISDbits.TRISD5 = 1
#define GLCD_TRIS_D6_IN TRISDbits.TRISD6 = 1
#define GLCD_TRIS_D7_IN TRISDbits.TRISD7 = 1
#define GLCD_TRIS_D0_OUT TRISDbits.TRISD0 = 0
#define GLCD_TRIS_D1_OUT TRISDbits.TRISD1 = 0
#define GLCD_TRIS_D2_OUT TRISDbits.TRISD2 = 0
#define GLCD_TRIS_D3_OUT TRISDbits.TRISD3 = 0
#define GLCD_TRIS_D4_OUT TRISDbits.TRISD4 = 0
#define GLCD_TRIS_D5_OUT TRISDbits.TRISD5 = 0
#define GLCD_TRIS_D6_OUT TRISDbits.TRISD6 = 0
#define GLCD_TRIS_D7_OUT TRISDbits.TRISD7 = 0
////////////////////////////////////////////////////////////////////////////////////////////////////
#define PAUSA_E ritardo(1)
#define PAUSA_INIT ritardo(100)
//------------------------------------------------------------------------------
// Variabili globali
//------------------------------------------------------------------------------
#pragma udata
volatile unsigned short timer_delay; // Timer software
unsigned char TRIS_BUS;
// ------------------------------------------------------
// GLCD Picture name: Immagine.bmp
// GLCD Model: KS0108 128x64
// ------------------------------------------------------
//------------------------------------------------------------------------------
// Funzione di servizio delle interrupt ad ALTA priorità
//------------------------------------------------------------------------------
#pragma code
#pragma interrupt highPriorityInterrupt
void highPriorityInterrupt()
{
// Verifica quale flag ha causato l' interrupt
// Esegui la parte di codice di servizio dell' interrupt
// Azzera il flag che ha causato l' interrupt
// ...
}
//------------------------------------------------------------------------------
// Funzione di servizio delle interrupt a BASSA priorità
//------------------------------------------------------------------------------
#pragma interruptlow lowPriorityInterrupt
void lowPriorityInterrupt()
{
// Verifica quale flag ha causato l' interrupt
// Esegui la parte di codice di servizio dell' interrupt
// Azzera il flag che ha causato l' interrupt
// ...
// Gestione dell' interrupt del timer 2
if(PIR1bits.TMR2IF)
{
// gestione del timer software. Il timer software deve decrementarsi
// fino ad arrivare a 0. Una volta arrivato a 0 resta fermo a 0.
if (timer_delay) timer_delay--;
// Resetta il flag che ha generato l' interrupt
PIR1bits.TMR2IF = 0;
}
}
//------------------------------------------------------------------------------
// Prototipi delle funzioni
//------------------------------------------------------------------------------
#pragma code
void timer2_deInit(void);
void ritardo(int x);
void impulso(int x);
//------------------------------------------------------------------------------
// Funzioni
//------------------------------------------------------------------------------
#pragma code
//------------------------------------------------------------------------------
// De-inizializza il timer 2 e lo porta nello stato in cui si trovava
// subito dopo il RESET
void timer2_deInit(void)
{
T2CON = 0; // Resetta il timer 2 control register
TMR2 = 0; // Azzera il contatore interno
PR2 = 0; // Azzera il registro comparatore
PIE1bits.TMR2IE = 0; // Disabilita l' interrupt
IPR1bits.TMR2IP = 0; // Resetta il bit di priorità dell' interrupt
PIR1bits.TMR2IF = 0; // Azzera il flag di interrupt
}
void ritardo(int x)
{
timer_delay = x;
for(;;){
if(!timer_delay){
break;}
} }
//FUNZIONI DEL DISPLAY
//Questa funzione la useremo al momento di leggere o scrivere qualcosa dal bus dati del display
void Enable_Strobe(void){
GLCD_E(1);
PAUSA_E;
GLCD_E(0);
PAUSA_E;
}
//Effettua il reset del display !!Attenzione non è LCD_Clear dopo il reset il display va reinizializzato!!!
void GLCD_RESETcmd(void){
//Reset LCD
GLCD_RST(1);
PAUSA_INIT;
GLCD_RST(0);
PAUSA_INIT;
GLCD_RST(1);
PAUSA_INIT;
}
//IMPOSTO LE PORTE D COME OUTPUT O INPUT (0 output, 1 input)
void GLCD_Set_Port(unsigned char ch)
{
if(ch == 1){
TRIS_BUS = 1;
GLCD_TRIS_D0_IN;
GLCD_TRIS_D1_IN;
GLCD_TRIS_D2_IN;
GLCD_TRIS_D3_IN;
GLCD_TRIS_D4_IN;
GLCD_TRIS_D5_IN;
GLCD_TRIS_D6_IN;
GLCD_TRIS_D7_IN;
}
else{
TRIS_BUS = 0;
GLCD_TRIS_D0_OUT;
GLCD_TRIS_D1_OUT;
GLCD_TRIS_D2_OUT;
GLCD_TRIS_D3_OUT;
GLCD_TRIS_D4_OUT;
GLCD_TRIS_D5_OUT;
GLCD_TRIS_D6_OUT;
GLCD_TRIS_D7_OUT;
}
PAUSA_E;
}
////////////////////////////////////////////////////////////////////////////////CONTROLLA LE PORTE DATI
//scrive un dato nel bus
void GLCD_Ctrl_Port(unsigned char ch){
if(TRIS_BUS == 1){GLCD_Set_Port(0);}//Se il bus dati è configurato come input lo riconfigura come output
if(ch & 1){GLCD_D0(1);}else{GLCD_D0(0);}
if(ch & 2){GLCD_D1(1);}else{GLCD_D1(0);}
if(ch & 4){GLCD_D2(1);}else{GLCD_D2(0);}
if(ch & 8){GLCD_D3(1);}else{GLCD_D3(0);}
if(ch & 16){GLCD_D4(1);}else{GLCD_D4(0);}
if(ch & 32){GLCD_D5(1);}else{GLCD_D5(0);}
if(ch & 64){GLCD_D6(1);}else{GLCD_D6(0);}
if(ch & 128){GLCD_D7(1);}else{GLCD_D7(0);}
}
////////////////////////////////////////////////////////////////////////////////LEGGE LE PORTE DATI
unsigned char GLCD_Ctrl_Port_Read(void){
unsigned char ch = 0;
if(TRIS_BUS == 0){GLCD_Set_Port(1);} //Se il bus dati è configurato come output lo riconfigura come input
if(GLCD_D7_Read == 1){ch=ch | 128;}
if(GLCD_D6_Read == 1){ch=ch | 64;}
if(GLCD_D5_Read == 1){ch=ch | 32;}
if(GLCD_D4_Read == 1){ch=ch | 16;}
if(GLCD_D3_Read == 1){ch=ch | 8;}
if(GLCD_D2_Read == 1){ch=ch | 4;}
if(GLCD_D1_Read == 1){ch=ch | 2;}
if(GLCD_D0_Read == 1){ch=ch | 1;}
return ch;
}
////////////////////////////////////////////////////////////////////////////////INVIA UN DATO all'LCD GRAFICO
//invio un dato al controller del display selezionandolo tramite la varabile chip & chop
//Ch è il valore da inviare
//colore invece se == 2 inverte i byte (negativo)
void Write_Data(unsigned char ch, unsigned char chip, unsigned char colore)
{
if(chip == 1){GLCD_CS1(1);GLCD_CS2(0);} //seleziono il chip 1
else{GLCD_CS1(0);GLCD_CS2(1);} // seleziono il chip 2
GLCD_RW(0); //scrivo
GLCD_RS(1); //invio un dato
if(colore==2){GLCD_Ctrl_Port(~ch);}
else{GLCD_Ctrl_Port(ch);}
Enable_Strobe();
}
////////////////////////////////////////////////////////////////////////////////INVIA UN COMANDO all'LCD GRAFICO
//Invia un comando al display
void Write_Cmd(unsigned char ch,unsigned char chip){
if(chip == 1){GLCD_CS1(1);GLCD_CS2(0);} //seleziono il chip 1
else{GLCD_CS1(0);GLCD_CS2(1);} //seleziono il chip 2
GLCD_RW(0); //scrivo
GLCD_RS(0); //invio un comando
GLCD_Ctrl_Port(ch);
Enable_Strobe();
}
////////////////////////////////////////////////////////////////////////////////LEGGE UN DATO dall'LCD GRAFICO
//legge un dato dal display selezionato tramite comando
unsigned char Read_Data(unsigned char chip){
unsigned char ch;
if(chip == 1){GLCD_CS1(1);GLCD_CS2(0);} //seleziono il chip 1
else{GLCD_CS1(0);GLCD_CS2(1);} //seleziono il chip 2
GLCD_RW(1); //leggo
GLCD_RS(1); //leggo un dato
GLCD_E(1);
PAUSA_E;
ch=GLCD_Ctrl_Port_Read();
GLCD_E(0);
PAUSA_E;
return ch;
}
////////////////////////////////////////////////////////////////////////////////SET Y START ADD
void GLCD_SetY_StartAdd(unsigned char ch,unsigned char chip){
if(ch <= 63){
Write_Cmd((ch | 0b11000000),chip);
}
}
////////////////////////////////////////////////////////////////////////////////SET Y ADD
void GLCD_SetY_Add(unsigned char ch,unsigned char chip){
if(ch <= 63){
Write_Cmd((ch | 0b01000000),chip);
}
}
////////////////////////////////////////////////////////////////////////////////SET PAGE ADD
void GLCD_SetPage_Add(unsigned char ch,unsigned char chip){
if(ch <= 7){
Write_Cmd((ch | 0b10111000),chip);
}
}
////////////////////////////////////////////////////////////////////////////////DISPLAY LDC ON/OFF
void GLCD_ON(unsigned char ch,unsigned char chip){
if(ch <= 1){
Write_Cmd((ch | 0b00111110),chip);
}
}
////////////////////////////////////////////////////////////////////////////////scrive lo stesso byte su tutta la pagina
void GLCD_Clear_Page(unsigned char ch,unsigned char chip,unsigned char page){
unsigned char i;
GLCD_SetPage_Add(page,chip);
GLCD_SetY_Add(0,chip);
for(i=0;i<64;i++){
Write_Data(ch,chip,0);
}
}
////////////////////////////////////////////////////////////////////////////////CHIP CLEAR
void GLCD_Clear_Chip(unsigned char ch,unsigned char chip){
unsigned char i;
for(i=0;i<8;i++){
GLCD_Clear_Page(ch,chip,i);}
}
////////////////////////////////////////////////////////////////////////////////GLCD CLEAR
void GLCD_ClearAll(void){
GLCD_Clear_Chip(0,1);
GLCD_Clear_Chip(0,2);
}
////////////////////////////////////////////////////////////////////////////////LEGGI un BYTE dall'LCD
unsigned char GLCD_ReadByte(unsigned char page,unsigned char y,unsigned char chip){
unsigned char ch;
GLCD_SetPage_Add(page,chip);
GLCD_SetY_Add(y,chip);
ch=Read_Data(chip);
return ch;
}
////////////////////////////////////////////////////////////////////////////////Scrive un BYTE sull'LCD
void GLCD_WriteByte(unsigned char ch,unsigned char color,unsigned char page,unsigned char y,unsigned char chip){
GLCD_SetPage_Add(page,chip);
GLCD_SetY_Add(y,chip);
Write_Data(ch,chip,color);
}
////////////////////////////////////////////////////////////////////////////////INIZIALIZZA l'LCD GRAFICO
void GLCD_My_init(void){
unsigned char ch=0;
///////////////////Inizializzo le porte del processore
GLCD_Set_Port(0);
GLCD_TRIS_CS1;
GLCD_TRIS_CS2;
GLCD_TRIS_RS;
GLCD_TRIS_RST;
GLCD_TRIS_RW;
GLCD_TRIS_E;
GLCD_Ctrl_Port(0);
GLCD_CS1(0);
GLCD_CS2(0);
GLCD_RW(0);
GLCD_RS(0);
GLCD_E(0);
PAUSA_INIT;
GLCD_RESETcmd();//Reset GLCD
//Protocollo di inizializzazione Vedi Datasheet
//Imposto lo zero nell'asse Y
GLCD_SetY_StartAdd(0,1);PAUSA_INIT;
GLCD_SetY_StartAdd(0,2);PAUSA_INIT;
//Posiziono il puntatore dell'asse Y sul punto 0
GLCD_SetY_Add(0,1);PAUSA_INIT;
GLCD_SetY_Add(0,2);PAUSA_INIT;
//Posiziono il cursore nella pagina 0
GLCD_SetPage_Add(0,1);PAUSA_INIT;
GLCD_SetPage_Add(0,2);PAUSA_INIT;
//invio il cmd di accensione!!
GLCD_ON(1,1);PAUSA_INIT;
GLCD_ON(1,2);PAUSA_INIT;
//Ed infine lo "LAVO"
GLCD_ClearAll();PAUSA_INIT;
}
void GLCD_XY_byte(unsigned char x,unsigned char y, unsigned char *Yp,unsigned char *page,unsigned char *chip){
if(y>55){*page=7; goto out;}
if(y>47){*page=6; goto out;}
if(y>39){*page=5; goto out;}
if(y>31){*page=4; goto out;}
if(y>23){*page=3; goto out;}
if(y>15){*page=2; goto out;}
if(y>7) {*page=1; goto out;}
else{ *page=0; }
out:
if(x > 63){*chip=1;*Yp=x-64;}else{*chip=2;*Yp=x;}
}
void GLCD_Goto_XY(unsigned char x,unsigned char y){
unsigned char Yp,page,chip;
GLCD_XY_byte(x,y,&Yp,&page,&chip);
GLCD_SetPage_Add(page,chip);
GLCD_SetY_Add(Yp,chip);
}
////////////////////////////////////////////////////////////////////////////////Scrivo un byte con coordinate X,Y
void GLCD_WriteByte_XY(unsigned char ch,unsigned char color,unsigned char x,unsigned char y){
unsigned char Yp,page,chip;
GLCD_XY_byte(x,y,&Yp,&page,&chip);
GLCD_WriteByte(ch,color,page,Yp,chip);
}
////////////////////////////////////////////////////////////////////////////////Leggo un byte con coordinate X,Y
unsigned char GLCD_ReadByte_XY(unsigned char x,unsigned char y){
unsigned char Yp,page,chip,ch;
GLCD_XY_byte(x,y,&Yp,&page,&chip);
ch=GLCD_ReadByte(page,Yp,chip);
return ch;
}
///////////////////////////////////////////////////////////////////////////////Scrivo vera e propria immagine
void GLCD_WriteForImm(unsigned char const immagine[],unsigned char color,unsigned char l,unsigned char h,unsigned char x,unsigned char y){
unsigned char xImm,yImm;
unsigned int xArr=0;
for(yImm=0;yImm<h;){
for(xImm=0;xImm<l;xImm++){
GLCD_WriteByte_XY(immagine[xArr],color,(x+xImm),(y+yImm));
xArr=xArr+1;
}
yImm=yImm+8;}
}
//------------------------------------------------------------------------------
// MAIN
void main(void)
{
char Immagine[16] = {1,2,3,4,5,4,2,3,4,2,3,5,6,2,2,3};
// Fa partire il PLL.
// Anche se viene selezionato tramite i bit di configurazione
// il suo funzionamento non è automatico. Ha bisogno di un comando.
OSCTUNEbits.PLLEN = 1;
// Attende abbastanza tempo per far stabilizzare il PLL
Delay1KTCYx(100);
// Da ora in poi abbiamo il PLL funzionante ed il micro con il turbo.
// -------- Inizializzazione delle periferiche --------
// De-inizializza il timer2. Non sarebbe necessario perché il micro esce
// allo stato di RESET ma è comunque buona pratica de-inizializzare sempre
// le periferiche per non tralasciare nessun bit.
timer2_deInit();
// Inizializza il timer 2 per interrupt ogni millisecondo.
// prescaler divide per 16
T2CONbits.T2CKPS = 2;
// Postscaler divide per 5
T2CONbits.T2OUTPS = 4;
// Imposta il valore comparatore a 150
PR2 = 150;
// Imposta l' interrupt del Timer 2 a priorita' bassa
IPR1bits.TMR2IP = 0;
// abilita interrupt del timer
PIE1bits.TMR2IE = 1;
// -------- Selezione ed abilitazione delle interrupt --------
// Ora che si sono inizializzate tutte le periferiche si possono abilitare
// Oppurtunamente le interrupt
// abilita le interrupt a bassa priorita'
RCONbits.IPEN = 1;
// abilta tutte le interrupt a priorità bassa
INTCONbits.GIEL = 1;
// Abilita tutte le interrupt in generale
INTCONbits.GIEH = 1;
// -------- Attivazione delle periferiche --------
// Con le interrupt abilitate possiamo ora far partire il timer 2
// Accende il timer
T2CONbits.TMR2ON = 1;
// Inizializza la variabile che funge da timer software
timer_delay = 0;
// Inizializza la variabile di conteggio
GLCD_My_init();
// -------------- Ciclo infinito di funzionamento -------------
for(;;)
{
GLCD_WriteForImm(Immagine[],0,32,8,0,0);
} // for(;;)
}
Cosa non va??

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)




