//*************************************************************************** // // Author(s)...: Pashgan ChipEnable.Ru // // Target(s)...: любая мега // // Compiler....: IAR EWA 5.11A // // Description.: драйвер графического индикатора МТ12232 // // Data........: 16.01.10 // //*************************************************************************** #include "lcd_graph_lib.h" #include "font_6x8.h" //макросы программных задержек #define _delay_ns(time) __delay_cycles(time*(F_CPU/1000000000)) #define _delay_us(time) __delay_cycles(time*(F_CPU/1000000)) #define _delay_ms(time) __delay_cycles(time*(F_CPU/1000)) #define PAGE0 0xb8 #define PAGE1 0xb9 #define PAGE2 0xba #define PAGE3 0xbb #define FLAG_BUSY 7 #define SelectLeftChip() SetBit(PORT_LCD_CON, CS) #define SelectRightChip() ClearBit(PORT_LCD_CON, CS) volatile unsigned char method = 1; volatile unsigned char flag = 0; //инициализация портов ввода/вывода void LCDG_InitPort(void) { DDRX_LCD_BUS = 0xff; PORT_LCD_BUS = 0xff; DDRX_LCD_CON |= ((1<<RES)|(1<<CS)|(1<<AO)|(1<<RD_WR)|(1<<EN)); PORT_LCD_CON |= ((1<<RES)|(1<<CS)|(1<<AO)|(1<<RD_WR)|(1<<EN)); } //функция чтения флага занятости void LCDG_WaitFLAG_BUSY(void) { unsigned char stat; DDRX_LCD_BUS = 0; //конфигурируем порт на вход PORT_LCD_BUS = 0xff; SetBit(PORT_LCD_CON, RD_WR); //выставляем управляющие сигналы ClearBit(PORT_LCD_CON, AO); __delay_cycles(2); do{ ClearBit(PORT_LCD_CON, EN); __delay_cycles(5); stat = PIN_LCD_BUS; //считываем статусный байт __delay_cycles(5); SetBit(PORT_LCD_CON, EN); } while((stat & (1<<FLAG_BUSY)) != 0); //сидим в цикле пока не сбросится флаг DDRX_LCD_BUS = 0xff; //делаем порт снова выходом PORT_LCD_BUS = 0; } //функция чтения байта данных из lcd unsigned char LCDG_ReadData(void) { unsigned char data; DDRX_LCD_BUS = 0; //конфигурируем порт на вход PORT_LCD_BUS = 0xff; SetBit(PORT_LCD_CON, RD_WR); SetBit(PORT_LCD_CON, AO); __delay_cycles(2); ClearBit(PORT_LCD_CON, EN); __delay_cycles(5); data = PIN_LCD_BUS; SetBit(PORT_LCD_CON, EN); //делаем порт снова выходом DDRX_LCD_BUS = 0xff; PORT_LCD_BUS = 0; return data; } //общая функция #pragma inline = forced void LCDG_CommonFunc(unsigned char data) { ClearBit(PORT_LCD_CON, RD_WR); __delay_cycles(2); ClearBit(PORT_LCD_CON, EN); PORT_LCD_BUS = data; __delay_cycles(5); SetBit(PORT_LCD_CON, EN); } //запись команды на lcd void LCDG_SendCom(unsigned char data) { LCDG_WaitFLAG_BUSY(); ClearBit(PORT_LCD_CON, AO); LCDG_CommonFunc(data); } //вывод данных на lcd void LCDG_SendData(unsigned char data) { LCDG_WaitFLAG_BUSY(); SetBit(PORT_LCD_CON, AO); LCDG_CommonFunc(data); } //функция инициализации lcd //подает сигнал сброса //настраивает правый и левый контроллеры void LCDG_InitLcd(void) { ClearBit(PORT_LCD_CON, RES); _delay_ms(400); SetBit(PORT_LCD_CON, RES); _delay_ms(400); SelectLeftChip(); LCDG_SendCom(COM_CLEAR_RMW); LCDG_SendCom(COM_STATIC_DRIVE_OFF); LCDG_SendCom(COM_DUTY_SELECT_ON); LCDG_SendCom(COM_DISPLAY_ON); LCDG_SendCom(COM_ADC_SELECT_ON); LCDG_SendCom(COM_RESET); LCDG_SendCom(COM_START_LINE(0)); SelectRightChip(); LCDG_SendCom(COM_CLEAR_RMW); LCDG_SendCom(COM_STATIC_DRIVE_OFF); LCDG_SendCom(COM_DUTY_SELECT_ON); LCDG_SendCom(COM_DISPLAY_ON); LCDG_SendCom(COM_ADC_SELECT_OFF); LCDG_SendCom(COM_RESET); LCDG_SendCom(COM_START_LINE(0)); } //функция очистки lcd void LCDG_ClrDisp(unsigned char x1, unsigned char x2) { unsigned char xPos = x1; unsigned char realAdr = 0; while(xPos < x2){ if (realAdr < 61) { SetBit(PORT_LCD_CON, CS); realAdr = realAdr + 19; } else { ClearBit(PORT_LCD_CON, CS); realAdr = realAdr - 61; } LCDG_SendCom(PAGE0); LCDG_SendCom(realAdr); LCDG_SendData(0); LCDG_SendCom(PAGE1); LCDG_SendCom(realAdr); LCDG_SendData(0); LCDG_SendCom(PAGE2); LCDG_SendCom(realAdr); LCDG_SendData(0); LCDG_SendCom(PAGE3); LCDG_SendCom(realAdr); LCDG_SendData(0); xPos++; realAdr = xPos; } } //установка метода вывода #pragma inline = forced void LCDG_SetMethod(unsigned char met) { method = met; } //отображает один пиксел на экране void LCDG_PutPixel(unsigned char xPos, unsigned char yPos) { unsigned char realAdr; unsigned char realPage; unsigned char data; unsigned char currentData; if ((xPos > 122) || (yPos > 31)) return; realAdr = xPos; realPage = PAGE0 + (yPos/8); data = yPos%8; if (realAdr < 61) { SetBit(PORT_LCD_CON, CS); realAdr = realAdr + 19; } else { ClearBit(PORT_LCD_CON, CS); realAdr = realAdr - 61; } LCDG_WaitFLAG_BUSY(); LCDG_SendCom(realPage); LCDG_SendCom(realAdr); LCDG_ReadData(); currentData = LCDG_ReadData(); switch(method){ case MET_AND: {currentData &= ~(1<<data); break;} case MET_OR : {currentData |= (1<<data); break;} case MET_XOR : {currentData ^= (1<<data); break;} } LCDG_SendCom(realAdr); LCDG_SendData(currentData); } //Знакогенератор____________________________________________________________________________ //устанавливает флаг инверсии #pragma inline = forced void LCDG_SetInv(unsigned char f) { flag = f; } //отображает один символ на жкд //unsigned char PlaceArray[] = {0,8,16,24,32,40,48,56,64,72,80,88,96,104,112}; //unsigned char PlaceArray[] = {0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112}; unsigned char PlaceArray[] = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,90,96,102,108,114}; void LCDG_SendSymbol(unsigned char xPos, unsigned char yPos,unsigned char data) { unsigned char realAdr; unsigned char realPage = PAGE0 + yPos; unsigned int pointerFont = (data<<2) + (data<<1); realAdr = PlaceArray[xPos]; xPos = realAdr; for(unsigned char i = 0; i<=5; i++){ if (realAdr < 61) { SetBit(PORT_LCD_CON, CS); realAdr = realAdr + 19; } else { ClearBit(PORT_LCD_CON, CS); realAdr = realAdr - 61; } data = font_6x8_Data[pointerFont]; if(flag) data = ~data; LCDG_SendCom(realPage); LCDG_SendCom(realAdr); LCDG_SendData(data); xPos++; realAdr = xPos; pointerFont++; } } //отображает на жкд строку из ОЗУ void LCDG_SendString(unsigned char xPos, unsigned char yPos, char * string) { char data = 0; while(*string){ data = *string++; LCDG_SendSymbol(xPos,yPos,data); xPos++; } } //отображает на жкд строку из флэш памяти void LCDG_SendStringFl(unsigned char xPos, unsigned char yPos, char __flash * string) { char data = 0; while(*string){ data = *string++; LCDG_SendSymbol(xPos,yPos,data); xPos++; } } /****************************************************************************/ /* Функция вывода прямой по алгоритму Брезенхема */ /****************************************************************************/ void LCDG_DrawLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2) { int dx, dy, i1, i2, i, kx, ky; int d; int x, y; int flag; dy = y2 - y1; dx = x2 - x1; if (dx == 0 && dy == 0){ LCDG_PutPixel(x1,y1); return; } kx = 1; ky = 1; if( dx < 0 ){ dx = -dx; kx = -1; } else if(dx == 0) kx = 0; if(dy < 0) { dy = -dy; ky = -1; } if(dx < dy){ flag = 0; d = dx; dx = dy; dy = d; } else flag = 1; i1 = dy + dy; d = i1 - dx; i2 = d - dx; x = x1; y = y1; for(i=0; i < dx; i++){ LCDG_PutPixel(x,y); if(flag) x += kx; else y += ky; if( d < 0 ) d += i1; else{ d += i2; if(flag) y += ky; else x += kx; } } LCDG_PutPixel(x,y); } /****************************************************************************/ /* Функция вывода круга */ /****************************************************************************/ void LCDG_DrawCircle(unsigned char xc,unsigned char yc,unsigned char r) { int x,y,d; y = r; d = 3-2*r; x = 0; while(x <= y) { LCDG_PutPixel(x+xc,y+yc); LCDG_PutPixel(x+xc,-y+yc); LCDG_PutPixel(-x+xc,-y+yc); LCDG_PutPixel(-x+xc,y+yc); LCDG_PutPixel(y+xc,x+yc); LCDG_PutPixel(y+xc,-x+yc); LCDG_PutPixel(-y+xc,-x+yc); LCDG_PutPixel(-y+xc,x+yc); if (d<0) { d = d+4*x+6; } else { d = d+4*(x-y)+10; y--; } x++; }; } /****************************************************************************/ /* Функция рисования прямоугольника */ /****************************************************************************/ void LCDG_DrawRect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char fill) { LCDG_DrawLine(x1, y1, x2, y1); LCDG_DrawLine(x1, y2, x2, y2); LCDG_DrawLine(x1, (y1+1), x1, (y2-1)); LCDG_DrawLine(x2, (y1+1), x2, (y2-1)); if (fill){ while(x1<x2){ x1++; LCDG_DrawLine(x1, (y1+1), x1, (y2-1)); } } }