Il software funziona ma e' stato buttato giu' di getto ed ha bisogno di una bella cura di bellezza, infatti mancano tutti i prototipi che, di solito metto quando ho la certezza che tutto funzioni.
Comunque spero di far cosa gradita, anche solo come curiosita', nel metterlo qui di seguito.
- Codice: Seleziona tutto
#include "mpu_config.h"
#include "app_defs.h"
#include <plib.h>
#include <p32xxxx.h>
#define SYS_FREQ (80000000)
#define SYS_FREQ_KHZ (80000)
// defines per l' assegnazione dei pin di uscita per il comando del modulo LCD
#define LCD_EN LATEbits.LATE4
#define LCD_EN_DIR TRISEbits.TRISE4
#define LCD_RS LATEbits.LATE5
#define LCD_RS_DIR TRISEbits.TRISE5
#define LCD_D4 LATEbits.LATE0
#define LCD_D4_DIR TRISEbits.TRISE0
#define LCD_D5 LATEbits.LATE1
#define LCD_D5_DIR TRISEbits.TRISE1
#define LCD_D6 LATEbits.LATE2
#define LCD_D6_DIR TRISEbits.TRISE2
#define LCD_D7 LATEbits.LATE3
#define LCD_D7_DIR TRISEbits.TRISE3
short lcd_curs_pos_x; // posizione x attuale del cursore
short lcd_curs_pos_y; // posizione y attuale del cursore
short lcd_size_x; // numero di caratteri per riga
short lcd_size_y; // numero di righe del display
short lcd_hardware_lines; // numero di linee hardware gestite dal controllore
char lcd_screen[80]; // array che contiene l'immagine del display
int lcd_chr_delay; // ritardo in millisecondi per l' invio di stringhe
/*****************************************************************************/
/* delay_ms */
/* This functions provides a software millisecond delay. It uses the */
/* core timer. */
/*****************************************************************************/
void delay_ms(unsigned int msec)
{
unsigned int tWait, tStart;
tWait=(SYS_FREQ/2000)*msec;
tStart=ReadCoreTimer();
while((ReadCoreTimer()-tStart)<tWait); // wait for the time to pass
}
/*****************************************************************************/
/* delay_us */
/* This functions provides a software microsecond delay. It uses the */
/* core timer. */
/*****************************************************************************/
void delay_us(unsigned int usec)
{
unsigned int tWait, tStart;
tWait=(SYS_FREQ_KHZ/2000)*usec;
tStart=ReadCoreTimer();
while((ReadCoreTimer()-tStart)<tWait); // wait for the time to pass
}
/*****************************************************************************/
/* lcd_send digit, lcd_send_byte */
/* Funzioni interne per l' invio di un digit e di un byte */
/*****************************************************************************/
void lcd_send_digit(unsigned char n)
{
delay_us(1); // dovrebbe essere di 10ns
n &= 0x0f;
LCD_EN = 1;
// mette il digit un bit alla volta nei pin D4-D7
if (n & 1) LCD_D4 = 1; else LCD_D4 = 0;
if (n & 2) LCD_D5 = 1; else LCD_D5 = 0;
if (n & 4) LCD_D6 = 1; else LCD_D6 = 0;
if (n & 8) LCD_D7 = 1; else LCD_D7 = 0;
delay_us(1); // dovrebbe essere di 80 ns.
LCD_EN = 0;
}
void lcd_send_byte(unsigned char n)
{
lcd_send_digit(n>>4);
lcd_send_digit(n);
}
/*****************************************************************************/
/* lcd_send_cmd */
/* Invia un byte al controllore come comando. Il comando verra' esguito */
/*****************************************************************************/
void lcd_send_cmd(unsigned char n)
{
LCD_RS = 0; // essendo un comando la linea RS va a 0
delay_us(1);
lcd_send_byte(n);
// Ritarda per attendere la completa esecuzione del comando
// questi ritardi sono piu' lunghi di quelli indicati nel datasheet.
// dovrebbero essere di 1520 e 37 us.
if (!(n & 0xfc)) delay_us(1600); else delay_us(40);
}
/*****************************************************************************/
/* lcd_send_data */
/* Invia un byte al controllore come dato. Il dato verra' memorizzato */
/* nella memoria grafica */
/*****************************************************************************/
void lcd_send_data(unsigned char n)
{
LCD_RS = 1; // essendo un dato la linea RS va a 1
delay_us(1);
lcd_send_byte(n);
// Ritarda per attendere la completa esecuzione del comando
// anche questo ritardo dovrebbe essere di 37us
delay_us(40);
}
/*****************************************************************************/
/* lcd_init */
/* Inizializza il display. sx ed sy sono le dimensioni del display */
/* nl e' il numero di linee hardware di cui e' composto il display */
/*****************************************************************************/
void lcd_init(short sx, short sy, short nl)
{
// inizializza le linee di uscita
LCD_EN_DIR = 0;
LCD_EN = 0;
LCD_RS_DIR = 0;
LCD_RS = 0;
LCD_D4_DIR = 0;
LCD_D4 = 0;
LCD_D5_DIR = 0;
LCD_D5 = 0;
LCD_D6_DIR = 0;
LCD_D6 = 0;
LCD_D7_DIR = 0;
LCD_D7 = 0;
delay_ms(15); // aspetta 15ms per stabilizzazione Vcc
// esegue la sequenza di reset, quella che si usa in caso di alimentazione
// che non garantisce un buon reset interno.
LATEbits.LATE5 = 0; // mette RS a 0
lcd_send_digit(0x03);
delay_ms(5); // sul datasheet e' indicato 4,1 ms
lcd_send_digit(0x03);
delay_us(120); // il datasheet indica > 100 us.
lcd_send_digit(0x03);
delay_us(120);
lcd_send_digit(0x02);
delay_us(120);
lcd_send_cmd(0x28); //0x20 per una linea
lcd_send_cmd(0x08);
lcd_send_cmd(0x01);
lcd_send_cmd(0x06);
lcd_send_cmd(0x28); //0x20 per una linea
lcd_send_cmd(0x0d); // lcd acceso e cursore lampeggiante senza cursore a linea
// aggiorna le variabili
lcd_curs_pos_x = lcd_curs_pos_y = 0;
lcd_size_x = sx;
lcd_size_y = sy;
lcd_hardware_lines = nl;
lcd_chr_delay = 0;
}
/*****************************************************************************/
/* lcd_clear */
/* invia il comando di cancellazione del display e riporta a 0 tutti i */
/* caratteri del buffer immagine dell schermo */
/*****************************************************************************/
void lcd_clear(void)
{
short i;
lcd_send_cmd(0x01);
lcd_curs_pos_x = 0;
lcd_curs_pos_y = 0;
for (i=0; i<80; i++) lcd_screen[i] = 0x10;
}
#define lcd_cursor_off() lcd_send_cmd(0x0c);
#define lcd_cursor_on() lcd_send_cmd(0x0d);
/*****************************************************************************/
/* lcd_gotoxy */
/* Posiziona il cursone alle coordinate indicate. L' angolo superiore */
/* sinistro ha come coordinate 0,0 */
/*****************************************************************************/
void lcd_gotoxy(short x, short y)
{
unsigned char ind;
if (lcd_hardware_lines == 2)
switch(y)
{
case 0: ind = x;
break;
case 1: ind = x + 0x40;
break;
case 2: ind = x + lcd_size_x;
break;
case 3: ind = x + lcd_size_x + 0x40;
break;
}
else
{
ind = x + y * lcd_size_x;
}
ind |= 0x80;
lcd_send_cmd(ind);
lcd_curs_pos_x = x;
lcd_curs_pos_y = y;
}
/*****************************************************************************/
/* lcd_curs_nextch */
/* Aggiorna la posizione del cursore sul display dopo che e' stato */
/* to un carattere. Gestisce il ritorno a capo */
/*****************************************************************************/
void lcd_curs_nextch(void)
{
short x,y,i;
lcd_curs_pos_x++;
if ((lcd_curs_pos_x == lcd_size_x) && (lcd_curs_pos_y == (lcd_size_y -1)))
{
// fa lo scroll dello schermo
for ( i=0 ; i<((lcd_size_y-1)*lcd_size_x); i++)
{
lcd_screen[i] = lcd_screen[i+lcd_size_x]; // memorizza i caratteri nel buffer
}
lcd_send_cmd(0x01);
i = 0;
for (y=0;y<(lcd_size_y-1);y++)
for (x=0;x<lcd_size_x;x++)
{
lcd_gotoxy(x,y);
lcd_send_data(lcd_screen[i]);
i++;
}
lcd_gotoxy(0,lcd_size_y-1);
}
else // non deve fare lo scroll
{
if (!(lcd_curs_pos_x % lcd_size_x) && lcd_curs_pos_x)
{
lcd_curs_pos_y++;
if (lcd_curs_pos_y == lcd_size_y) lcd_gotoxy(0,0); else lcd_gotoxy(0,lcd_curs_pos_y);
}
}
}
/*****************************************************************************/
/* lcd_screen_update */
/* Funzione di aggiornamento dell' immagine dello schermo */
/*****************************************************************************/
void lcd_screen_update(char c)
{
lcd_screen[lcd_curs_pos_x + lcd_curs_pos_y * lcd_size_x] = c;
}
/*****************************************************************************/
/* lcd_write_char */
/* Scrive un carattere, aggiorna l' immagine dello schermo e non */
/* introduce nessun ritardo di visualizzazione */
/*****************************************************************************/
void lcd_write_char(char c)
{
lcd_send_data(c);
lcd_screen_update(c);
lcd_curs_nextch();
}
/*****************************************************************************/
/* lcd_write_text */
/* Scrive la stringa a partire dalla posizione attuale del cursore */
/*****************************************************************************/
void lcd_write_text(char *s)
{
while(*s)
{
lcd_send_data(*s);
lcd_screen_update(*s);
s++;
if (lcd_chr_delay) delay_ms(lcd_chr_delay);
lcd_curs_nextch();
}
}
/*****************************************************************************/
/* main */
/*****************************************************************************/
int main(void)
{
int i;
// KEY CONCEPT - Configure the device for maximum performance, but do not change the PBDIV clock divisor.
// Given the options, this function will change the program Flash wait states,
// RAM wait state and enable prefetch cache, but will not change the PBDIV.
// The PBDIV value is already set via the pragma FPBDIV option above.
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
lcd_init(20,4,2);
lcd_chr_delay = 50;
lcd_clear();
lcd_cursor_off();
lcd_gotoxy(0,0);
lcd_write_text("prova di LCD per valutare il ritorno a capo automatico e scroll.");
lcd_write_text("DURANTE IL MAIUSCOLO DEVE EFFETTUARE LO SCROLLING");
lcd_clear();
lcd_gotoxy(0,3);
lcd_write_text("Ulteriore prova per verificare lo scrolling");
while(1)
{
}
return (0);
}

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)

