#include #include #include "lcd.h" #include "symtab.h" unsigned char lcd_x = 0, lcd_y = 0; #ifdef CONFIG_LCD_1602A // максимальное число пользовательских знаков в знакогенераторе #define LCD_MAX_CHAR_SYG 8 // список текущих символов в знакогенераторе unsigned char current_rus_syg[LCD_MAX_CHAR_SYG] = {0, 0, 0, 0, 0, 0, 0, 0}; unsigned char current_syg_index = 0; unsigned char lcd_lines[2][16]; void LCD_putcmd(unsigned char data,unsigned char cmdtype); #endif const unsigned char rus_sym_table[64]= { 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4, 0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8, 0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB, #ifdef CONFIG_LCD_1602A 0xAC,0xE2,0xAD,0xAE,'b',0xAF,0xB0,0xB1, #else 0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1, #endif 0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7, 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE, 0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0, 0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 }; void us_delay(unsigned long x) { while (x--) { for (int i=0; i<10; i++) __no_operation(); } } #ifdef CONFIG_LCD_1602A // void LCD_WriteCGRAM(unsigned char data) { // LCD Upper 4 bits data LCD_SET_RS_PIN(); // RS = 1, E = 1 LCD_SET_E_PIN(); LCD_CLR_RW_PIN(); us_delay(1); LCD_OUT_DATA(data >> 4); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(1); // LCD Lower 4 bits data LCD_SET_E_PIN(); // RS = 1, E = 1 us_delay(1); LCD_OUT_DATA(data); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(100); } unsigned char LCD_ConvertSymOrient(unsigned int sym_ofst, unsigned char byte) { unsigned char data = 0; unsigned char i; for (i = 0; i < 5; i++) { if (symtab[sym_ofst + i] & (1 << byte)) data |= (1 << (4 - i)); } return data; } // void LCD_CreateChar(unsigned char syg_index, unsigned char data) { unsigned int sym_ofst = (data - 0x20) * 5UL; LCD_putcmd(0x40 + syg_index * 8, LCD_2CYCLE); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 0)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 1)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 2)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 3)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 4)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 5)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 6)); LCD_WriteCGRAM(LCD_ConvertSymOrient(sym_ofst, 7)); } #endif void LCD_putch(unsigned char data) { unsigned char data_out; #ifndef CONFIG_LCD_1602A if (data >= 0xC0) data_out = rus_sym_table[data-0xC0]; else data_out = data; #else if (data >= 0xC0) { if (rus_sym_table[data-0xC0] < 0xA0) { data_out = rus_sym_table[data-0xC0]; } else { CPU_INT08U i; CPU_INT08U finded = 0; for (i = 0; i < LCD_MAX_CHAR_SYG; i++) { if (data == current_rus_syg[i]) { data_out = i; finded = 1; break; } } if (!finded) { CPU_INT08U n, j; CPU_INT08U *ptr; for (j = 0; j < LCD_MAX_CHAR_SYG; j++) { if (current_rus_syg[j] == 0) break; ptr = (CPU_INT08U *)lcd_lines; for (n = 0; n < 32; n++, ptr++) { if (current_rus_syg[j] == *ptr) { break; } } if (n == 32) { current_rus_syg[j] = 0; break; } } if (j < LCD_MAX_CHAR_SYG) current_syg_index = j; LCD_CreateChar(current_syg_index, data); current_rus_syg[current_syg_index] = data; data_out = current_syg_index; LCD_goto(lcd_x, lcd_y); } } } else { data_out = data; } lcd_lines[lcd_y][lcd_x] = data; #endif LCD_SET_DATA_OUT(); // LCD Upper 4 bits data LCD_SET_RS_PIN(); // RS = 1, E = 1 LCD_SET_E_PIN(); LCD_CLR_RW_PIN(); us_delay(1); LCD_OUT_DATA(data_out >> 4); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(1); // LCD Lower 4 bits data LCD_SET_E_PIN(); // RS = 1, E = 1 us_delay(1); LCD_OUT_DATA(data_out); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(100); // OSTimeDly(1); // Wait for busy flag (BF) lcd_x++; } void LCD_putch_table(unsigned char data) { LCD_SET_DATA_OUT(); // LCD Upper 4 bits data LCD_SET_RS_PIN(); // RS = 1, E = 1 LCD_SET_E_PIN(); LCD_CLR_RW_PIN(); us_delay(1); LCD_OUT_DATA(data >> 4); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(1); // LCD Lower 4 bits data LCD_SET_E_PIN(); // RS = 1, E = 1 us_delay(1); LCD_OUT_DATA(data); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(100); // OSTimeDly(1); // Wait for busy flag (BF) lcd_x++; } unsigned char LCD_getch() { unsigned char data_h, data_l; LCD_SET_DATA_IN(); // LCD Upper 4 bits data LCD_SET_RS_PIN(); // RS = 1, E = 1 LCD_SET_E_PIN(); LCD_SET_RW_PIN(); us_delay(1); data_h = LCD_IN_DATA(); LCD_CLR_E_PIN(); us_delay(1); // LCD Lower 4 bits data LCD_SET_E_PIN(); // RS = 1, E = 1 us_delay(1); data_l = LCD_IN_DATA(); LCD_CLR_E_PIN(); us_delay(100); return (data_h << 4) | data_l; } unsigned char LCD_get_status() { unsigned char data_h, data_l; LCD_SET_DATA_IN(); // LCD Upper 4 bits data LCD_CLR_RS_PIN(); // RS = 0, E = 1 LCD_SET_E_PIN(); LCD_SET_RW_PIN(); us_delay(1); data_h = LCD_IN_DATA(); LCD_CLR_E_PIN(); us_delay(1); // LCD Lower 4 bits data LCD_SET_E_PIN(); // RS = 0, E = 1 us_delay(1); data_l = LCD_IN_DATA(); LCD_CLR_E_PIN(); us_delay(100); return (data_h << 4) | data_l; } void LCD_putcmd(unsigned char data,unsigned char cmdtype) { LCD_SET_DATA_OUT(); // LCD Upper 4 bits data LCD_CLR_RS_PIN(); // RS = 0, E = 1 LCD_SET_E_PIN(); LCD_CLR_RW_PIN(); us_delay(1); LCD_OUT_DATA(data >> 4); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); // cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes if (cmdtype == LCD_2CYCLE) { // LCD Lower 4 bits data us_delay(1); LCD_SET_E_PIN(); // RS = 0, E = 1 us_delay(1); LCD_OUT_DATA(data); us_delay(1); // E=0; write data LCD_CLR_E_PIN(); us_delay(1); //while(LCD_get_status() & 0x80); OSTimeDly(3); // Wait for busy flag (BF) //LCD_get_status(); } else { OSTimeDly(3); } } void InitLcdPins() { /* P2.8 MK_P65 Сигнал A0 индикатора P2.7 MK_P66 Сигнал E индикатора P2.6 MK_P67 Сигнал R_W индикатора P0.19 MK_P59 DB4 P0.20 MK_P58 DB5 P0.21 MK_P57 DB6 P0.22 MK_P56 DB7 */ #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif OS_ENTER_CRITICAL(); PINSEL4_bit.P2_8 = 0x0; PINSEL4_bit.P2_7 = 0x0; PINSEL4_bit.P2_6 = 0x0; PINMODE4_bit.P2_8 = 0; PINMODE4_bit.P2_7 = 0; PINMODE4_bit.P2_6 = 0; FIO2DIR_bit.P2_8 = 1; FIO2DIR_bit.P2_7 = 1; FIO2DIR_bit.P2_6 = 1; FIO2MASK_bit.P2_8 = 0; FIO2MASK_bit.P2_7 = 0; FIO2MASK_bit.P2_6 = 0; PINSEL1_bit.P0_19 = 0x0; PINSEL1_bit.P0_20 = 0x0; PINSEL1_bit.P0_21 = 0x0; PINSEL1_bit.P0_22 = 0x0; PINMODE1_bit.P0_19 = 0; PINMODE1_bit.P0_20 = 0; PINMODE1_bit.P0_21 = 0; PINMODE1_bit.P0_22 = 0; FIO0DIR_bit.P0_19 = 1; FIO0DIR_bit.P0_20 = 1; FIO0DIR_bit.P0_21 = 1; FIO0DIR_bit.P0_22 = 1; FIO0MASK_bit.P0_19 = 0; FIO0MASK_bit.P0_20 = 0; FIO0MASK_bit.P0_21 = 0; FIO0MASK_bit.P0_22 = 0; LCD_CLR_E_PIN(); LCD_CLR_RW_PIN(); LCD_CLR_RS_PIN(); OS_EXIT_CRITICAL(); } unsigned char test = 0; void InitLcd() { InitLcdPins(); // Wait for more than 15 ms after VCC rises to 4.5 V OSTimeDly(100); // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Function set: Set interface to be 4 bits long (only 1 cycle write). LCD_putcmd(0x20,LCD_1CYCLE); // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font) LCD_putcmd(0x28,LCD_2CYCLE); // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off //LCD_putcmd(0x08,LCD_2CYCLE); // Display On, Cursor Off LCD_putcmd(0x0C,LCD_2CYCLE); // Display Clear LCD_putcmd(0x01,LCD_2CYCLE); // Entry Mode Set: I/D=1; Increment, S=0; No shift LCD_putcmd(0x06,LCD_2CYCLE); } void LCD_gotoline(unsigned char n) { switch (n){ case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break; case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break; #ifndef CONFIG_LCD_1602A case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break; case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); lcd_x = 0; lcd_y = n; break; #endif default: return; } } // запись строки с номером n void LCD_puts(unsigned char *s, unsigned char n) { unsigned char i; LCD_putcmd(0x28,LCD_2CYCLE); LCD_gotoline(n); i=0; #ifdef CONFIG_LCD_1602A while((*s != 0) && (*s != '\n') && (i<16)) #else while((*s != 0) && (*s != '\n') && (i<20)) #endif { LCD_putch(*s); s++; i++; } #ifdef CONFIG_LCD_1602A while(i<16) #else while(i<20) #endif { LCD_putch(' '); i++; } } void LCD_goto(unsigned char m, unsigned char n) { switch (n){ case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break; case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break; #ifndef CONFIG_LCD_1602A case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break; case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); lcd_x = m; lcd_y = n; break; #endif default: return; } } // запись символа в строку с номером n в позицию m void LCD_putc(unsigned char c, unsigned char m, unsigned char n) { LCD_goto(m, n); LCD_putch(c); } // запись символа в строку с номером n в позицию m void LCD_putc_embed(unsigned char c, unsigned char m, unsigned char n) { LCD_goto(m, n); LCD_putch_table(c); } void LCD_clear(void) { // Display Clear LCD_putcmd(0x01,LCD_2CYCLE); lcd_x = 0; lcd_y = 0; #ifdef CONFIG_LCD_1602A memset(lcd_lines, 0, sizeof(lcd_lines)); #endif } void LCD_cursor_on(void) { LCD_putcmd(0x0F,LCD_2CYCLE); } void LCD_cursor_off(void) { LCD_putcmd(0x0C,LCD_2CYCLE); }