Bonjour,
Je dois réaliser un compte-tour pour moteur Brushless, pour cela je décide d'utiliser un PIC 18f1320 connecté à un afficheur LCD.
J'ai réalisé le cablage sur une plaquette Labdec, et je programme via MPLAB sur C18.
Le problème c'est que lorsque j'alimente la plaquette, le LCD affiche que des carrés noirs sur la première ligne.
Est-ce que cela viendrait de mon montage ou de mon programme?
Le principe de l'application reste simple, chaque fois que RB0 reçoit une impulsion le comptage est incrémenté.
Voilà mon programme:
Je vous remercie de vos réponses/****************************** ****************************** ****************************** ***************
* Tachymètre (compte-tour) numérique à base de capteur à effet Hall *
* Quartz 20Mhz PIC 18F1320 *
* *
* Formule de calcul du timer0 : *
* Temps=(256-valeur Décimale chargée TMR0) * 4 * (prescaler OPTION_REG) * 1/Oscillateur en Hz *
* Ce qui donne: *
* T=(256-0)*4*64*(1/20000000)= 0,0032768 >> pour avoir 0,999424 seconde à multiplier par cnt=305 *
* 0,999424 étant pour ce quartz la valeur la plus proche de 1 seconde avec le timer0 *
* *
* Le capteur Hall connecté sur RB0 déclenche une interruption à chaque passage de l'aimant *
****************************** ****************************** ****************************** ***************/
#include <p18f1320.h>
#include <delays.h> // déclaration prototype fonctions delay
#include <stdio.h> // pour avoir fonction sleep
// Configuration des ports sur le LCD
#define LCD_PORT PORTB // data afficheur ATTENTION Ports 4 bits faibles sur aff 4 bits forts
#define LCD_E PORTAbits.RA1 // cde afficheur E
#define LCD_RW PORTAbits.RA2 // cde afficheur RW
#define LCD_RS PORTAbits.RA3 // cde afficheur RS
#define LCD_D7 PORTBbits.RB7;
#define LCD_D6 PORTBbits.RB6;
#define LCD_D5 PORTBbits.RB5;
#define LCD_D4 PORTBbits.RB4;
// Orientation des ports
#define LCD_E_DIR TRISAbits.TRISA1 // cde direction afficheur E
#define LCD_RW_DIR TRISAbits.TRISA2 // cde direction afficheur RW
#define LCD_RS_DIR TRISAbits.TRISA3 // cde direction afficheur RS
#define LCD_D7_Direction TRISBbits.TRISB7;
#define LCD_D6_Direction TRISBbits.TRISB6;
#define LCD_D5_Direction TRISBbits.TRISB5;
#define LCD_D4_Direction TRISBbits.TRISB4;
//Déclaration des variables
unsigned int temp,compteur,cnt,tour,i;
unsigned char rotation_brute;
unsigned short int seconde,sequence;
void debordement (void);
void Affiche_Compteur (void);
void w_cde_nibble( unsigned char ); // ?crit le quartet fort du char x en mode cde
void w_cde_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode cde puis le quartet faible
void w_data_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode data puis le quartet faible
// Declenchement de l'interuption -> Appelle de la fonction debordement
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void vecteur (void)
{
debordement();
}
#pragma code
//****************************** ****************************** *****************
void main(){ // Début du programme principal
INTCON=0b10010000; // activer detection interruption front montant RB0 avec INTE et GIE
T0CON = 0b00000101; // Config T0CON pour avoir prescaler 64 et le timer sur 16bits.
INTCONbits.TMR0IE = 1; // Autorisation source d'interruption
INTCONbits.GIE = 1; // Autorisation globale des interruptions
TMR0L=0;
TMR0H=0;
T0CONbits.TMR0ON = 1; // Timer 0 marche (debut du comptage)
ADCON0=0; // ADC désactivé
TRISA=1; // PORTA configuré en entrée
TRISB=0b00000001; // PORTB configuré en sortie sauf port0
PORTA=0;
PORTB=0;
compteur=0;
temp=0;
seconde=0;
tour=0;
//****************************** ****************************** ******************
//***** init LCD ****************************
w_cde_nibble( 0x30 ); // 3 control
Delay1KTCYx(750); // delay = 15mS
w_cde_nibble( 0x30 ); // 3 control
Delay1KTCYx(250); // delay = 5mS
w_cde_nibble( 0x30 ); // 3 control
Delay10TCYx(50); // delay = 100?S
w_cde_nibble( 0x20 ); // 2 mode 4 bits
w_cde_octet( 0x28 ) ;// fonction set attention si 2F il ecrit en bas a droite ? l'envers avec 4 caracteres de masques (affiche a partir du 5eme car ecrit !)
w_cde_octet( 0x0F ) ;// display on
w_cde_octet( 0x06 ) ;// mode d'entree
w_cde_octet( 0x01 ) ;// clear display (facultatif)
w_cde_octet( 0x80 ) ;// DDRAM 0000 (facultatif)
w_cde_octet( 0x02 ) ;// home (facultatif)
Delay1KTCYx(250); // delay = 5mS INDISPENSABLE pour CDE HOME !
w_cde_octet( 0x01 ) ;// clear display (facultatif)
w_cde_octet( 0x83 ) ;// 4eme case de la 1ère ligne
w_data_octet( 0x54 ) ;// T
w_data_octet( 0x41 ) ;// A
w_data_octet( 0x43 ) ;// C
w_data_octet( 0x48 ) ;// H
w_data_octet( 0x59 ) ;// Y
w_data_octet( 0x4D ) ;// M
w_data_octet( 0x45 ) ;// E
w_data_octet( 0x54 ) ;// T
w_data_octet( 0x52 ) ;// R
w_data_octet( 0x45 ) ;// E
w_cde_octet( 0xC0 ) ;// passage seconde ligne
w_cde_octet( 0xC8 ) ;// passage milieu seconde ligne
w_data_octet( 0x54 ) ;// T
w_data_octet( 0x52 ) ;// R
w_data_octet( 0x2F ) ;// /
w_data_octet( 0x4D ) ;// M
w_data_octet( 0x4E ) ;// N
//boucle infinie
while(1)
{
Affiche_Compteur(); // Fonction d'affichage sur LCD
} //fin de while
} // fin de main
void Affiche_Compteur (void){ // fonction d'affichage de nombre sur plusieurs digits
unsigned int temp;
unsigned char rotation_brute;
rotation_brute = (compteur/1000)+48;
temp = compteur % 1000;
w_cde_octet( 0xC0 ) ; // passage seconde ligne
w_cde_octet( 0xC3 ) ; // passage à la 4eme case de la seconde ligne
w_data_octet( rotation_brute ) ; // Afficher les milliers
rotation_brute = (temp/100)+48;
temp = temp % 100;
w_data_octet( rotation_brute ) ;// // Afficher les centaines
rotation_brute = (temp/10)+48;
w_data_octet( rotation_brute ) ;// // Afficher les dizaines
rotation_brute = (temp % 10)+48;
w_data_octet( rotation_brute ) ;// // Afficher les unités
}
//***** ecriture des fonctions ****************************
void w_cde_nibble( unsigned char x) // ?crit le quartet fort du char x en mode cde
{
unsigned char a;
LCD_RS=0; // mode cde
LCD_E=1; // monte enable
a=x>>4; // l'afficheur est sur les pds faibles du port !
LCD_PORT=a; // ecriture sur le port
LCD_E=0; // descends enable
Delay10TCYx(50); // delay = 100?S
}
void w_cde_octet( unsigned char x) // ?crit le quartet fort du char x en mode cde puis le quartet faible
{
unsigned char a;
LCD_RS=0; // mode cde
LCD_E=1; // monte enable
a=x>>4; // l'afficheur est sur les pds faibles du port !
LCD_PORT=a; // ecriture sur le port
LCD_E=0; // descends enable
Delay10TCYx(5); // delay = 10?S
LCD_E=1; // monte enable
LCD_PORT=x; // ecriture sur le port
LCD_E=0; // descends enable
Delay10TCYx(50); // delay = 100?S
}
void w_data_octet( unsigned char x ) // ?crit le quartet fort du char x en mode data puis le quartet faible
{
unsigned char a;
LCD_RS=1; // mode data
LCD_E=1; // monte enable
a=x>>4; // l'afficheur est sur les pds faibles du port !
LCD_PORT=a; // ecriture sur le port
LCD_E=0; // descends enable
Delay10TCYx(5); // delay = 10?S
LCD_E=1; // monte enable
LCD_PORT=x; // ecriture sur le port
LCD_E=0; // descends enable
Delay10TCYx(50); // delay = 100?S
}
//****************************** ****************************** ******************
//Interruption
void debordement() {
cnt++;
TMR0L = 0; // Valeur décimale préchargée à soustraire à 256
TMR0H = 0;
INTCONbits.TMR0IF = 0; // On remet a 0 le flag pour pouvoir détecter un autre debordement
if(INTCONbits.INT0IF==1){ // Si une interruption du port B0 est détectée
tour++; // incrémenter la variable de détection d'aimant
} // fin if
INTCON = 0x20; // Initialisation du registre timer et interruption
if(cnt==305){ // lorsque l'on compte 1 seconde (voir commentaire entête)
compteur= (tour/8)*60; // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
i=tour;
cnt=0; // RAZ variable cnt
tour=0;
INTCONbits.INT0IE = 1; // Activer RB0/INT interruption
seconde++;
} // Fin if
} //fin interruption
![]()
-----