HD44780 =============== Display that is used is HD44780 with I2C IO-expander connected to it. This was an practical way to reduce used IO's since otherwise minimun of 7-IO's would be required by display(4-data,EN,RW,RS). Using expander, only two I2C-pins is used. Expander have been bought at ebay many years ago but aliexpress sells same thing still. I2C-expander chip is PCF8574. .. image:: i2c_expander.png :width: 400 :alt: expander memset function is used to init lcdbuf array to show clear on LCD. Otherwise first four init dataset is used for just in case, since some LCD-screen variations seems to require it. Rest of inits are done like HD44780 datasheet tells. Only reason why LCD is set to use 4-bit data is since this is ported to this platform from my old Atmel Atmega128 microcontroller code where 4-bit bus was used. .. code-block:: C void lcdinit(){ memset((void*)&lcdbuf, 20, sizeof(int)*32); //alustetaan lcdbufferi näyttämään tyhjää volatile unsigned char lcd_data; lcd_data=0b00110000; i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); nrf_delay_ms(6); lcd_data=0b00110000; i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); nrf_delay_ms(6); lcd_data=0b00110000; i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); nrf_delay_ms(6); lcd_data=0b00100000; i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); nrf_delay_ms(6); sendcmd(0x28); nrf_delay_ms(2); //Function set, 4bit, 2rivinen, 42 us :0b00101000 sendcmd(0x08); nrf_delay_ms(2); //display off,curs off, blink off, 42 us:0b00001000 sendcmd(0x01); nrf_delay_ms(2); //clear display, min 1.64 ms :0b00000001 sendcmd(0x06); nrf_delay_ms(2); //entry mode set :0b00000110 sendcmd(0x0C); nrf_delay_ms(2); //display on,curs off,blink off :0b00001011 sendcmd(0x80); nrf_delay_ms(2); //DD-address=0 :0b10000000 sendcmd(2); nrf_delay_ms(2); } Since data is 4-bit, data send operation is done two times where first four high bits are send first, then lower four. This version of fuction is used to send commands, so RS bit is set to 0. .. code-block:: C void sendcmd(volatile unsigned char a) { volatile unsigned char lcd_data=0; lcd_data = (0b11110000 & a); //get high 4 bits i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); //pulse to set D4-D7 bits lcd_data = a<<4; //get low 4 bits lcd_data =(lcd_data & 0b11110000); i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); } This is same as previous, but RS bit is set to 1, signaling to LCD that character is send. .. code-block:: C void sendchar(volatile unsigned char a) { volatile unsigned char lcd_data=0; lcd_data = (0b11110000 & a)+1; //get high 4 bits //RS 1-tilaan i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); //pulse to set D4-D7 bits lcd_data = a<<4; //get low 4 bits lcd_data=(0b11110000 & lcd_data)+1; i2c_write_byte_no_reg(DEV_ADDR,lcd_data); e_puls(lcd_data); } This function is called whenever character on LCD is changed. Basically every character from buffer is send always when this function is called. .. code-block:: C void lcdkirj() { int a; sendcmd(128); nrf_delay_ms(2); sendcmd(2); nrf_delay_ms(2); for(a=0;a<=31;a++) { sendchar(lcdbuf[a]); nrf_delay_us(40); if(a==15){ sendcmd(0b11000000); nrf_delay_us(40);} } }