📄 hd44780.c
字号:
}static void HD_write (unsigned char controller, char *string, int len, int delay){ unsigned char enable; if (Bits==8) { // enable signal: 'controller' is a bitmask // bit 0 .. send to controller #0 // bit 1 .. send to controller #1 // so we can send a byte to both controllers at the same time! enable=0; if (controller&0x01) enable|=SIGNAL_ENABLE; if (controller&0x02) enable|=SIGNAL_ENABLE2; // clear RW, set RS parport_control (SIGNAL_RW | SIGNAL_RS, SIGNAL_RS); // Address set-up time ndelay(T_AS); while (len--) { // put data on DB1..DB8 parport_data (*(string++)); // send command parport_toggle (enable, 1, T_PW); // wait for command completion udelay(delay); } } else { // 4 bit mode while (len--) { // send data with RS enabled HD_byte (controller, *(string++), SIGNAL_RS); // wait for command completion udelay(delay); } }}static void HD_setGPO (int bits){ if (Lcd.gpos>0) { // put data on DB1..DB8 parport_data (bits); // 74HCT573 set-up time ndelay(20); // send data // 74HCT573 enable pulse width = 24ns parport_toggle (SIGNAL_GPO, 1, 230); }}static void HD_define_char (int ascii, char *buffer){ // define chars on *both* controllers! HD_command (0x03, 0x40|8*ascii, T_EXEC); HD_write (0x03, buffer, 8, T_WRCG);}int HD_clear (int full){ memset (FrameBuffer1, ' ', Lcd.rows*Lcd.cols*sizeof(char)); icon_clear(); bar_clear(); GPO=0; if (full) { memset (FrameBuffer2, ' ', Lcd.rows*Lcd.cols*sizeof(char)); HD_command (0x03, 0x01, T_CLEAR); // clear *both* displays HD_command (0x03, 0x03, T_CLEAR); // return home HD_setGPO (GPO); // all GPO's off } return 0;}int HD_init (LCD *Self){ int rows=-1, cols=-1, gpos=-1; char *s; s=cfg_get("Size",NULL); if (s==NULL || *s=='\0') { error ("HD44780: no 'Size' entry in %s", cfg_source()); return -1; } if (sscanf(s,"%dx%d",&cols,&rows)!=2 || rows<1 || cols<1) { error ("HD44780: bad size '%s'",s); return -1; } if (cfg_number("GPOs", 0, 0, 8, &gpos)<0) return -1; info ("HD44780: controlling %d GPO's", gpos); if (cfg_number("Controllers", 1, 1, 2, &Controllers)<0) return -1; info ("wiring: using display with %d controllers", Controllers); // current controller Controller=1; Self->rows=rows; Self->cols=cols; Self->gpos=gpos; Lcd=*Self; // Init the framebuffers FrameBuffer1 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char)); FrameBuffer2 = (char*)malloc(Lcd.cols*Lcd.rows*sizeof(char)); if (FrameBuffer1==NULL || FrameBuffer2==NULL) { error ("HD44780: framebuffer could not be allocated: malloc() failed"); return -1; } if (cfg_number("Bits", 8, 4, 8, &Bits)<0) return -1; if (Bits!=4 && Bits!=8) { error ("HD44780: bad Bits '%s' in %s, should be '4' or '8'", s, cfg_source()); return -1; } info ("wiring: using %d bit mode", Bits); if (Bits==8) { if ((SIGNAL_RS = parport_wire_ctrl ("RS", "AUTOFD"))==0xff) return -1; if ((SIGNAL_RW = parport_wire_ctrl ("RW", "GND") )==0xff) return -1; if ((SIGNAL_ENABLE = parport_wire_ctrl ("ENABLE", "STROBE"))==0xff) return -1; if ((SIGNAL_ENABLE2 = parport_wire_ctrl ("ENABLE2", "SELECT"))==0xff) return -1; if ((SIGNAL_GPO = parport_wire_ctrl ("GPO", "INIT") )==0xff) return -1; } else { if ((SIGNAL_RS = parport_wire_data ("RS", "DB4"))==0xff) return -1; if ((SIGNAL_RW = parport_wire_data ("RW", "DB5"))==0xff) return -1; if ((SIGNAL_ENABLE = parport_wire_data ("ENABLE", "DB6"))==0xff) return -1; if ((SIGNAL_ENABLE2 = parport_wire_data ("ENABLE2", "DB7"))==0xff) return -1; if ((SIGNAL_GPO = parport_wire_data ("GPO", "GND"))==0xff) return -1; } if (parport_open() != 0) { error ("HD44780: could not initialize parallel port!"); return -1; } // clear all signals if (Bits==8) { parport_control (SIGNAL_RS|SIGNAL_RW|SIGNAL_ENABLE|SIGNAL_ENABLE2|SIGNAL_GPO, 0); } else { parport_data (0); } // set direction: write parport_direction (0); // initialize *both* displays if (Bits==8) { HD_command (0x03, 0x30, T_INIT1); // 8 Bit mode, wait 4.1 ms HD_command (0x03, 0x30, T_INIT2); // 8 Bit mode, wait 100 us HD_command (0x03, 0x38, T_EXEC); // 8 Bit mode, 1/16 duty cycle, 5x8 font } else { HD_nibble(0x03, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms HD_nibble(0x03, 0x03); udelay(T_INIT2); // 4 Bit mode, wait 100 us HD_nibble(0x03, 0x03); udelay(T_INIT1); // 4 Bit mode, wait 4.1 ms HD_nibble(0x03, 0x02); udelay(T_INIT2); // 4 Bit mode, wait 100 us HD_command (0x03, 0x28, T_EXEC); // 4 Bit mode, 1/16 duty cycle, 5x8 font } HD_command (0x03, 0x08, T_EXEC); // Display off, cursor off, blink off HD_command (0x03, 0x0c, T_CLEAR); // Display on, cursor off, blink off, wait 1.64 ms HD_command (0x03, 0x06, T_EXEC); // curser moves to right, no shift if (cfg_number("Icons", 0, 0, CHARS, &Icons)<0) return -1; if (Icons>0) { debug ("reserving %d of %d user-defined characters for icons", Icons, CHARS); icon_init(Lcd.rows, Lcd.cols, XRES, YRES, CHARS, Icons, HD_define_char); Self->icons=Icons; Lcd.icons=Icons; } bar_init(rows, cols, XRES, YRES, CHARS-Icons); bar_add_segment( 0, 0,255, 32); // ASCII 32 = blank bar_add_segment(255,255,255,255); // ASCII 255 = block HD_clear(1); return 0;}void HD_goto (int row, int col){ int pos; if (Controllers>1 && row>=2) { row -= 2; Controller = 2; } else { Controller = 1; } pos=(row%2)*64+(row/2)*20+col; HD_command (Controller, (0x80|pos), T_EXEC);}int HD_put (int row, int col, char *text){ char *p=FrameBuffer1+row*Lcd.cols+col; char *t=text; while (*t && col++<=Lcd.cols) { *p++=*t++; } return 0;}int HD_bar (int type, int row, int col, int max, int len1, int len2){ return bar_draw (type, row, col, max, len1, len2);}int HD_icon (int num, int seq, int row, int col){ return icon_draw (num, seq, row, col);}int HD_gpo (int num, int val){ if (num>=Lcd.gpos) return -1; if (val) { GPO |= 1<<num; // set bit } else { GPO &= ~(1<<num); // clear bit } return 0;}int HD_flush (void){ int row, col, pos1, pos2; int c, equal; bar_process(HD_define_char); for (row=0; row<Lcd.rows; row++) { for (col=0; col<Lcd.cols; col++) { c=bar_peek(row, col); if (c==-1) c=icon_peek(row, col); if (c!=-1) { FrameBuffer1[row*Lcd.cols+col]=(char)c; } } for (col=0; col<Lcd.cols; col++) { if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) continue; HD_goto (row, col); for (pos1=col++, pos2=pos1, equal=0; col<Lcd.cols; col++) { if (FrameBuffer1[row*Lcd.cols+col]==FrameBuffer2[row*Lcd.cols+col]) { // If we find just one equal byte, we don't break, because this // would require a goto, which takes one byte, too. if (++equal>2) break; } else { pos2=col; equal=0; } } HD_write (Controller, FrameBuffer1+row*Lcd.cols+pos1, pos2-pos1+1, T_EXEC); } } memcpy (FrameBuffer2, FrameBuffer1, Lcd.rows*Lcd.cols*sizeof(char)); HD_setGPO(GPO); return 0;}int HD_quit (void){ info("HD44780: shutting down."); if (FrameBuffer1) { free(FrameBuffer1); FrameBuffer1=NULL; } if (FrameBuffer2) { free(FrameBuffer2); FrameBuffer2=NULL; } return parport_close();}LCD HD44780[] = { { name: "HD44780", rows: 0, cols: 0, xres: XRES, yres: YRES, bars: BAR_L | BAR_R | BAR_U | BAR_D | BAR_H2, icons: 0, gpos: 0, init: HD_init, clear: HD_clear, put: HD_put, bar: HD_bar, icon: HD_icon, gpo: HD_gpo, flush: HD_flush, quit: HD_quit }, { NULL }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -