Hey there,
Im using a KL25Z and having tons of trouble for the past 2 weeks getting a LCD screen to initialize using I2C. Ive asked about it on reddit and Ive just been told the reason people use arduino is because its open source and these things are so **bleep** finicky. I guess i was hoping the community here can help.
I have this screen
https://www.amazon.ca/gp/product/B019K5X53O/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
Default write address is 0x4E
This is board manual
https://spivey.oriel.ox.ac.uk/dswiki/images-digisys/5/56/KL25-refman.pdf
Im trying to use port E pins 1 and 0.
Ive tried using external 3.8k and 1k pull up resistors on sda and scl.
Any insight is of help, this is making me just want to use arduinos aha but i must prevail and learn.
Screen just stays light with top row as blocks.
My code as its called is as follows
int main (void) {
i2c_init(); // enable I2C
Delay(10);
init_I2C_LCD(); // enable screen
// Print_LCD("Hello, World!"); // print, commented out since doesn't seem to communicate properly.
}
where
void i2c_init(void)
{
//clock i2c peripheral and port E
SIM->SCGC4 |= SIM_SCGC4_I2C1_MASK;
SIM->SCGC5 |= (SIM_SCGC5_PORTE_MASK);
//set pins to I2C function
PORTE->PCR[0] |= PORT_PCR_MUX(6);
PORTE->PCR[1] |= PORT_PCR_MUX(6);
//set to 100k baud
//baud = bus freq/(scl_div*mul)
//100k = 24M/(1*240); icr=0x1F sets scl_div to 240
I2C1->F = (I2C_F_ICR(0x1F) | I2C_F_MULT(0));
//enable i2c and interrupts
I2C1->C1 = 0x00; // preemptive clearing for trouble shooting, didnt fix anything
I2C1->C1 |= (I2C_C1_IICEN_MASK | I2C_C1_IICIE_MASK); // enable
I2C1->S |= I2C_S_IICIF_MASK;
}
void init_I2C_LCD(void)
{
// Delay(100);
LCD_Write_4bit_CMD(0x3); // set 8 bit
Delay(100);
LCD_Write_4bit_CMD(0x3); // set 8 bit
Delay(10);
LCD_Write_4bit_CMD(0x3); // set 8 bit
LCD_Write_4bit_CMD(0x2); // set to 4 bit
LCD_Write_8bit_CMD(0x28); // set 2 lines
LCD_Write_8bit_CMD(0x0C); //
LCD_Write_8bit_CMD(0x06);
LCD_Write_8bit_CMD(0x80);
}
void LCD_Write_4bit_CMD(uint8_t c)
{
// input must be in form of 0x0c or 0xc
// For instructions RS & RW =0
uint8_t EHi = 0x04;
uint8_t ELo = 0x00;
I2C_TRAN;
I2C_M_START;
I2C1->S |= I2C_S_IICIF_MASK;
I2C1->D = LCD_ADDR_W;
I2C_WAIT;
I2C1->D = ((c<<4) | ELo);
I2C_WAIT;
I2C1->D = ((c<<4) | EHi);
I2C_WAIT;
I2C_M_STOP;
}
#define I2C_TRAN I2C1->C1 |= I2C_C1_TX_MASK
#define I2C_M_START I2C1->C1 |= I2C_C1_MST_MASK
#define I2C_M_STOP I2C1->C1 &= ~I2C_C1_MST_MASK
#define I2C_WAIT while((I2C1->S & I2C_S_IICIF_MASK)==0) {} \
I2C1->S |= I2C_S_IICIF_MASK;
#define LCD_ADDR_W 0x4E