/*********************************************** * I2C_LCD Libraly * I2C Interface * lcd_init() ----- Initialize LCD * lcd_cmd(cmd) ----- Command Output * lcd_data(data) ----- One Char Output * lcd_str(ptr) ----- String Data Output * lcd_clear() ----- All Delete * * Used PIC24FJ64GA002 I2C2 Module * Condition: * 8MHz Internal RC oscillator, 4x PLL (8MHzx4= 32MHz) * Fcy=32MHz/2=16MHz, Tcy=62.5ns * * 2012/10/15: N.Ishii **********************************************/ #include #include "lcd_i2c_lib.h" /// I2C Sub Loutine void IdleI2C(void) { // Wait until I2C Bus is Inactive while(I2C2CONbits.SEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT); } void i2c_write(unsigned char data) { I2C2TRN = data; } void receive_ack(void) { while(I2C2STATbits.TBF) {;} // Wait TBF'0':TxBuffer Enpty while(I2C2STATbits.ACKSTAT) {;} // Wait ACKSTAT'0':A Response ACK } //------------------------------------------------------------------------------------ /********************************* * One Char Output to LCD *********************************/ void lcd_data(unsigned char data) { // START Bus Event IdleI2C(); I2C2CONbits.SEN = 1; // Set SENbit START Bus Event // Send Slave Address + Writebit while(I2C2CONbits.SEN); // Wait SENbit Clear i2c_write(LCD_SLVADRS_WR); // Receive ACK From LCD receive_ack(); // Send Data mode IdleI2C(); i2c_write(0x40); // Receive ACK From LCD receive_ack(); // Send Disp.Data IdleI2C(); i2c_write(data); // Receive ACK From LCD receive_ack(); // Stop Bus Event IdleI2C(); I2C2CONbits.PEN = 1; delay_us(30); } /******************************* * Command Output to LCD *******************************/ void lcd_cmd(unsigned char cmd) { // START Bus Event IdleI2C(); I2C2CONbits.SEN = 1; // Set SENbit START Bus Event // Send Slave Address + Writebit while(I2C2CONbits.SEN); // Wait SENbit Clear i2c_write(LCD_SLVADRS_WR); // Receive ACK From LCD receive_ack(); // Send Command mode IdleI2C(); i2c_write(0x00); // Receive ACK From LCD receive_ack(); // Send Command IdleI2C(); i2c_write(cmd); // Receive ACK From LCD receive_ack(); // Stop Bus Event IdleI2C(); I2C2CONbits.PEN = 1; // Clear or Home Command -> Switch wait */ if((cmd == 0x01)||(cmd == 0x02)) delay_ms(2); else delay_ms(30); } /******************************* * Initialize LCD *******************************/ void lcd_init(void) { delay_ms(100); lcd_cmd(0x38); // 8bit 2line Normal mode lcd_cmd(0x39); // 8bit 2line Extend mode lcd_cmd(0x14); // SET Internal OSC 183Hz BIAS 1/5 // Set Contorast lcd_cmd(0x70 + (CONTRAST & 0x0F)); lcd_cmd(0x5C + (CONTRAST >> 4)); // lcd_cmd(0x6A); // Follower for 5.0V lcd_cmd(0x6B); // Ffollwer for 3.3V delay_ms(300); lcd_cmd(0x38); // Set Normal mode lcd_cmd(0x0C); // Display On lcd_cmd(0x01); // Clear Display } /****************************** * All Delete ******************************/ void lcd_clear(void) { lcd_cmd(0x01); //Output Initialize Command } /***************************** * String Data Output *****************************/ void lcd_str(char* ptr) { while(*ptr != 0) // Get Char lcd_data(*ptr++); // Disp. Char } /***************************** * Disp. ICON *****************************/ void lcd_icon(unsigned char num, unsigned char onoff) { lcd_cmd(0x39); // Extend mode lcd_cmd(0x40 | ICON[num][0]); // Set ICON Address if(onoff) lcd_data(ICON[num][1]); // ICON ON Data else lcd_data(0x00); // ICON OFF Data lcd_cmd(0x38); // Normal Mode }