/********************************************** ****************PCD8544 Driver***************** *********************************************** for original NOKIA 3310 & alternative "chinese" version of display 48x84 dots, 6x14 symbols **********************************************/ //#define china 1 // если определено - работаем по алгоритмам "китайского" дисплея, иначе - оригинального #define SOFT_SPI 1 // если определено - используем программный SPI, иначе - аппаратный #ifndef SOFT_SPI unsigned char SPCR_val = 0x50; // режим unsigned char SPSR_val = 0x01; // удвоение частоты #endif #define power_of_display PORTC.0 #define power_of_display_ddr DDRC.0 //LCD Port & pinout setup. Примечание: порты с "кривой" адресацией (типа порт G и т.п.) не поддерживаются #define LCD_DC_PORT PORTB // выбор команда-данные; любой пин любого порта #define LCD_DC_DDR DDRB #define LCD_DC_PIN 4 #define LCD_CPORT PORTB // Chip-Select; любой пин любого порта #define LCD_CDDR DDRB #define LCD_CPIN 2 #define LCD_RST_PORT PORTC // сброс экрана; любой пин любого порта #define LCD_RST_DDR DDRC #define LCD_RST_PIN 3 #define LCD_MOSI_PORT PORTB // выход данных SPI, должен быть соответствующий пин аппаратного SPI, если он используется #define LCD_MOSI_DDR DDRB #define LCD_MOSI_PIN 3 #define LCD_CLK_PORT PORTB // тактирование SPI, должен быть соответствующий пин аппаратного SPI, если он используется #define LCD_CLK_DDR DDRB #define LCD_CLK_PIN 5 #ifndef SOFT_SPI #define LCD_SS_PORT PORTB // ChipSelect SPI, должен быть соответствующий пин аппаратного SPI и настроен на выход #define LCD_SS_DDR DDRB #define LCD_SS_PIN 2 #endif //*********************************************************** //Настройки контроллера дисплея и переменные для работы с ним //*********************************************************** #pragma used+ unsigned char lcd_buf[15]; //текстовый буфер для вывода на LCD bit power_down = 0; //power-down control: 0 - chip is active, 1 - chip is in PD-mode bit addressing = 0; //направление адресации: 0 - горизонтальная, 1- вертикальная //bit instuct_set = 0; //набор инструкций: 0 - стандартный, 1 - расширенный - в текущей версии не используется #ifdef china bit x_mirror = 0; //зеркалирование по X: 0 - выкл., 1 - вкл. bit y_mirror = 0; //зеркалирование по Y: 0 - выкл., 1 - вкл. bit SPI_invert = 0; //порядок битов в SPI: 0 - MSB first, 1 - LSB first #endif //unsigned char set_y; //адрес по У, 0..5 - в текущей версии не используется //unsigned char set_x; //адрес по Х, 0..83 - в текущей версии не используется //unsigned char temp_control = 3; //температурный коэффициент, 0..3 //unsigned char bias = 3; //смещение, 0..7 unsigned char Vop = 80; //рабочее напрядение LCD, 0..127 (определяет контрастность) unsigned char disp_config = 2; //режим дисплея: 0 - blank, 1 - all on, 2 - normal, 3 - inverse #define reverse_display #ifdef china unsigned char shift = 5; //0..3F - сдвиг экрана вверх, в точках #endif #define PIXEL_OFF 0 //режимы отображения пикселя - используются в графических функциях #define PIXEL_ON 1 #define PIXEL_XOR 2 #define LCD_X_RES 84 //разрешение экрана #define LCD_Y_RES 48 #define LCD_CACHSIZE LCD_X_RES*LCD_Y_RES/8 #define Cntr_X_RES 102 //разрешение контроллера - предполагаемое - но работает)) #define Cntr_Y_RES 64 #define Cntr_buf_size Cntr_X_RES*Cntr_Y_RES/8 unsigned char LcdCache [LCD_CACHSIZE]; //Cache buffer in SRAM 84*48 bits or 504 bytes unsigned int LcdCacheIdx; //Cache index #define LCD_CMD 0 #define LCD_DATA 1 //*************************************************** //****************Прототипы функций****************** //*************************************************** void LcdSend (unsigned char data, unsigned char cmd); //Sends data to display controller void LcdUpdate (void); //Copies the LCD cache into the device RAM void LcdClear (void); //Clears the display void LcdInit ( void ); //Настройка SPI и дисплея void LcdContrast (unsigned char contrast); //contrast -> Contrast value from 0x00 to 0x7F void LcdMode (unsigned char mode); //режимы дисплея: 0 - blank, 1 - all on, 2 - normal, 3 - inverse void LcdPwrMode (void); //инвертирует состояние вкл/выкл дисплея void LcdPwrOff (void); //выкл дисплея void LcdPwrOn (void); //вкл дисплея void LcdImage (flash unsigned char *imageData); //вывод изображения void LcdPixel (unsigned char x, unsigned char y, unsigned char mode); //Displays a pixel at given absolute (x, y) location, mode -> Off, On or Xor void LcdLine (int x1, int y1, int x2, int y2, unsigned char mode); //Draws a line between two points on the display void LcdCircle(char x, char y, char radius, unsigned char mode); //рисуем круг с координатами центра и радиусом void LcdBatt(int x1, int y1, int x2, int y2, unsigned char persent); //рисуем батарейку и заполняем ее на % void LcdGotoXYFont (unsigned char x, unsigned char y); //Sets cursor location to xy location. Range: 1,1 .. 14,6 void clean_lcd_buf (void); //очистка текстового буфера void LcdChr (int ch); //Displays a character at current cursor location and increment cursor location void LcdString (unsigned char x, unsigned char y); //Displays a string at current cursor location void LcdChrBold (int ch); //Печатает символ на текущем месте, большой и жирный) void LcdStringBold (unsigned char x, unsigned char y); //Печатает большую и жирную строку void LcdChrBig (int ch); //Печатает символ на текущем месте, большой void LcdStringBig (unsigned char x, unsigned char y); //Печатает большую строку //*************************************************** // UPDATE ##1 void LcdBar(int x1, int y1, int x2, int y2, unsigned char persent); // рисует прогресс-бар и заполняет его на "процент" void LcdBarLine(unsigned char line, unsigned char persent); // рисуем прошресс-бар в указанной строке void LcdStringInv (unsigned char x, unsigned char y); // печатает строку в инверсном шрифте (удобно для настроек) //ASCII flash char table[0x01E0] = { 0x00, 0x00, 0x00, 0x00, 0x00,// 20 space 0x00, 0x00, 0x5F, 0x00, 0x00,// 21 ! 0x00, 0x07, 0x00, 0x07, 0x00,// 22 " 0x14, 0x7F, 0x14, 0x7F, 0x14,// 23 # 0x24, 0x2A, 0x7F, 0x2A, 0x12,// 24 $ 0x23, 0x13, 0x08, 0x64, 0x62,// 25 % 0x36, 0x49, 0x55, 0x22, 0x50,// 26 & 0x00, 0x05, 0x03, 0x00, 0x00,// 27 ' 0x00, 0x1C, 0x22, 0x41, 0x00,// 28 ( 0x00, 0x41, 0x22, 0x1C, 0x00,// 29 ) 0x14, 0x08, 0x3E, 0x08, 0x14,// 2a * 0x08, 0x08, 0x3E, 0x08, 0x08,// 2b + 0x00, 0x50, 0x30, 0x00, 0x00,// 2c , 0x08, 0x08, 0x08, 0x08, 0x08,// 2d - 0x00, 0x60, 0x60, 0x00, 0x00,// 2e . 0x20, 0x10, 0x08, 0x04, 0x02,// 2f / 0x3E, 0x51, 0x49, 0x45, 0x3E,// 30 0 0x00, 0x42, 0x7F, 0x40, 0x00,// 31 1 0x42, 0x61, 0x51, 0x49, 0x46,// 32 2 0x21, 0x41, 0x45, 0x4B, 0x31,// 33 3 0x18, 0x14, 0x12, 0x7F, 0x10,// 34 4 0x27, 0x45, 0x45, 0x45, 0x39,// 35 5 0x3C, 0x4A, 0x49, 0x49, 0x30,// 36 6 0x01, 0x71, 0x09, 0x05, 0x03,// 37 7 0x36, 0x49, 0x49, 0x49, 0x36,// 38 8 0x06, 0x49, 0x49, 0x29, 0x1E,// 39 9 0x00, 0x36, 0x36, 0x00, 0x00,// 3a : 0x00, 0x56, 0x36, 0x00, 0x00,// 3b ; 0x08, 0x14, 0x22, 0x41, 0x00,// 3c < 0x14, 0x14, 0x14, 0x14, 0x14,// 3d = 0x00, 0x41, 0x22, 0x14, 0x08,// 3e > 0x02, 0x01, 0x51, 0x09, 0x06,// 3f ? 0x32, 0x49, 0x79, 0x41, 0x3E,// 40 @ 0x7E, 0x11, 0x11, 0x11, 0x7E,// 41 A 0x7F, 0x49, 0x49, 0x49, 0x36,// 42 B 0x3E, 0x41, 0x41, 0x41, 0x22,// 43 C 0x7F, 0x41, 0x41, 0x22, 0x1C,// 44 D 0x7F, 0x49, 0x49, 0x49, 0x41,// 45 E 0x7F, 0x09, 0x09, 0x09, 0x01,// 46 F 0x3E, 0x41, 0x49, 0x49, 0x7A,// 47 G 0x7F, 0x08, 0x08, 0x08, 0x7F,// 48 H 0x00, 0x41, 0x7F, 0x41, 0x00,// 49 I 0x20, 0x40, 0x41, 0x3F, 0x01,// 4a J 0x7F, 0x08, 0x14, 0x22, 0x41,// 4b K 0x7F, 0x40, 0x40, 0x40, 0x40,// 4c L 0x7F, 0x02, 0x0C, 0x02, 0x7F,// 4d M 0x7F, 0x04, 0x08, 0x10, 0x7F,// 4e N 0x3E, 0x41, 0x41, 0x41, 0x3E,// 4f O 0x7F, 0x09, 0x09, 0x09, 0x06,// 50 P 0x3E, 0x41, 0x51, 0x21, 0x5E,// 51 Q 0x7F, 0x09, 0x19, 0x29, 0x46,// 52 R 0x46, 0x49, 0x49, 0x49, 0x31,// 53 S 0x01, 0x01, 0x7F, 0x01, 0x01,// 54 T 0x3F, 0x40, 0x40, 0x40, 0x3F,// 55 U 0x1F, 0x20, 0x40, 0x20, 0x1F,// 56 V 0x3F, 0x40, 0x38, 0x40, 0x3F,// 57 W 0x63, 0x14, 0x08, 0x14, 0x63,// 58 X 0x07, 0x08, 0x70, 0x08, 0x07,// 59 Y 0x61, 0x51, 0x49, 0x45, 0x43,// 5a Z 0x00, 0x7F, 0x41, 0x41, 0x00,// 5b [ 0x02, 0x04, 0x08, 0x10, 0x20,// 5c Yen Currency Sign 0x00, 0x41, 0x41, 0x7F, 0x00,// 5d ] 0x04, 0x02, 0x01, 0x02, 0x04,// 5e ^ 0x40, 0x40, 0x40, 0x40, 0x40,// 5f _ 0x00, 0x01, 0x02, 0x04, 0x00,// 60 ` 0x20, 0x54, 0x54, 0x54, 0x78,// 61 a 0x7F, 0x48, 0x44, 0x44, 0x38,// 62 b 0x38, 0x44, 0x44, 0x44, 0x20,// 63 c 0x38, 0x44, 0x44, 0x48, 0x7F,// 64 d 0x38, 0x54, 0x54, 0x54, 0x18,// 65 e 0x08, 0x7E, 0x09, 0x01, 0x02,// 66 f 0x0C, 0x52, 0x52, 0x52, 0x3E,// 67 g 0x7F, 0x08, 0x04, 0x04, 0x78,// 68 h 0x00, 0x44, 0x7D, 0x40, 0x00,// 69 i 0x20, 0x40, 0x44, 0x3D, 0x00,// 6a j 0x7F, 0x10, 0x28, 0x44, 0x00,// 6b k 0x00, 0x41, 0x7F, 0x40, 0x00,// 6c l 0x7C, 0x04, 0x18, 0x04, 0x78,// 6d m 0x7C, 0x08, 0x04, 0x04, 0x78,// 6e n 0x38, 0x44, 0x44, 0x44, 0x38,// 6f o 0x7C, 0x14, 0x14, 0x14, 0x08,// 70 p 0x08, 0x14, 0x14, 0x18, 0x7C,// 71 q 0x7C, 0x08, 0x04, 0x04, 0x08,// 72 r 0x08, 0x54, 0x54, 0x54, 0x20,// 73 s 0x04, 0x3F, 0x44, 0x40, 0x20,// 74 t 0x3C, 0x40, 0x40, 0x20, 0x7C,// 75 u 0x1C, 0x20, 0x40, 0x20, 0x1C,// 76 v 0x3C, 0x40, 0x30, 0x40, 0x3C,// 77 w 0x44, 0x28, 0x10, 0x28, 0x44,// 78 x 0x0C, 0x50, 0x50, 0x50, 0x3C,// 79 y 0x44, 0x64, 0x54, 0x4C, 0x44,// 7a z 0x00, 0x08, 0x36, 0x41, 0x00,// 7b < 0x00, 0x00, 0x7F, 0x00, 0x00,// 7c | 0x00, 0x41, 0x36, 0x08, 0x00,// 7d > 0x10, 0x08, 0x08, 0x10, 0x08,// 7e Right Arrow -> 0x78, 0x46, 0x41, 0x46, 0x78 // 7f Left Arrow <- }; flash char table_rus[0x0140] = { 0x7E, 0x11, 0x11, 0x11, 0x7E,// C0 А 0x7F, 0x49, 0x49, 0x49, 0x31,// C1 Б 0x7F, 0x49, 0x49, 0x49, 0x36,// C2 В 0x7F, 0x01, 0x01, 0x01, 0x03,// C3 Г 0x60, 0x3E, 0x21, 0x21, 0x7F,// C4 Д 0x7F, 0x49, 0x49, 0x49, 0x41,// C5 Е 0x77, 0x08, 0x7F, 0x08, 0x77,// C6 Ж 0x22, 0x41, 0x49, 0x49, 0x36,// C7 З 0x7F, 0x10, 0x08, 0x04, 0x7F,// C8 И 0x7F, 0x10, 0x09, 0x04, 0x7F,// C9 И 0x7F, 0x08, 0x14, 0x22, 0x41,// CA К 0x40, 0x3E, 0x01, 0x01, 0x7F,// CB Л 0x7F, 0x02, 0x0C, 0x02, 0x7F,// CC М 0x7F, 0x08, 0x08, 0x08, 0x7F,// CD Н 0x3E, 0x41, 0x41, 0x41, 0x3E,// CE О 0x7F, 0x01, 0x01, 0x01, 0x7F,// CF П 0x7F, 0x09, 0x09, 0x09, 0x06,// D0 Р 0x3E, 0x41, 0x41, 0x41, 0x22,// D1 С 0x01, 0x01, 0x7F, 0x01, 0x01,// D2 Т 0x27, 0x48, 0x48, 0x48, 0x3F,// D3 У 0x1E, 0x21, 0x7F, 0x21, 0x1E,// D4 Ф 0x63, 0x14, 0x08, 0x14, 0x63,// D5 Х 0x3F, 0x20, 0x20, 0x3F, 0x60,// D6 Ц 0x07, 0x08, 0x08, 0x08, 0x7F,// D7 Ч 0x7F, 0x40, 0x7F, 0x40, 0x7F,// D8 Ш 0x3F, 0x20, 0x3F, 0x20, 0x7F,// D9 Щ 0x01, 0x7F, 0x48, 0x48, 0x30,// DA Ъ 0x7F, 0x48, 0x30, 0x00, 0x7F,// DB Ы 0x00, 0x7F, 0x48, 0x48, 0x30,// DC Ь 0x22, 0x41, 0x49, 0x49, 0x3E,// DD Э 0x7F, 0x08, 0x3E, 0x41, 0x3E,// DE Ю 0x46, 0x29, 0x19, 0x09, 0x7F,// DF Я 0x20, 0x54, 0x54, 0x54, 0x78,// E0 а 0x3C, 0x4A, 0x4A, 0x4A, 0x30,// E1 б 0x7C, 0x54, 0x54, 0x28, 0x00,// E2 в 0x7C, 0x04, 0x04, 0x04, 0x04,// E3 г 0x60, 0x38, 0x24, 0x24, 0x7C,// E4 д 0x38, 0x54, 0x54, 0x54, 0x18,// E5 е 0x6C, 0x10, 0x7C, 0x10, 0x6C,// E6 ж 0x00, 0x44, 0x54, 0x54, 0x28,// E7 з 0x7C, 0x20, 0x10, 0x08, 0x7C,// E8 и 0x7C, 0x21, 0x12, 0x09, 0x7C,// E9 й 0x7C, 0x10, 0x28, 0x44, 0x00,// EA к 0x40, 0x38, 0x04, 0x04, 0x7C,// EB л 0x7C, 0x08, 0x10, 0x08, 0x7C,// EC м 0x7C, 0x10, 0x10, 0x10, 0x7C,// ED н 0x38, 0x44, 0x44, 0x44, 0x38,// EE о 0x7C, 0x04, 0x04, 0x04, 0x7C,// EF п 0x7C, 0x14, 0x14, 0x14, 0x08,// F0 р 0x38, 0x44, 0x44, 0x44, 0x00,// F1 с 0x04, 0x04, 0x7C, 0x04, 0x04,// F2 т 0x0C, 0x50, 0x50, 0x50, 0x3C,// F3 у 0x08, 0x14, 0x7C, 0x14, 0x08,// F4 ф 0x44, 0x28, 0x10, 0x28, 0x44,// F5 х 0x3C, 0x20, 0x20, 0x3C, 0x60,// F6 ц 0x0C, 0x10, 0x10, 0x10, 0x7C,// F7 ч 0x7C, 0x40, 0x7C, 0x40, 0x7C,// F8 ш 0x3C, 0x20, 0x3C, 0x20, 0x7C,// F9 щ 0x04, 0x7C, 0x50, 0x50, 0x20,// FA ъ 0x7C, 0x50, 0x20, 0x00, 0x7C,// FB ы 0x00, 0x7C, 0x50, 0x50, 0x20,// FC ь 0x28, 0x44, 0x54, 0x54, 0x38,// FD э 0x7C, 0x10, 0x38, 0x44, 0x38,// FE ю 0x48, 0x54, 0x34, 0x14, 0x7C // FF я }; void LcdSend (unsigned char data, unsigned char cmd) //Sends data to display controller { #ifdef SOFT_SPI unsigned char i, mask = 128; #endif LCD_CPORT.LCD_CPIN = 0; //Enable display controller (active low) if (cmd) LCD_DC_PORT.LCD_DC_PIN = 1; //выбираем команда или данные else LCD_DC_PORT.LCD_DC_PIN = 0; #ifdef SOFT_SPI if(cmd==LCD_DATA) { #ifdef reverse_display mask = 1; for (i=0;i<8;i++) { if ((data&mask)!=0) LCD_MOSI_PORT.LCD_MOSI_PIN = 1; else LCD_MOSI_PORT.LCD_MOSI_PIN = 0; mask = mask*2; LCD_CLK_PORT.LCD_CLK_PIN = 1; LCD_CLK_PORT.LCD_CLK_PIN = 0; } #else for (i=0;i<8;i++) { if ((data&mask)!=0) LCD_MOSI_PORT.LCD_MOSI_PIN = 1; else LCD_MOSI_PORT.LCD_MOSI_PIN = 0; mask = mask/2; LCD_CLK_PORT.LCD_CLK_PIN = 1; LCD_CLK_PORT.LCD_CLK_PIN = 0; } #endif } else { for (i=0;i<8;i++) { if ((data&mask)!=0) LCD_MOSI_PORT.LCD_MOSI_PIN = 1; else LCD_MOSI_PORT.LCD_MOSI_PIN = 0; mask = mask/2; LCD_CLK_PORT.LCD_CLK_PIN = 1; LCD_CLK_PORT.LCD_CLK_PIN = 0; } } #endif #ifndef SOFT_SPI SPDR = data; //Send data to display controller while ( (SPSR & 0x80) != 0x80 ); //Wait until Tx register empty #endif LCD_CPORT.LCD_CPIN = 1; //Disable display controller } void LcdUpdate (void) //Copies the LCD cache into the device RAM { int i; #ifdef china char j; #endif LcdSend(0x80, LCD_CMD); //команды установки указателя памяти дисплея на 0,0 LcdSend(0x40, LCD_CMD); #ifdef china //если китайский дисплей - грузим пустую строку for (j = Cntr_X_RES; j>0; j--) LcdSend(0, LCD_DATA); #endif #ifdef reverse_display for (i = LCD_CACHSIZE-1; i>=0; i--) //грузим данные #else for (i = 0; i < LCD_CACHSIZE; i++) //грузим данные #endif { LcdSend(LcdCache[i], LCD_DATA); #ifdef china //если дисплей китайский - догружаем каждую строку до размера его буфера if (++j == LCD_X_RES) { for (j = (Cntr_X_RES-LCD_X_RES); j>0; j--) LcdSend(0, LCD_DATA); j=0; } #endif } } void LcdClear_massive (void) //Clears the display { int i; for (i = 0; i < LCD_CACHSIZE; i++) LcdCache[i] = 0; //забиваем всю память 0 } void LcdClear (void) //Clears the display { LcdClear_massive(); //забиваем всю память 0 LcdUpdate (); } void LcdInit ( void ) //инициализация SPI и дисплея { LCD_RST_PORT.LCD_RST_PIN = 1; //настроили порты ввода/вывода LCD_RST_DDR.LCD_RST_PIN = LCD_DC_DDR.LCD_DC_PIN = LCD_CDDR.LCD_CPIN = LCD_MOSI_DDR.LCD_MOSI_PIN = LCD_CLK_DDR.LCD_CLK_PIN = 1; LCD_CLK_PORT.LCD_CLK_PIN = 0; #ifndef SOFT_SPI LCD_SS_DDR.LCD_SS_PIN = 1; LCD_SS_PORT.LCD_SS_PIN = 0; #endif delay_ms(1); #ifndef SOFT_SPI SPCR = SPCR_val; SPSR = SPSR_val; #endif LCD_RST_PORT.LCD_RST_PIN = 0; //дернули ресет delay_ms(20); LCD_RST_PORT.LCD_RST_PIN = 1; //Enable SPI port: No interrupt, MSBit first, Master mode, CPOL->0, CPHA->0, Clk/4 LCD_CPORT.LCD_CPIN = 1; //Disable LCD controller /* LcdSend(0x21, LCD_CMD); LcdSend(0xC5, LCD_CMD); LcdSend(0x06, LCD_CMD); LcdSend(0x20, LCD_CMD); //<-------- LcdSend(0x20, LCD_CMD); LcdSend(0x0C, LCD_CMD); */ LcdSend( 0b00100001, LCD_CMD ); //LCD Extended Commands LcdSend( 0b00000111, LCD_CMD ); //Set Temp coefficent 3 #ifdef china LcdSend( 0b00001000|SPI_invert<<3, LCD_CMD ); //порядок битов в SPI #endif LcdSend( 0b00010011, LCD_CMD ); //LCD bias mode 1:48 (3) #ifdef china LcdSend( 0b01000000+shift, LCD_CMD ); //первая строка выше экрана, отображаем со второй #endif LcdSend( 0b10000000+Vop, LCD_CMD ); //Set LCD Vop (Contrast) #ifdef china LcdSend( 0x20|x_mirror<<4|y_mirror<<3|power_down<<2, LCD_CMD ); //LCD Standard Commands #endif LcdSend( 0x20|power_down<<2|addressing<<1, LCD_CMD ); //XXXX //LCD Standard Commands LcdSend( 0b00001000|((disp_config<<1|disp_config)&0b00000101), LCD_CMD ); //LCD mode LcdClear(); } void LcdContrast (unsigned char contrast) //contrast -> Contrast value from 0x00 to 0x7F { if (contrast > 0x7F) return; LcdSend( 0x21, LCD_CMD ); //LCD Extended Commands LcdSend( 0x80 | contrast, LCD_CMD ); //Set LCD Vop (Contrast) LcdSend( 0x20, LCD_CMD ); //LCD Standard Commands,Horizontal addressing mode } void LcdMode (unsigned char mode) //режим дисплея: 0 - blank, 1 - all on, 2 - normal, 3 - inverse { if (mode > 3) return; LcdSend( 0b00001000|((mode<<1|mode)&0b00000101), LCD_CMD ); //LCD mode } void LcdPwrMode (void) //инвертирует состояние вкл/выкл дисплея { power_down = ~power_down; #ifdef china LcdSend( 0x20|x_mirror<<4|y_mirror<<3|power_down<<2|addressing<<1, LCD_CMD ); //LCD Standard Commands #else //LcdSend( 0x20|0<<2|addressing<<1, LCD_CMD ); LcdSend( 0x20|power_down<<2|addressing<<1, LCD_CMD ); //LCD Standard Commands //LcdSend( 0x20|power_down<<3, LCD_CMD ); #endif } void Lcd_turn (unsigned char mode) //вкл/выкл дисплея { #ifdef china LcdSend( 0x20|x_mirror<<4|y_mirror<<3|mode<<2|addressing<<1, LCD_CMD ); //LCD Standard Commands #else LcdSend( 0x20|mode<<2|addressing<<1, LCD_CMD ); #endif } void Lcd_off (void) //выкл дисплея { Lcd_turn(1); } void Lcd_on (void) //вкл дисплея { Lcd_turn(0); } void LcdImage (flash unsigned char *imageData) //вывод изображения { unsigned int i; LcdSend(0x80, LCD_CMD); //ставим указатель на 0,0 LcdSend(0x40, LCD_CMD); for (i = 0; i < LCD_CACHSIZE; i++) LcdCache[i] = imageData[i]; //грузим данные } void LcdPixel (unsigned char x, unsigned char y, unsigned char mode) //Displays a pixel at given absolute (x, y) location, mode -> Off, On or Xor { int index; unsigned char offset, data; if ( x > LCD_X_RES ) return; //если передали в функцию муть - выходим if ( y > LCD_Y_RES ) return; index = (((int)(y)/8)*84)+x; //считаем номер байта в массиве памяти дисплея offset = y-((y/8)*8); //считаем номер бита в этом байте data = LcdCache[index]; //берем байт по найденному индексу if ( mode == PIXEL_OFF ) data &= ( ~( 0x01 << offset ) ); //редактируем бит в этом байте else if ( mode == PIXEL_ON ) data |= ( 0x01 << offset ); else if ( mode == PIXEL_XOR ) data ^= ( 0x01 << offset ); LcdCache[index] = data; //загружаем байт назад } void LcdLine (int x1, int y1, int x2, int y2, unsigned char mode) //Draws a line between two points on the display - по Брезенхейму { signed int dy = 0; signed int dx = 0; signed int stepx = 0; signed int stepy = 0; signed int fraction = 0; if (x1>LCD_X_RES || x2>LCD_X_RES || y1>LCD_Y_RES || y2>LCD_Y_RES) return; dy = y2 - y1; dx = x2 - x1; if (dy < 0) { dy = -dy; stepy = -1; } else stepy = 1; if (dx < 0) { dx = -dx; stepx = -1; } else stepx = 1; dy <<= 1; dx <<= 1; LcdPixel(x1,y1,mode); if (dx > dy) { fraction = dy - (dx >> 1); while (x1 != x2) { if (fraction >= 0) { y1 += stepy; fraction -= dx; } x1 += stepx; fraction += dy; LcdPixel(x1,y1,mode); } } else { fraction = dx - (dy >> 1); while (y1 != y2) { if (fraction >= 0) { x1 += stepx; fraction -= dy; } y1 += stepy; fraction += dx; LcdPixel(x1,y1,mode); } } } void LcdCircle(char x, char y, char radius, unsigned char mode) //рисуем круг по координатам с радиусом - по Брезенхейму { signed char xc = 0; signed char yc = 0; signed char p = 0; if (x>LCD_X_RES || y>LCD_Y_RES) return; yc=radius; p = 3 - (radius<<1); while (xc <= yc) { LcdPixel(x + xc, y + yc, mode); LcdPixel(x + xc, y - yc, mode); LcdPixel(x - xc, y + yc, mode); LcdPixel(x - xc, y - yc, mode); LcdPixel(x + yc, y + xc, mode); LcdPixel(x + yc, y - xc, mode); LcdPixel(x - yc, y + xc, mode); LcdPixel(x - yc, y - xc, mode); if (p < 0) p += (xc++ << 2) + 6; else p += ((xc++ - yc--)<<2) + 10; } } void LcdBatt(int x1, int y1, int x2, int y2, unsigned char persent) //рисуем батарейку с заполнением в % { unsigned char horizon_line,horizon_line2,i; if(persent>100)return; LcdLine(x1,y2,x2,y2,1); //down LcdLine(x2,y1,x2,y2,1); //right LcdLine(x1,y1,x1,y2,1); //left LcdLine(x1,y1,x2,y1,1); //up LcdLine(x1+7,y1-1,x2-7,y1-1,1); LcdLine(x1+7,y1-2,x2-7,y1-2,1); horizon_line=persent*(y2-y1-3)/100; for(i=0;ihorizon_line;i--) LcdLine(x1+2,y2-2-i,x2-2,y2-2-i,0); } void LcdBar(int x1, int y1, int x2, int y2, unsigned char persent) //рисуем прогресс-бар { unsigned char line; if(persent>100)return; LcdLine(x1+2,y2,x2-2,y2,1); //down LcdLine(x2-2,y1,x2-2,y2,1); //right LcdLine(x1+2,y1,x1+2,y2,1); //left LcdLine(x1+2,y1,x2-2,y1,1); //up LcdLine(x2-1,y1+1,x2-1,y2-1,1); //right LcdLine(x1+1,y1+1,x1+1,y2-1,1); //left LcdLine(x2,y1+2,x2,y2-2,1); //right LcdLine(x1,y1+2,x1,y2-2,1); //left line=persent*(x2-x1-7)/100-1; LcdLine(x1+4,y1+2,x2-4,y2-2,0); LcdLine(x1+4,y1+2,x1+4+line,y2-2,1); } void LcdBarLine(unsigned char line, unsigned char persent) //рисуем прошресс-бар { LcdBar(0, (line-1)*7+1, 83, (line-1)*7+5, persent); } void LcdGotoXYFont (unsigned char x, unsigned char y) //Sets cursor location to xy location. Range: 1,1 .. 14,6 { if (x <= 14 && y <= 6) LcdCacheIdx = ( (int)(y) - 1 ) * 84 + ( (int)(x) - 1 ) * 6; } void clean_lcd_buf (void) //очистка текстового буфера { char i; for (i=0; i<14; i++) lcd_buf[i] = 0; } void LcdChr (int ch) //Displays a character at current cursor location and increment cursor location { unsigned char i; for ( i = 0; i < 5; i++ ) { LcdCache[LcdCacheIdx++] = (ch>0x7f) ? table_rus[(ch*5+i-0x3C0)] : table[(ch*5+i-0xA0)]; //выделяем байт-столбик из символа и грузим в массив - 5 раз } LcdCache[LcdCacheIdx++] = 0x00; //добавляем пробел между символами } void LcdChrInv (int ch) //Displays a character at current cursor location and increment cursor location { unsigned char i; for ( i = 0; i < 5; i++ ) { LcdCache[LcdCacheIdx++] = (ch>0x7f) ? ~(table_rus[(ch*5+i-0x3C0)]) : ~(table[(ch*5+i-0xA0)]); //выделяем байт-столбик из символа и грузим в массив - 5 раз } LcdCache[LcdCacheIdx++] = 0xFF; //добавляем пробел между символами } void LcdString (unsigned char x, unsigned char y) //Displays a string at current cursor location { unsigned char i; if (x > 14 || y > 6) return; LcdGotoXYFont (x, y); for ( i = 0; i < 15-x; i++ ) if (lcd_buf[i]) LcdChr (lcd_buf[i]); clean_lcd_buf(); } void LcdStringInv (unsigned char x, unsigned char y) //Displays a string at current cursor location { unsigned char i; if (x > 14 || y > 6) return; LcdGotoXYFont (x, y); for ( i = 0; i < 15-x; i++ ) if (lcd_buf[i]) LcdChrInv (lcd_buf[i]); clean_lcd_buf(); } unsigned char Stretch( unsigned char n ) { return (n & 0x01) * 3 | (n & 0x02) * 6 | (n & 0x04) * 12 | (n & 0x08) * 24; } void LcdChrBold (int ch) //Displays a bold character at current cursor location and increment cursor location { unsigned char i; unsigned char a = 0, b = 0, c = 0; for ( i = 0; i < 5; i++ ) { c = (ch>0x7f) ? table_rus[(ch*5+i-0x3C0)] : table[(ch*5+i-0xA0)]; //выделяем столбец из символа b = Stretch(c); c >>= 4; a = Stretch (c); if(alarm) { LcdCache[LcdCacheIdx] = ~b; //копируем байты в экранный буфер LcdCache[LcdCacheIdx+1] = ~b; //дублируем для получения жирного шрифта LcdCache[LcdCacheIdx+84] = ~a; LcdCache[LcdCacheIdx+85] = ~a; } else { LcdCache[LcdCacheIdx] = b; //копируем байты в экранный буфер LcdCache[LcdCacheIdx+1] = b; //дублируем для получения жирного шрифта LcdCache[LcdCacheIdx+84] = a; LcdCache[LcdCacheIdx+85] = a; } LcdCacheIdx = LcdCacheIdx+2; } if(alarm) { LcdCache[LcdCacheIdx+84] = 0xFF; //для пробела между символами LcdCache[LcdCacheIdx+85] = 0xFF; LcdCache[LcdCacheIdx] = 0xFF; LcdCache[LcdCacheIdx+1] = 0xFF; LcdCacheIdx+=2; } else { LcdCache[LcdCacheIdx++] = 0x00; //для пробела между символами LcdCache[LcdCacheIdx++] = 0x00; } } void LcdStringBold (unsigned char x, unsigned char y) //Displays a string at current cursor location { unsigned char i; if (x > 13 || y > 5) return; LcdGotoXYFont (x, y); for ( i = 0; i < 14-x; i++ ) if (lcd_buf[i]) LcdChrBold (lcd_buf[i]); clean_lcd_buf(); } void LcdChrBig (int ch) //Displays a character at current cursor location and increment cursor location { unsigned char i; unsigned char a = 0, b = 0, c = 0; for ( i = 0; i < 5; i++ ) { c = (ch>0x7f) ? table[(ch*5+i-0x3C0)] : table[(ch*5+i-0xA0)]; //выделяем столбец из символа b = Stretch(c); c >>= 4; a = Stretch(c); LcdCache[LcdCacheIdx] = b; LcdCache[LcdCacheIdx+84] = a; LcdCacheIdx = LcdCacheIdx+1; } LcdCache[LcdCacheIdx++] = 0x00; } void LcdStringBig (unsigned char x, unsigned char y) //Displays a string at current cursor location { unsigned char i; if (x > 14 || y > 5) return; LcdGotoXYFont (x, y); for ( i = 0; i < 15-x; i++ ) if (lcd_buf[i]) LcdChrBig (lcd_buf[i]); clean_lcd_buf(); } void LcdPwrOff(void) { if(!power_down) { //black_light_enable=0; beep=0; TIMSK=0x40; beep_pin=0; menu_active=0; power_down=1; led_refresh(NONE); power_of_display=0; //power_of_display_ddr=0; LCD_DC_PORT.LCD_DC_PIN=0; //LCD_DC_DDR.LCD_DC_PIN=0; LCD_CPORT.LCD_CPIN=0; //LCD_CDDR.LCD_CPIN=0; LCD_RST_PORT.LCD_RST_PIN=0; //LCD_RST_DDR.LCD_RST_PIN=0; LCD_MOSI_PORT.LCD_MOSI_PIN=0; //LCD_MOSI_DDR.LCD_MOSI_PIN=0; LCD_CLK_PORT.LCD_CLK_PIN=0; //LCD_CLK_DDR.LCD_CLK_PIN=0; } } void LcdPwrOn(void) { if(power_down) { power_of_display=1; power_of_display_ddr=1; power_down=0; led_refresh(NONE); delay_ms(100); LcdInit(); LcdUpdate(); } } #pragma used-