// hd44780.h - HD44780 Instructions and Parameter definitions // // Copyright (C) 1997, Ian Harries & Imperial College, London, UK // /* $Id: hd44780.h,v 1.3 2006/05/20 15:54:04 nemo Exp $ antics@nervousbot.us ported for use with sdcc/gcc and various microcontrollers this header is intended mainly for use with AVR and PIC (ATmega32 and p16f628a used in development) micros but should be easy to port to any system in any configuration. note that init() and wait_for_lcd() need to be modified for your micro as well to set the data direction register Wiring Guide: A7 = R/W 0->Write, 1->Read A1 = E : 0->Not, 1->Enable A0 = RS: 0->instruction, 1->data B0-B7 = Data 20x4 Details: http://ouwehand.net/~peter/lcd/lcd0.shtml Changelog: + 18 May 2006 christopher pepe - initial updates for AVR use - retained PIC related code - added comments to show where to (un)comment for use with PIC/AVR */ //this block is specific to the micorcontroller setup //change the masks to match your pinout #define Data PORTB //8 bit data port #define Data_read PINB //AVR input port b #define Data_ddr DDRB //data direction register //#define Control PORTA // Control register #define Control PORTD // Control register for ATmega32 (porta is the ADC which is also used) #define Control_ddr DDRD //date direction register //Common Combos #define RS_E_Low 0xfc #define RW_RS_E_Low 0x7c // R/W 7 6 5 4 3 2 1 0 // =============== === === === === === === === === #define Read 0x80 // 1 . . . . . . . #define Write 0x00 // 0 . . . . . . . // RS 7 6 5 4 3 2 1 0 // =============== === === === === === === === === #define Data_Register 0x01 // . . . . . . . 1 #define Ins_Register 0x00 // . . . . . . . 0 // Enable 7 6 5 4 3 2 1 0 // ====== === === === === === === === === #define E_Low 0xfd // 1 1 1 1 1 1 0 1 #define E_High 0x02 // . . . . . . 1 . //this block is specific to the micorcontroller setup // HD44780 Instruction Set DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 // ======================= === === === === === === === === #define Clear_Display 0x01 // 0 0 0 0 0 0 0 1 #define Return_Home 0x02 // 0 0 0 0 0 0 1 * #define Set_Entry_Mode 0x04 // 0 0 0 0 0 1 I/D S #define Set_Display 0x08 // 0 0 0 0 1 D C B #define Set_Cursor_and_Display_Shift 0x10 // 0 0 0 1 S/C R/L * * #define Set_Function 0x20 // 0 0 1 DL N F * * #define Set_CGRAM_Address 0x40 // 0 1 A A A A A A #define Set_DDRAM_Address 0x80 // 1 A A A A A A A // HD44780 Parameters // ================== // N.B. explicit values for EVERY corresponding parameter // ==== MUST be passed each time any instruction is used // Set_Entry_Mode // ============== #define Decrement_Address 0x00 // . . . . . . 0 . #define Increment_Address 0x02 // . . . . . . 1 . #define Shift_Display_Off 0x00 // . . . . . . . 0 #define Shift_Display_On 0x01 // . . . . . . . 1 // Set_Display // =========== #define Display_Off 0x00 // . . . . . 0 . . #define Display_On 0x04 // . . . . . 1 . . #define Cursor_Off 0x00 // . . . . . . 0 . #define Cursor_On 0x02 // . . . . . . 1 . #define Blink_Off 0x00 // . . . . . . . 0 #define Blink_On 0x01 // . . . . . . . 1 // Set_Cursor_and_Display_Shift // ============================ #define Cursor 0x00 // . . . . 0 . . . #define Display_and_Cursor 0x08 // . . . . 1 . . . #define Left 0x00 // . . . . . 0 . . #define Right 0x04 // . . . . . 1 . . // Set_Function // ============ #define Data_Length_4 0x00 // . . . 0 . . . . #define Data_Length_8 0x10 // . . . 1 . . . . #define One_Display_Line 0x00 // . . . . 0 . . . #define Two_Display_Lines 0x08 // . . . . 1 . . . #define Font_5x7 0x00 // . . . . . 0 . . #define Font_5x10 0x04 // . . . . . 1 . . #define Line2_Offset 0x40 #define putc Put_Data // same thing #define lcd Put_Ins // same thing static void init(){ //CMCON=7; //PIC: turn comparators off // all are outputs to send commands to lcd //TRISB=0x00; //PIC Data_ddr=0xff; //AVR //PORTA is all outputs although only A0 and A1 are used //TRISA=0x00; //PIC Control_ddr=0xff; //AVR //clear ports Data=Control=0; } static void pause(void) { // dilute to taste int i,j; for (i=0; i<100;i++){ for(j=0;j<254;j++); } } static void wait_for_lcd(void){ unsigned char busy=0x80; unsigned char cnt=0; //portb = inputs //TRISB = 0xff; //PIC Data_ddr=0x00; //AVR Control &= RS_E_Low; Control |= Read; //read Data until busy flag goes low //or cnt overflows while((busy & 0x80) != 0){//is lcd busy? Control |= E_High; Control &= E_Low; /* PIC */ //busy = Data; //read Data for lcd status /* AVR */ busy = Data_read; //read Data for lcd status if(cnt++ > 254){busy = 0;} //or timeout } Control &= RW_RS_E_Low; //R/W, RS, E low //portb = outputs //TRISB = 0x00; //PIC Data_ddr = 0xff; //AVR } static void Put_Ins(int Ins) { Data = Ins; Control &= RS_E_Low; Control |= E_High; //RS=0, E=1 Control &= RS_E_Low; wait_for_lcd(); } static void Put_Data(unsigned char Ch) { Data = Ch; Control &= RS_E_Low; //RS=E=0 Control |= (Data_Register + E_High); //RS=E=1 Control &= E_Low; //Data_Register stays high wait_for_lcd(); } //doesn't seem to work with sdcc static void puts(unsigned char *Str, unsigned char len) { unsigned int i; for (i = 0; i < len; i++){ Put_Data(*Str++); //pause(); //optional pause } } static void initlcd(void) { Put_Ins(Set_Function | Data_Length_8); Put_Ins(Set_Function | Data_Length_8); Put_Ins(Set_Function | Data_Length_8); Put_Ins(Set_Function | Data_Length_8 | Font_5x7 | Two_Display_Lines); Put_Ins(Set_Entry_Mode | Increment_Address | Shift_Display_Off); Put_Ins(Set_Display | Display_On | Cursor_Off | Blink_On); Put_Ins(Set_Function | Data_Length_8 | Font_5x7 | Two_Display_Lines); Put_Ins(Clear_Display); }