JJReyes
Newbie
Hello everyone,
I have bought a LCD Sunfounder 1602 (LCD + PCF8574T to be exact). My goal is to display data from the PIC24FJ128GA110 to the LCD, I have written an I2C library that seems to work (tested it with an ADC and I got pretty much what I wanted). So I connect the LCD (4 pins : VDD, GND, SCL and SDA), and when I observe with my scope, I can indeed see the signals SCL and SDA on the pins of the LCD. But else, nothing is being displayed on the LCD and I don't really know why. I have done continuity testing, to check that the software driver matches the port assignments and it was fine. I suspect a problem in the code, (maybe the LCD initialization that is not correct ?), but as I am quite new with microcontrollers, I don't know what could be wrong to be honest. I am including the I2C and LCD libraries in case someone had already worked with one of those LCD.
LCD Lib :
I2C Lib :
Main :
I reckon I just don't really know what's wrong, because I thought the I2C was working, and because I can see the SCL and SDA signals on my scope. I work with the MPLABX IDE, so it's pretty hard to have a debug terminal, so usually try to debug with a LED (LED_IGN_LAT), and it seems that it never turns off as it's supposed to after I send the 'J' to the LCD, but it seems to be doing the initialization. As I said, my guess would be that something is wrong with the LCD library, but I don't quite know where to look... If anyone had an idea I'd gladly take it!
Thanks heaps !
I have bought a LCD Sunfounder 1602 (LCD + PCF8574T to be exact). My goal is to display data from the PIC24FJ128GA110 to the LCD, I have written an I2C library that seems to work (tested it with an ADC and I got pretty much what I wanted). So I connect the LCD (4 pins : VDD, GND, SCL and SDA), and when I observe with my scope, I can indeed see the signals SCL and SDA on the pins of the LCD. But else, nothing is being displayed on the LCD and I don't really know why. I have done continuity testing, to check that the software driver matches the port assignments and it was fine. I suspect a problem in the code, (maybe the LCD initialization that is not correct ?), but as I am quite new with microcontrollers, I don't know what could be wrong to be honest. I am including the I2C and LCD libraries in case someone had already worked with one of those LCD.
LCD Lib :
C:
#include <xc.h>
#include "lcd.h"
#include "i2c1.h"
#include <string.h>
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 8000000UL
#endif
#ifndef FCY
#define FCY _XTAL_FREQ/2
#endif
#include <libpic30.h>
void lcd_init() {
// Initialization sequence for 16x2 LCD
lcd_send_command(0x33); // Initialize the LCD in 8-bit mode
__delay_ms(5);
lcd_send_command(0x32); // Initialize the LCD in 4-bit mode then
__delay_ms(5);
lcd_send_command(0x28); // 2 lines, 5x7 matrix
__delay_ms(5);
lcd_send_command(0x0C); // Display ON, Cursor OFF, Blink OFF
__delay_ms(5);
lcd_clear(); // Clear the LCD
}
void lcd_clear() {
lcd_send_command(0x01); // Clear display command
__delay_ms(5); // Delay to allow the LCD to process the command
}
void write_word_lcd(int data){
int temp = data;
temp |= 0x08;
send_i2c1_byte(LCD_ADDRESS);
send_i2c1_byte(temp);
}
void lcd_send_command(unsigned int command) {
//send_i2c1_byte(LCD_ADDRESS << 1); //RW = 0
//send_i2c1_byte(command);
int buffer;
//Write bit 7 to 4
buffer = command & 0xF0;
buffer |= 0x04; // RS = 0, RW = 0, EN = 1
write_word_lcd(buffer);
__delay_ms(50);
buffer &= 0xFB;
write_word_lcd(buffer);
//Write bit 3 to 0
buffer = (command & 0x0F) << 4;
buffer |= 0x04; // RS = 0, RW = 0, EN = 1
write_word_lcd(buffer);
__delay_ms(50);
buffer &= 0xFB; // EN = 0
write_word_lcd(buffer);
}
void lcd_send_data(unsigned char data) {
// Set RS high (0x80) for data, and send data byte to LCD
//send_i2c1_byte((LCD_ADDRESS << 1) | 0x01); // Set R/W bit high for Write
//send_i2c1_byte(data);
int buffer;
//Write bit 7 to 4
buffer = data & 0xF0;
buffer |= 0x05; // RS = 1, RW = 0, EN = 1
write_word_lcd(buffer);
__delay_ms(50);
buffer &= 0xFB; // EN = 0
write_word_lcd(buffer);
//Write bit 3 to 0
buffer = (data & 0x0F) << 4;
buffer |= 0x05; // RS = 1, RW = 0, EN = 1
write_word_lcd(buffer);
__delay_ms(50);
buffer &= 0xFB; // EN = 0
write_word_lcd(buffer);
}
void write(int x, int y, char data[]){
int addr, i;
int temp;
if (x < 0) x = 0;
if (x > 15) x = 15;
if (y < 0) y = 0;
if (y > 1) y = 1;
// Move cursor
addr = 0x80 + 0x40 * y + x;
lcd_send_command(addr);
temp = strlen(data);
for (i = 0; i < temp; i++){
lcd_send_data(data[i]);
}
}
/*
void lcd_set_cursor(unsigned char row, unsigned char col) {
unsigned char address = (0x80 | (row << 6) | col); // Calculate the DDRAM address
lcd_send_command(address);
}
*/
/*
void lcd_display_string(const char *str) {
while (*str) {
lcd_send_data(*str);
str++;
}
}
*/
I2C Lib :
C:
#include <xc.h>
#include "i2c1.h"
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 8000000UL
#endif
#ifndef FCY
#define FCY _XTAL_FREQ/2
#endif
#include <libpic30.h>
void i2c1_init() {
I2C1BRG = 18; //8 7 4 = 300kH
//I2C1CONbits.I2CEN = 0; // Disable I2C Mode
// Clear Interrupt
IFS3bits.MI2C2IF = 0;
//Continue module operation in Idle mode
I2C1CONbits.I2CSIDL = 0;
//IPMIEN mode disabled
I2C1CONbits.IPMIEN = 0;
//Slew rate enabled
I2C1CONbits.DISSLW = 0;
//General call address disabled
I2C1CONbits.GCEN = 0;
//Disable SMBus input thresholds
I2C1CONbits.SMEN = 0;
//Software or receive call stretching disabled
I2C1CONbits.STREN = 0;
// Enable I2C Mode
I2C1CONbits.I2CEN = 1;
}
void i2c1_wait(void) {
//while(!IFS3bits.MI2C2IF);
__delay_ms(500);
IFS3bits.MI2C2IF = 0; // Reset flag
}
void i2c1_start(void) {
I2C1CONbits.SEN = 1; //Initiate Start condition
i2c1_wait();
}
void i2c1_restart(void) {
I2C1CONbits.RSEN = 1; //Initiate restart condition
i2c1_wait();
}
void i2c1_stop(void) {
I2C1CONbits.PEN = 1; //Initiate Start condition
i2c1_wait();
}
void reset_i2c1_bus(void) {
I2C1CONbits.PEN = 1; //initiate stop bit
while (I2C1CONbits.PEN);
I2C1CONbits.RCEN = 0;
IFS3bits.MI2C2IF = 0; // Clear Interrupt
I2C1STATbits.IWCOL = 0;
I2C1STATbits.BCL = 0;
}
char send_i2c1_byte(unsigned char data) {
I2C1TRN = data; // load the outgoing data byte
i2c1_wait();
return (I2C1STATbits.ACKSTAT == 0); // return 1 if ACK
}
unsigned char receive_i2c1_byte(char send_ack) {
unsigned char data;
if (send_ack)
I2C1CONbits.ACKDT = 0;
else
I2C1CONbits.ACKDT = 1;
I2C1CONbits.RCEN = 1; // Start reception
//i2c1_wait();
data = I2C1RCV; // Read data
I2C1CONbits.ACKEN = 1; // Send ACK/NAK
//i2c1_wait();
while (I2C1CONbits.ACKEN);
return data;
}
unsigned char I2C1write(unsigned char dev, unsigned char reg, unsigned char value) {
dev <<= 1; // RW=0
i2c1_start(); // Send start
if (!send_i2c1_byte(dev) || !send_i2c1_byte(reg)) { // Send device address and reg address
i2c1_stop(); // Cancel if NACK
return 0;
}
send_i2c1_byte(value); // Write data
i2c1_stop(); // Send stop
return 1;
}
char I2C1read(unsigned char dev, unsigned char reg) {
unsigned char data;
dev = (dev << 1); // RW=0
i2c1_start(); // Send start
if (!send_i2c1_byte(dev) || !send_i2c1_byte(reg)) { // Send device address and reg address
i2c1_stop(); // Cancel if NACK
return 0;
}
dev |= 1; // RW=1
i2c1_restart(); // Send restart
if (!send_i2c1_byte(dev)) { // Send device address
i2c1_stop(); // Cancel if NACK
return 0;
}
data = receive_i2c1_byte(0);
i2c1_stop(); // Send stop
return data; // Return read data
}
Main :
C:
LED_IGN_TRIS = LED_OUTPUT;
LED_IGN_LAT = LED_OFF;
i2c1_init();
//lcd_init();
__delay_ms(500);
i2c1_start();
LED_IGN_LAT = LED_ON;
while (1) {
//write(0, 0, 'J');
lcd_send_command(0x33);
__delay_ms(50);
lcd_send_command(0x32);
__delay_ms(50);
lcd_send_command(0x28); // 2 lines, 5x7 matrix
__delay_ms(50);
lcd_send_command(0x0C); // Display ON, Cursor OFF, Blink OFF
__delay_ms(50);
lcd_send_data('J');
LED_IGN_LAT = LED_OFF;
I reckon I just don't really know what's wrong, because I thought the I2C was working, and because I can see the SCL and SDA signals on my scope. I work with the MPLABX IDE, so it's pretty hard to have a debug terminal, so usually try to debug with a LED (LED_IGN_LAT), and it seems that it never turns off as it's supposed to after I send the 'J' to the LCD, but it seems to be doing the initialization. As I said, my guess would be that something is wrong with the LCD library, but I don't quite know where to look... If anyone had an idea I'd gladly take it!
Thanks heaps !
Last edited: