Certain on pu me lire sur ce topic de pspic qui a réalisé une communication entre un pic et un lcd 16x2
via ce module :
Je souhaite donc en faire autant mais en C. Pour ce projet je souhaite juste afficher du texte sur l’écran. Pour ce qui et du matériel, voici ce que j'ai:
pic 16f887 Datasheet
le module pcf8574AT Datasheet
un lcd 16x2 (pas de datasheet)
et une breadbord
Voilà pour ce qui est du matériel. J'ai fait un petitschema sous proteus pour vous montrer le branchement que j'ai fait (car niveau photo je n'ai pas de quoi faire une belle qualité)
Voici donc le schéma :
J'ai quand même fait une simulation sous isis (même si a plusieurs reprises vous m'avez dit que la simu reste de la simu)
sa fonctionne. biensur sur la breadbord ça ne fonctionne pas, si non j'aurais ecrit en gros et gras "youhou !!!!!!!"
J'ai récuperer un code sur libstock que j'ai modifier pour un 16f887.
Le voici :
Code mise a jour et fonctionnelle le 21/05/2018
Merci a paulfjujo qui a fait tout le code
Code : Tout sélectionner
///////////////////////////////
// name : LCDI2C //
// create : venom //
// pic : 16f887 4MHz //
// Merci à Paulfjujo //
//Qui a corrigé tout le code //
///////////////////////////////
// config
//CONFIG1 : $2007 : 0x24F4
//CONFIG2 : $2008 : 0x0600
#define _LCD_FIRST_ROW 0x80 //Move cursor to the 1st row
#define _LCD_SECOND_ROW 0xC0 //Move cursor to the 2nd row
#define _LCD_THIRD_ROW 0x94 //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW 0xD4 //Move cursor to the 4th row
#define _LCD_CLEAR 0x01 //Clear display
#define _LCD_RETURN_HOME 0x02 //Return cursor to home position, returns a shifted display to
//its original position. Display data RAM is unaffected.
#define _LCD_CURSOR_OFF 0x0C //Turn off cursor
#define _LCD_UNDERLINE_ON 0x0E //Underline cursor on
#define _LCD_BLINK_CURSOR_ON 0x0F //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT 0x10 //Move cursor left without changing display data RAM
#define _LCD_MOVE_CURSOR_RIGHT 0x14 //Move cursor right without changing display data RAM
#define _LCD_TURN_ON 0x0C //Turn Lcd display on
#define _LCD_TURN_OFF 0x08 //Turn Lcd display off
#define _LCD_SHIFT_LEFT 0x18 //Shift display left without changing display data RAM
#define _LCD_SHIFT_RIGHT 0x1E //Shift display right without changing display data RAM
// Adresse I2C du LCD
#define LCD_ADDR 0x7E // venom adresse du PCF8574A = 0x7E.
//test led fosc
sbit LED at PORTC.B0;
sbit LED_Dir at TRISC.B0;
unsigned int i,j;
char rs;
// Lcd constants
char txt1[] = "FantasPic ! ";
char txt2[] = "LCD I2C ! ";
void CRLF1(void){
UART1_Write(13);
UART1_Write(10);
}
void I2C_LCD_Cmd(char out_char) {
char hi_n, lo_n;
rs = 0x00;
hi_n = out_char & 0xF0;
lo_n = (out_char << 4) & 0xF0;
I2C1_Start();
I2C1_Is_Idle();
I2C1_Wr(LCD_ADDR);
I2C1_Is_Idle();
I2C1_Wr(hi_n | rs | 0x04 | 0x08);
I2C1_Is_Idle();
Delay_us(50);
I2C1_Wr(hi_n | rs | 0x00 | 0x08);
I2C1_Is_Idle();
Delay_us(100);
I2C1_Wr(lo_n | rs | 0x04 | 0x08);
I2C1_Is_Idle();
Delay_us(50);
I2C1_Wr(lo_n | rs | 0x00 | 0x08);
I2C1_Is_Idle();
I2C1_Stop();
if(out_char == 0x01)Delay_ms(25);
}
void I2C_LCD_Chr(char row, char column, char out_char) {
char hi_n, lo_n;
rs = 0x00;
switch(row){
case 1:
I2C_LCD_Cmd(0x80 + (column - 1));
break;
case 2:
I2C_LCD_Cmd(0xC0 + (column - 1));
break;
};
hi_n = out_char & 0xF0;
lo_n = (out_char << 4) & 0xF0;
rs = 0x01;
I2C1_Start();
Delay_us(50);
I2C1_Wr(LCD_ADDR);
Delay_us(50);
I2C1_Wr(hi_n | rs | 0x04 | 0x08);
Delay_us(50);
Delay_us(50);
I2C1_Wr(hi_n | rs | 0x00 | 0x08);
Delay_us(100);
I2C1_Wr(lo_n | rs | 0x04 | 0x08);
Delay_us(50);
I2C1_Wr(lo_n | rs | 0x00 | 0x08);
I2C1_Stop();
}
void I2C_LCD_Init()
{
rs=1;
Delay_ms(500); //30 // laisser le temps au LCD de s'alimenter correctement
I2C_LCD_Cmd(0x30);
Delay_ms(10);
I2C_LCD_Cmd(0x30);
Delay_ms(10);
I2C_LCD_Cmd(0x30);
Delay_ms(10);
I2C_LCD_Cmd(0x20);
Delay_ms(10);
I2C_LCD_Cmd(0x28);
Delay_ms(10);
I2C_LCD_Cmd(0x06);
Delay_ms(10);
I2C_LCD_Cmd(0x01);
Delay_ms(50);
}
void I2C_LCD_Out(char row, char col, char *text) {
while(*text)
I2C_LCD_Chr(row, col++, *text++);
}
void main()
{
OSCCON = 0b01101000; // configuration OSCCON interne 4mhz
// 0b01110000 oscillateur 8 Mhz
// 0b01101000 oscillateur 4 Mhz
// 0b01011000 oscillateur 2 Mhz
// 0b01001000 oscillateur 1 Mhz
// 0b00111000 oscillateur 500 Khz
// 0b00101000 oscillateur 250 Khz
// 0b00011000 oscillateur 125 Khz
// 0b00001000 oscillateur 31 kHz
while(OSCCON.HTS==0); // boucle en attendant de voir le flag à 1
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
PORTA=0;
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
TRISA = 0b11101111;
PORTC=0;
TRISC = 0b10100110;
LED_Dir=0;
LED=0;
Delay_ms(100);
//test FOSC visuel avec une led
for (i=0;i<2;i++)
{
LED=1;
Delay_ms(1000);
LED=0;
Delay_ms(1000);
}
I2C1_Init(100000);
I2C_LCD_Init();
Delay_ms(500);
I2C_LCD_Cmd(_LCD_CLEAR); Delay_ms(50);
I2C_LCD_Cmd(_LCD_RETURN_HOME); Delay_ms(50);
I2C_LCD_Cmd(_LCD_CURSOR_OFF); Delay_ms(50);
I2C_LCD_Out(1,1,txt1);
I2C_LCD_Out(2,1,txt2);
while(1) {
}
} Voici pour ceux qui est des options du projet:
Mais je pense repartir de zero niveau code. Deja pour mieux apprendre le fonctionnement de l'i2c puis pour repérer les éventuelles erreurs car la sa ne fonctionne pas sur la breadbord
Voila les news de mon nouveau projet.
Ps: en general je met du temps a mes projet (manque de temps, trop de hobby) Mais la je viens d'etre papa donc les nuits sont courtes et le temps libre a encore reduit
@++

