problema oscillatore o pic rotto? Mancata inizializzazione LCD HD44780

12 Anni 5 Mesi fa #1 da Chuck_Norris
Ciao a tutti, come da titolo ho un problema abbastanza stupido ma che mi sta facendo perdere un sacco di tempo ed energie. E' la prima volta che cerco di "scrivere qualcosa" su un LCD con standard hitachi HD44780 e mi sono subito arenato.

Il programma è il semplice "hello world", quindi nulla di complicato però l'LCD non viene inizializzato (prima riga chiara seconda tutta nera) e non vedo un bel niente. Ho usato sia un PIC16F84A che un PIC16F876A che avevo in casa con un quarzo a 4MHz ma il risultato non cambia.
Così ho cominciato a smenttare un pò sul circuito e con l'oscilloscopio mi sono accorto che il quarzo non oscilla. Mi da un segnale di appena 100mV picco picco a 40-50Hz con condensatori da 12, 22 e 33pF.
A livello di programmazione uso l'HITech C presente in MPLAB con librerie per il delay e l'LCD presenti sul sito di settorezero che agli altri sembrano funzionare... :lol:

Che siano i pic rotti? Avendo montato tutto su breadboard non vorrei aver fatto toccare qualche filo inavvertitamente cortocircuitandoli...

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Chuck_Norris
  • Avatar di Chuck_Norris
  • Premium Member
  • Premium Member
Di più
12 Anni 5 Mesi fa #2 da Matteo Garia
l'oscilloscopio come lo usi?
devi mettere la sonda in X10 altrimenti l'impedenza troppo bassa impedisce al quarzo di oscillare

la breadboard non è il massimo per questo genere di cose ma non ho mai avuto problemi

la configuration word è settata correttamente?

prova a fare un semplice programma che faccia anche solo lampeggiare un led e vedi se va

Matteo

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Matteo Garia
  • Avatar di Matteo Garia
  • Moderator
  • Moderator
Di più
12 Anni 5 Mesi fa #3 da Chuck_Norris
fino ad ora la breadboard non ha dato problemi neanche a me. Dovrò costruirmi una devboard prima o poi :cheer:

tornando a noi, questa è la config word per l'876A:

__CONFIG (FOSC_XT & WDTE_OFF & PWRTE_ON & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & DEBUG_OFF);


e questa è per l'84A

__CONFIG (FOSC_XT & WDTE_OFF & PWRTE_ON & CP_OFF);


sembrano corrette: oscillatore al quarzo, power up timer attivato, protezioni varie disabilitate e low voltage programming disattivato. Anche i vari registri di configurazione sono settati bene, ho ricontrollato.

Il programma che accende un led l'ho provato 2 giorni fa perchè mi è arrivato il pickit3 e dovevo vedere se era tutto ok prima di dare il feed al venditore e ha funzionato. Ora ho appena provato a mettere una routine per il lampeggio del led tra le righe del codice per la scrittura sull'LCD e il led lampeggia ma l'LCD continua a non visualizzare nulla.

Per quanto riguarda il quarzo era un errore da niubbo, hai ragione te! Con la sonda a 10x leggo 4.008MHz 200mV picco picco (quindi 2Vpp). Cominciamo ad escludere il problerma sull'oscillazione

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Chuck_Norris
  • Avatar di Chuck_Norris
  • Premium Member
  • Premium Member
Di più
12 Anni 5 Mesi fa - 12 Anni 5 Mesi fa #4 da Matteo Garia
okay, è già un passo avanti :)
la configurazione va bene

non ho presente la libreria che stai utilizzando, ma ti pongo una domanda: il pin R/W è gestito dalla libreria? se non lo è va posto a massa
do per scontato che gli altri cablaggi sono corretti

ps. dimenticavo... fa vedere il codice ;)
Ultima Modifica 12 Anni 5 Mesi fa da Matteo Garia.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Matteo Garia
  • Avatar di Matteo Garia
  • Moderator
  • Moderator
Di più
12 Anni 5 Mesi fa - 12 Anni 5 Mesi fa #5 da Chuck_Norris
questo è il programmino di test che ho scritto

#include <htc.h>
#include <pic.h>
#include <delay_settorezero.c
#include <lcd_modificato.c>

__CONFIG (FOSC_XT & WDTE_OFF & PWRTE_ON & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & DEBUG_OFF);



void main(void)
{
TRISA = 0b00000000 ;
TRISB = 0b00000000 ;
TRISC = 0b00000000 ;
PORTA = 0;
PORTB = 0;
PORTC = 0;
nRBPU = 0; // pull-up sulla PORT B attivati

RB0 = 1; // accendo il led
DelayMs(250);
LCD_INIT() ; // inizializzo il display
DelayMs(100);
LCD_CMD(LCD_CONTROL); // linea inserita per far funzionare il display
LCD_CLEAR(); // "pulisco" il display
DelayMs(100);
LCD_GOTO(1,1);
LCD_PUTS("- - - - - - - - "); // Scrivo sul display dei trattini
LCD_GOTO(2,1);
LCD_PUTS(" - - - - - - - -");
while(1)
{
LCD_GOTO(1,1);
LCD_PUTS("PRIMA RIGA");
LCD_GOTO(2,1);
LCD_PUTS("SECONDA RIGA");
RB1=RB1^1; // lampeggio led
DelayMs(150);
}
return;
}


LCD_CMD(LCD_CONTROL); è un istruzione che mi è stata suggerita da un amico. Mi ha detto che dopo averla messa ha risolto perchè ha "sistemato" le temporizzazioni, a me invece non cambia nulla...

Per quanto riguarda le librerie:

Questa è quella che uso per l'LCD che sembrerebbe funzionare (agli altri....)

/************************************************************************/
/* POOR's (universal) LCD interface V1.4b */
/* simple and complete LCD routines by Andrea Bonzini */
/************************************************************************/
/* */
/* Please report any bug or suggestion at Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo. */
/* */
/************************************************************************/
/* */
/* This code will interface to a standard LCD controller */
/* like the Hitachi HD44780. */
/* It has been tested and works correctly with the followings */
/* LCD types: */
/* 1x8, 2x8, 1x16, 2x16, 2x20, 4x16, 4x20 */
/* */
/* */
/* !!! WARNINGS !!! */
/* */
/* This routines had been written to meet minimum hardware */
/* requirements...so you can use it even when your main */
/* application has left a few I/O lines not on the same port :) */
/* To let this you have the following restriction and benefits: */
/* */
/* 1) LCD works only in 4 bit mode. */
/* 2) You can use any Output pin of your MCU, you have only */
/* to change pin assignments in the define section. */
/* 3) R/W select is not available so you must ground LCD's R/W pin */
/* */
/* */
/* !!! NOTE !!! */
/* */
/* These routines use delay.c */
/* */
/************************************************************************

USER'S ROUTINES DESCRIPTION:

LCD_INIT()


> initilalize the LCD.
You must call it the first time you use the LCD
and before any other LCD routines.

LCD_CLEAR()
> Clears and Home LCD.

LCD_CMD('char')
> Send a command to the LCD.
See LCD datasheet for the complete
list of commands.

LCD_GOTO(line,pos) ---> Set the Cursor to a specified Line and position.
Lines available are from 1 to 4. Pos available
starts from 1 to max available on your LCD.

LCD_PUTCH('char') ----> Write a character on LCD (ASCII representation).

LCD_PUTS("string") ---> Write a string on LCD.

LCD_PUTUN(number) ---> Write an Unsigned Number on LCD.
It works both with INT (16bit) and CHAR (8bit).

LCD_PUTSN(number) ---> Write a Signed Number on LCD (with Sign if <0).
It works both with INT (16bit) and CHAR (8bit).


/************************************************************************/
/* */
/* !!! ATTENTION !!! */
/* Follow these simple instructions to configure your LCD module */
/* */
/* 1) check your hardware to determine which lines to use */
/* (you need 6 output lines). */
/* 2) set properly TRIS registers in your main code to configure */
/* the 6 lines as outputs. */
/* 3) In the next step use the defines to set the 6 lines as your */
/* hardware requires. */
/* 4) Set LCD Rows and Columns number using the define as shown */
/* 5) You are ready...your LCD will work!!! :) */
/* */
/************************************************************************/


/************************************************************************/
/* Use this includes if these files are not included in your main code */
/************************************************************************/
//#include "pic.h"
//#include "delay.c"


/************************************************************************/
/* Use the following defines to set the lines as your hardware requires */
/* ...you can use ANY output line of the MCU, even on several ports :) */
/************************************************************************/

#define LCD_RS RB4 // Register select
#define LCD_EN RB5 // Enable
#define LCD_D4 RB0 // LCD data 4
#define LCD_D5 RB1 // LCD data 5
#define LCD_D6 RB2 // LCD data 6
#define LCD_D7 RB3 // LCD data 7



/************************************************************************/
/* Now you have only to write LCD Rows and Columns number */
/************************************************************************/
/* !!! NOTE !!! */
/* Some 1x16 LCD works as 2x8!!! ...be sure how to configure */
/* yours, see its datasheet!!! */
/************************************************************************/

#define LCD_ROWS 2 // valid numbers are: 1,2
// (set to 2 for 2 or more rows)
#define LCD_COLS 20 // valid numbers are: 8,16,20





/************************************************************************/
/* */
/* YOUR LCD IS NOW READY TO WORK!!! :) */
/* YOU CAN IGNORE THE FOLLOWING CODE */
/* ENJOY !!! */
/* */
/************************************************************************/





/************************************************************************/
/* Use the following defines to send fast command */
/* to the LCD */
/* EX: LCD_CMD(LCD_line2); will set the cursor on line 2 */
/* You can add fast command of your own!!! */
/************************************************************************/
/* */
/* !!! NOTE !!! */
/* DON'T CHANGE THE DEFINES WITHIN #if-#endif */
/* */
/************************************************************************/

#define LCD_CLR 0x01 // Clear Display
#define LCD_HOME 0x02 // Cursor to Home position

/************************************************************************/
#if (LCD_COLS==20)
#define LCD_line1 0x80 // Line 1 position 1
#define LCD_line2 0xC0 // Line 2 position 1
#define LCD_line3 0x94 // Line 3 position 1 (20 char LCD)
#define LCD_line4 0xD4 // Line 4 position 1 (20 char LCD)
#else
#define LCD_line1 0x80 // Line 1 position 1
#define LCD_line2 0xC0 // Line 2 position 1
#define LCD_line3 0x90 // Line 3 position 1 (16 char LCD)
#define LCD_line4 0xD0 // Line 4 position 1 (16 char LCD)
#endif
/************************************************************************/


/****************************************/
/* Enable LCD to read data */
/****************************************/
void LCD_STROBE (void)
{
LCD_EN = 1;
DelayUs(1);
LCD_EN=0;
}


/****************************************/
/* Write a nibble to the LCD */
/****************************************/
void LCD_NIBBLE_OUT (unsigned char c )
{
if ( c & 0b10000000 )
LCD_D7=1;
else LCD_D7=0;
if ( c & 0b01000000 )
LCD_D6=1;
else LCD_D6=0;
if ( c & 0b00100000 )
LCD_D5=1;
else LCD_D5=0;
if ( c & 0b00010000 )
LCD_D4=1;
else LCD_D4=0;
LCD_STROBE();
}


/****************************************/
/* Write a byte to the LCD (4 bit mode) */
/****************************************/
void LCD_WRITE (unsigned char c)
{
LCD_NIBBLE_OUT(c);
c <<= 4;
LCD_NIBBLE_OUT(c);
DelayUs(50);
}


/****************************************/
/* send a command to the LCD */
/****************************************/
void LCD_CMD (char c)
{
LCD_RS = 0; // write command
LCD_WRITE(c);
}


/****************************************/
/* GoTO specified line and position */
/****************************************/
void LCD_GOTO (char line,char pos)
{
switch(line)
{
case 1: LCD_CMD((LCD_line1-1)+pos);
break;
case 2: LCD_CMD((LCD_line2-1)+pos);
break;
case 3: LCD_CMD((LCD_line3-1)+pos);
break;
case 4: LCD_CMD((LCD_line4-1)+pos);
}
}


/****************************************/
/* Clear and Home LCD */
/****************************************/
void LCD_CLEAR (void)
{
LCD_CMD(LCD_CLR);
DelayMs(3);
}


/****************************************/
/* Write one character to the LCD */
/****************************************/
void LCD_PUTCH (char c)
{
LCD_RS = 1; // write characters
LCD_WRITE(c);
}


/****************************************/
/* Write numbers to the LCD */
/****************************************/
void LCD_PUTUN (unsigned int c)
{
unsigned char t1,i,wrote;
unsigned int k;

wrote=0;
for (i=4;i>=1;i--)
{
switch(i){
case 4: k=10000;
break;
case 3: k=1000;
break;
case 2: k=100;
break;
case 1: k=10;
}
t1=c/k;
if((wrote)||(t1!=0))
{
LCD_PUTCH(t1+'0');
wrote=1;
}
c-=(t1*k);
}
LCD_PUTCH(c+'0');
}
/****************************************/
void LCD_PUTSN (signed int c)
{
if(c<0)
{
LCD_PUTCH('-');
c*=(-1);
}
LCD_PUTUN(c);
}


/****************************************/
/* Write a string to the LCD */
/****************************************/
void LCD_PUTS (const char * s)
{
LCD_RS = 1; // write characters
while(*s)
LCD_WRITE(*s++);
}


/****************************************/
/* Initialize LCD */
/****************************************/
void LCD_INIT (void)
{
LCD_RS = 0; // write control bytes
DelayMs(15); // power on delay
LCD_D4=1;
LCD_D5=1;
LCD_D6=0;
LCD_D7=0;
LCD_STROBE();
DelayMs(5);
LCD_STROBE();
DelayUs(100);
LCD_STROBE();
DelayMs(5);
LCD_D4=0; // set 4 bit mode
LCD_STROBE();
DelayUs(40);

#if (LCD_ROWS==1)
LCD_WRITE(0b00100000); // 4 bit mode, 1 line, 5x8 font
#else
LCD_WRITE(0b00101000); // 4 bit mode, 2 or more lines, 5x8 font
#endif

LCD_WRITE(0b00001000); // display off
LCD_WRITE(0b00001100); // display on, curson off, blink off
LCD_WRITE(0b00000110); // shift entry mode, display not shifted
}

/************************************************************************/
#undef LCD_ROWS
#undef LCD_COLS
/************************************************************************/
/* !!! END !!! */
/* THANKS FOR EXAMINING MY CODE ;) */
/************************************************************************/
/* */
/* Please report any bug or suggestion at Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo. */
/* */
/************************************************************************/


ovviamente va modificata ogni volta a seconda dei colegamenti e del display (e io l'ho fatto).


Per quanto riguarda i collegamenti, i piedini DB0-DB3 sono collegati insieme e messi a massa e R/W è a massa fisso.


PS: mi sono appena accorto di una cosa davvero stranissima!

Se tengo collegato l'oscilloscopio con la sonda a 10x, il led lampeggia quindi il pic sembra funzionare. Come stacco la sonda non lampeggia più! Inoltre il led su RB0 non si accende anche se l'altro lampeggia correttamente.
Ultima Modifica 12 Anni 5 Mesi fa da Chuck_Norris.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Chuck_Norris
  • Avatar di Chuck_Norris
  • Premium Member
  • Premium Member
Di più
Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login