Biblioteka KS0108
-- Sebastian Pawlak, 2014.
Przedstawiam tu moją bibliotekę obsługującą
wyświetlacz KS0108.
Zamieściłem także kod krótkiego programu wykorzystującego bibliotekę.
Kod źródłowy pliku "libKS0108.h":
/* libKS0108: KS0108 LCD driver library * * This library was designed to operate with Atmel AVR ATmega128 * and 192x64 graphics display * * CSA=0, CSB=0: left part * CSA=0, CSB=1: middle part * CSA=1, CSB=0: right part * * Sebastian Pawlak, 2014, v1.1 */ #ifndef _KS0108_H_ #define _KS0108_H_ #define F_CPU 16000000 /* set your uC frequency */ #if F_CPU > 16000000 warning("Please, check if waiting time in delay() is long enough for your " "CPU, which is faster than 16MHz."); #endif extern uint8_t KS0108_x; extern uint8_t KS0108_y; /* display size */ enum { KS0108_DISPLAY_WIDTH = 192, /* width of the display in pixels */ KS0108_DISPLAY_HEIGHT = 64, /* height of the display in pixels */ SET_PIXEL = 1, CLEAR_PIXEL = 0, }; /* set proper ports and pins */ #define KS0108_DATA_OUTPUT_PORT PORTA #define KS0108_DATA_DDR_PORT DDRA #define KS0108_DATA_INPUT_PORT PINA #define KS0108_CONTROL_EN_OUTPUT_PORT PORTG #define KS0108_CONTROL_EN_OUTPUT_PIN PORTG2 #define KS0108_CONTROL_EN_DDR_PORT DDRG #define KS0108_CONTROL_EN_DDR_PIN DDG2 #define KS0108_CONTROL_RW_OUTPUT_PORT PORTF #define KS0108_CONTROL_RW_OUTPUT_PIN PORTF7 #define KS0108_CONTROL_RW_DDR_PORT DDRF #define KS0108_CONTROL_RW_DDR_PIN DDF7 #define KS0108_CONTROL_RS_OUTPUT_PORT PORTF #define KS0108_CONTROL_RS_OUTPUT_PIN PORTF6 #define KS0108_CONTROL_RS_DDR_PORT DDRF #define KS0108_CONTROL_RS_DDR_PIN DDF6 #define KS0108_CONTROL_CSB_OUTPUT_PORT PORTF #define KS0108_CONTROL_CSB_OUTPUT_PIN PORTF5 #define KS0108_CONTROL_CSB_DDR_PORT DDRF #define KS0108_CONTROL_CSB_DDR_PIN DDF5 #define KS0108_CONTROL_CSA_OUTPUT_PORT PORTF #define KS0108_CONTROL_CSA_OUTPUT_PIN PORTF4 #define KS0108_CONTROL_CSA_DDR_PORT DDRF #define KS0108_CONTROL_CSA_DDR_PIN DDF4 #define KS0108_CONTROL_RST_OUTPUT_PORT PORTF #define KS0108_CONTROL_RST_OUTPUT_PIN PORTF3 #define KS0108_CONTROL_RST_DDR_PORT DDRF #define KS0108_CONTROL_RST_DDR_PIN DDF3 #define _BV(bit) (1 << (bit)) #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) /* display control instructions */ #define KS0108_DISPLAY_TURN_ON_OFF 0x3E #define KS0108_DISPLAY_SET_ADDRESS 0x40 /* corresponding to X */ #define KS0108_DISPLAY_SET_PAGE 0xB8 /* page number */ #define KS0108_DISPLAY_SET_Z_ADDRESS 0xC0 /* display start line */ #define KS0108_DISPLAY_STATUS_BUSY_FLAG 0x80 #define KS0108_DISPLAY_STATUS_ON_OFF_FLAG 0x20 #define KS0108_DISPLAY_STATUS_RESET_FLAG 0x10 #define KS0108_CONTROL_SBI_EN \ sbi(KS0108_CONTROL_EN_OUTPUT_PORT, KS0108_CONTROL_EN_OUTPUT_PIN); #define KS0108_CONTROL_SBI_RW \ sbi(KS0108_CONTROL_RW_OUTPUT_PORT, KS0108_CONTROL_RW_OUTPUT_PIN); #define KS0108_CONTROL_SBI_RS \ sbi(KS0108_CONTROL_RS_OUTPUT_PORT, KS0108_CONTROL_RS_OUTPUT_PIN); #define KS0108_CONTROL_SBI_CSB \ sbi(KS0108_CONTROL_CSB_OUTPUT_PORT, KS0108_CONTROL_CSB_OUTPUT_PIN); #define KS0108_CONTROL_SBI_CSA \ sbi(KS0108_CONTROL_CSA_OUTPUT_PORT, KS0108_CONTROL_CSA_OUTPUT_PIN); #define KS0108_CONTROL_SBI_RST \ sbi(KS0108_CONTROL_RST_OUTPUT_PORT, KS0108_CONTROL_RST_OUTPUT_PIN); #define KS0108_CONTROL_CBI_EN \ cbi(KS0108_CONTROL_EN_OUTPUT_PORT, KS0108_CONTROL_EN_OUTPUT_PIN); #define KS0108_CONTROL_CBI_RW \ cbi(KS0108_CONTROL_RW_OUTPUT_PORT, KS0108_CONTROL_RW_OUTPUT_PIN); #define KS0108_CONTROL_CBI_RS \ cbi(KS0108_CONTROL_RS_OUTPUT_PORT, KS0108_CONTROL_RS_OUTPUT_PIN); #define KS0108_CONTROL_CBI_CSB \ cbi(KS0108_CONTROL_CSB_OUTPUT_PORT, KS0108_CONTROL_CSB_OUTPUT_PIN); #define KS0108_CONTROL_CBI_CSA \ cbi(KS0108_CONTROL_CSA_OUTPUT_PORT, KS0108_CONTROL_CSA_OUTPUT_PIN); #define KS0108_CONTROL_CBI_RST \ cbi(KS0108_CONTROL_RST_OUTPUT_PORT, KS0108_CONTROL_RST_OUTPUT_PIN); #define KS0108_CONTROL_ONLY_CSB \ sbi(KS0108_CONTROL_CSB_OUTPUT_PORT, KS0108_CONTROL_CSB_OUTPUT_PIN), \ cbi(KS0108_CONTROL_CSA_OUTPUT_PORT, KS0108_CONTROL_CSA_OUTPUT_PIN); #define KS0108_CONTROL_ONLY_CSA \ sbi(KS0108_CONTROL_CSA_OUTPUT_PORT, KS0108_CONTROL_CSA_OUTPUT_PIN), \ cbi(KS0108_CONTROL_CSB_OUTPUT_PORT, KS0108_CONTROL_CSB_OUTPUT_PIN); #define KS0108_CONTROL_NO_CS \ cbi(KS0108_CONTROL_CSA_OUTPUT_PORT, KS0108_CONTROL_CSA_OUTPUT_PIN), \ cbi(KS0108_CONTROL_CSB_OUTPUT_PORT, KS0108_CONTROL_CSB_OUTPUT_PIN); void KS0108_init(void); void KS0108_displayOn(void); void KS0108_displayOff(void); uint8_t KS0108_readStatus(); void inline KS0108_writeCommand(uint8_t cmd); void inline KS0108_setProperCS(void); void inline KS0108_writeData(uint8_t data); void inline KS0108_writeDataNoCS(uint8_t data); uint8_t inline KS0108_readData(void); void KS0108_gotoXY(uint8_t x, uint8_t y); void KS0108_setDisplay(void); void KS0108_clearDisplay(void); void inline KS0108_setPixelXY(uint8_t x, uint8_t y); void inline KS0108_clearPixelXY(uint8_t x, uint8_t y); void KS0108_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, int8_t c); void KS0108_drawLineFaster(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, int8_t c); void KS0108_drawHorizontalLine(register uint8_t x, uint8_t y, uint8_t width, int8_t c); void KS0108_drawVerticalLine(uint8_t x, uint8_t y, uint8_t height, int8_t c); void KS0108_drawRectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c); void KS0108_drawFilledRectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c); void KS0108_drawCircle(uint8_t x, uint8_t y, uint8_t r, int8_t c); void KS0108_drawFilledCircle(uint8_t x, uint8_t y, uint8_t r, int8_t c); void KS0108_drawBitmap(const uint8_t *bmp, uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c); void KS0108_drawSprite(const uint8_t *bmp, uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c); void KS0108_charGotoXY(uint8_t x, uint8_t y); void inline KS0108_writeChar(uint8_t ch, int8_t c); void inline KS0108_writeCharUTF8(uint32_t n, int8_t c); void inline KS0108_writeCharSprite(uint8_t ch, int8_t c); void inline KS0108_writeCharUTF8Sprite(uint32_t n, int8_t c); void KS0108_writeString(const uint8_t *s, int8_t c); void KS0108_writeStringUTF8(const uint8_t *s, int8_t c); void KS0108_writeStringSprite(const uint8_t *s, int8_t c); void KS0108_writeStringUTF8Sprite(const uint8_t *s, int8_t c); #endif
Kod źródłowy pliku "libKS0108.c":
/* libKS0108: KS0108 LCD driver library * * This library was designed to operate with Atmel AVR ATmega128 * and 192x64 graphics display * * CSA=0, CSB=0: left part * CSA=0, CSB=1: middle part * CSA=1, CSB=0: right part * * Sebastian Pawlak, 2014, v1.1 * * Changelog: * 2014-03-28, v1.1: possible to use control pins on different ports */ #include <avr/io.h> #include <avr/pgmspace.h> #include "libKS0108.h" #include "fonts5x8.h" uint8_t KS0108_x; /* X position in pixels */ uint8_t KS0108_y; /* Y position in pixels */ /* KS0108_delay: short KS0108_delay, just to be sure; * it is not probably demanded, if F_CPU == 16MHz */ void KS0108_delay(void) { asm volatile("nop\n\t" "nop\n\t" ::); } /* KS0108_busyWait: waits until the controller is not busy */ void inline KS0108_busyWait(void) { KS0108_DATA_DDR_PORT = 0x00; /* set pins to input */ KS0108_CONTROL_CBI_RS KS0108_CONTROL_SBI_RW /* status read */ do { KS0108_delay(); KS0108_CONTROL_SBI_EN KS0108_delay(); KS0108_CONTROL_CBI_EN } while (KS0108_DATA_INPUT_PORT & KS0108_DISPLAY_STATUS_BUSY_FLAG); KS0108_DATA_DDR_PORT = 0xff; /* set pins to output */ } /* KS0108_init: port and the display initialization */ void KS0108_init(void) { KS0108_DATA_DDR_PORT = 0xff; /* set pins to output */ KS0108_CONTROL_EN_DDR_PORT |= _BV(KS0108_CONTROL_EN_DDR_PIN); KS0108_CONTROL_RW_DDR_PORT |= _BV(KS0108_CONTROL_RW_DDR_PIN); KS0108_CONTROL_RS_DDR_PORT |= _BV(KS0108_CONTROL_RS_DDR_PIN); KS0108_CONTROL_CSB_DDR_PORT |= _BV(KS0108_CONTROL_CSB_DDR_PIN); KS0108_CONTROL_CSA_DDR_PORT |= _BV(KS0108_CONTROL_CSA_DDR_PIN); KS0108_CONTROL_RST_DDR_PORT |= _BV(KS0108_CONTROL_RST_DDR_PIN); KS0108_CONTROL_SBI_RST /* it is not demanded to connect RST signal */ KS0108_displayOn(); } /* KS0108_displayOn: turn the display on */ void KS0108_displayOn(void) { KS0108_CONTROL_CBI_RS KS0108_CONTROL_CBI_RW /* display on/off */ KS0108_CONTROL_NO_CS /* left part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x01); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x01); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); KS0108_CONTROL_ONLY_CSB /* middle part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x01); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); } /* KS0108_displayOff: turn the display off */ void KS0108_displayOff(void) { KS0108_CONTROL_CBI_RS KS0108_CONTROL_CBI_RW /* display on/off */ KS0108_CONTROL_NO_CS /* left part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x00); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x00); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); KS0108_CONTROL_ONLY_CSB /* middle part of the display */ KS0108_writeCommand(KS0108_DISPLAY_TURN_ON_OFF | 0x00); KS0108_writeCommand(KS0108_DISPLAY_SET_Z_ADDRESS | 0x00); } /* KS0108_readStatus: reads controller status; * do not forget to set proper CS before calling * this function * (only one CS may be active at each call of the function) */ uint8_t inline KS0108_readStatus() { uint8_t status; KS0108_DATA_DDR_PORT = 0x00; /* set pins to input */ KS0108_CONTROL_CBI_RS KS0108_CONTROL_SBI_RW /* status read */ KS0108_CONTROL_SBI_EN KS0108_delay(); status = KS0108_DATA_INPUT_PORT; KS0108_CONTROL_CBI_EN KS0108_DATA_DDR_PORT = 0xff; /* set pins to output */ return status; } /* KS0108_writeCommand: writes a command to the controller; * do not forget to set proper CS before calling * this function * (only one CS may be active at each call of the function) */ void inline KS0108_writeCommand(uint8_t cmd) { KS0108_busyWait(); KS0108_CONTROL_CBI_RS KS0108_CONTROL_CBI_RW /* write command */ KS0108_DATA_OUTPUT_PORT = cmd; KS0108_CONTROL_SBI_EN KS0108_delay(); KS0108_CONTROL_CBI_EN } /* KS0108_setProperCS: sets proper CS according to actual X */ void inline KS0108_setProperCS(void) { if (KS0108_x < 64) KS0108_CONTROL_NO_CS /* left part of the display */ else if (KS0108_x < 128) KS0108_CONTROL_ONLY_CSB /* middle part of the display */ else KS0108_CONTROL_ONLY_CSA /* right part of the display */ } /* KS0108_writeData: writes data to the controller */ void inline KS0108_writeData(uint8_t data) { KS0108_setProperCS(); KS0108_busyWait(); KS0108_CONTROL_SBI_RS KS0108_CONTROL_CBI_RW /* write data */ KS0108_DATA_OUTPUT_PORT = data; KS0108_CONTROL_SBI_EN KS0108_delay(); KS0108_CONTROL_CBI_EN if (++KS0108_x >= KS0108_DISPLAY_WIDTH) KS0108_x = 0; } /* KS0108_writeDataNoCS: writes data to the controller; does not set CS */ void inline KS0108_writeDataNoCS(uint8_t data) { KS0108_busyWait(); KS0108_CONTROL_SBI_RS KS0108_CONTROL_CBI_RW /* write data */ KS0108_DATA_OUTPUT_PORT = data; KS0108_CONTROL_SBI_EN KS0108_delay(); KS0108_CONTROL_CBI_EN if (++KS0108_x >= KS0108_DISPLAY_WIDTH) KS0108_x = 0; } /* KS0108_readData: reads data from the controller */ uint8_t inline KS0108_readData(void) { uint8_t data; KS0108_setProperCS(); KS0108_busyWait(); KS0108_DATA_DDR_PORT = 0x00; /* set pins to input */ KS0108_CONTROL_SBI_RS KS0108_CONTROL_SBI_RW /* read data */ KS0108_CONTROL_SBI_EN KS0108_delay(); data = KS0108_DATA_INPUT_PORT; KS0108_CONTROL_CBI_EN KS0108_DATA_DDR_PORT = 0xff; /* set pins to output */ if (++KS0108_x >= KS0108_DISPLAY_WIDTH) KS0108_x = 0; return data; } /* KS0108_gotoXY: sets X, Y position */ void inline KS0108_gotoXY(uint8_t x, uint8_t y) { KS0108_x = x; KS0108_y = y; if (KS0108_x < 64) { KS0108_CONTROL_NO_CS /* left part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | KS0108_x); } else if (KS0108_x < 128) { KS0108_CONTROL_ONLY_CSB /* middle part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (KS0108_x - 64)); } else { KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (KS0108_x - 128)); } } /* KS0108_setDisplay: sets all pixels of the display */ void KS0108_setDisplay(void) { register uint8_t x, y, mx; for (y = 0; y < 8; y++) { for (mx = 0; mx < KS0108_DISPLAY_WIDTH >> 6; mx++) { KS0108_gotoXY(mx << 6, y << 3); for (x = 0; x < 64; x++) KS0108_writeDataNoCS(0xff); } } } /* KS0108_clearDisplay: clears the display */ void KS0108_clearDisplay(void) { register uint8_t x, y, mx; for (y = 0; y < 8; y++) { for (mx = 0; mx < KS0108_DISPLAY_WIDTH >> 6; mx++) { KS0108_gotoXY(mx << 6, y << 3); for (x = 0; x < 64; x++) KS0108_writeDataNoCS(0x00); } } } /* KS0108_setPixelXY: sets pixel in X, Y */ void inline KS0108_setPixelXY(uint8_t x, uint8_t y) { uint8_t tmp; KS0108_gotoXY(x, y); KS0108_readData(); KS0108_gotoXY(x, y); /* it is demanded to do this twice */ tmp = KS0108_readData(); KS0108_gotoXY(x, y); KS0108_writeData(tmp | (0x01 << (y % 8))); } /* KS0108_clearPixelXY: clears pixel in X, Y */ void inline KS0108_clearPixelXY(uint8_t x, uint8_t y) { uint8_t tmp; KS0108_gotoXY(x, y); KS0108_readData(); KS0108_gotoXY(x, y); /* it is demanded to do this twice */ tmp = KS0108_readData(); KS0108_gotoXY(x, y); KS0108_writeData(tmp & ~(0x01 << (y % 8))); } /* KS0108_drawLine: draws a line */ void KS0108_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, int8_t c) { int16_t dx, sdx, px; int16_t dy, sdy, py; register int16_t x = 0, y = 0; void (*drawPixel)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&KS0108_setPixelXY) : (&KS0108_clearPixelXY)); dx = x2 - x1; dy = y2 - y1; sdx = (dx < 0) ? -1 : 1; sdy = (dy < 0) ? -1 : 1; dx = sdx * dx + 1; dy = sdy * dy + 1; px = x1; py = y1; if (dx >= dy) { for (x = 0; x < dx; x++) { drawPixel(px, py); y += dy; if (y >= dx) y -= dx, py += sdy; px += sdx; } } else { for (y = 0; y < dy; y++) { drawPixel(px, py); x += dx; if (x >= dy) x -= dy, px += sdx; py += sdy; } } } /* KS0108_drawLineFaster: draws a line; does it faster */ void KS0108_drawLineFaster(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, int8_t c) { int16_t dx, sdx, px; int16_t dy, py, ppy, spy = 0; register int16_t x = 0, y = 0; void (*drawPixel)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&KS0108_setPixelXY) : (&KS0108_clearPixelXY)); if (y2 < y1) { uint8_t tmp; tmp = y1, y1 = y2, y2 = tmp; tmp = x1, x1 = x2, x2 = tmp; } dx = x2 - x1; dy = y2 - y1 + 1; sdx = (dx < 0) ? -1 : 1; dx = sdx * dx + 1; px = x1; py = ppy = y1; if (dx >= dy) { for (x = 0; x < dx; x++) { drawPixel(px, py); y += dy; if (y >= dx) y -= dx, py++; px += sdx; } } else { for (y = 0; y < dy; y++) { spy++; x += dx; if (x >= dy) { KS0108_drawVerticalLine(px, ppy, spy, c); ppy = py + 1; spy = 0; x -= dy, px += sdx; } py++; } } } /* KS0108_drawHorizontalLine: draws a horizontal line */ void KS0108_drawHorizontalLine(register uint8_t x, uint8_t y, uint8_t width, int8_t c) { const uint8_t x2 = x + width; void (*drawPixel)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&KS0108_setPixelXY) : (&KS0108_clearPixelXY)); for ( ; x <= x2; x++) drawPixel(x, y); } /* setBits: sets proper bits in a byte; for internal use only */ inline uint8_t setBits(uint8_t byte, uint8_t bits) { return byte | bits; } /* clearBits: clears proper bits in a byte; for internal use only */ inline uint8_t clearBits(uint8_t byte, uint8_t bits) { return byte & (~bits); } /* KS0108_drawVerticalLine: draws a vertical line */ void KS0108_drawVerticalLine(uint8_t x, uint8_t y, uint8_t height, int8_t c) { const uint8_t y2 = y + height; uint8_t tmp, yy; uint8_t (*doBits)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&setBits) : (&clearBits)); /* draw top part of the line */ if ((y % 8) != 0) { KS0108_gotoXY(x, y); KS0108_readData(); KS0108_gotoXY(x, y); /* it is demanded to do this twice */ tmp = KS0108_readData(); KS0108_gotoXY(x, y); if ((y2 >> 3 == y >> 3) && (y2 % 8 != 0)) KS0108_writeData(doBits(tmp, ((0xff << (y % 8)) & (0xff >> (8 - (y2 % 8)))))); else KS0108_writeData(doBits(tmp, (0xff << (y % 8)))); } /* draw middle part of the line */ if ((y2 >> 3 != y >> 3) || ((y % 8) == 0)) { for (yy = (y >> 3) + ((y % 8) == 0 ? 0 : 1); yy < (y2 >> 3); yy++) { KS0108_gotoXY(x, yy << 3); KS0108_writeData((c == SET_PIXEL) ? 0xff : 0x00); } /* draw bottom part of the line */ if (y2 % 8 != 0) { KS0108_gotoXY(x, ((y2 >> 3) << 3)); KS0108_readData(); KS0108_gotoXY(x, ((y2 >> 3) << 3)); tmp = KS0108_readData(); KS0108_gotoXY(x, ((y2 >> 3) << 3)); KS0108_writeData(doBits(tmp, (0xff >> (8 - (y2 % 8))))); } } } /* KS0108_drawRectangle: draws a rectangle */ void KS0108_drawRectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c) { KS0108_drawHorizontalLine(x + 1, y, width - 2, c); KS0108_drawHorizontalLine(x + 1, y + height - 1, width - 2, c); KS0108_drawVerticalLine(x, y, height, c); KS0108_drawVerticalLine(x + width - 1, y, height, c); } /* KS0108_drawFilledRectangle: draws a filled rectangle * (this function need to be optimalized) */ void KS0108_drawFilledRectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c) { const uint8_t x2 = x + width; for ( ; x < x2; x++) KS0108_drawVerticalLine(x, y, height, c); } /* KS0108_drawCircle: draws a circle */ void KS0108_drawCircle(uint8_t x, uint8_t y, uint8_t r, int8_t c) { int16_t xx = r, yy = 0, xc = 1 - (r << 1), yc = 1, re = 0; void (*drawPixel)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&KS0108_setPixelXY) : (&KS0108_clearPixelXY)); while (xx >= yy) { drawPixel(x + xx, y + yy); drawPixel(x - xx, y + yy); drawPixel(x - xx, y - yy); drawPixel(x + xx, y - yy); drawPixel(x + yy, y + xx); drawPixel(x - yy, y + xx); drawPixel(x - yy, y - xx); drawPixel(x + yy, y - xx); yy++; re += yc; yc += 2; if ((re << 1) + xc > 0) { xx--; re += xc; xc += 2; } } } /* KS0108_drawFilledCircle: draws a filled circle */ void KS0108_drawFilledCircle(uint8_t x, uint8_t y, uint8_t r, int8_t c) { int16_t xx = r, yy = 0, xc = 1 - (r << 1), yc = 1, re = 0; while (xx >= yy) { KS0108_drawVerticalLine(x + xx, y - yy, yy << 1, c); KS0108_drawVerticalLine(x - xx, y - yy, yy << 1, c); KS0108_drawVerticalLine(x + yy, y - xx, xx << 1, c); KS0108_drawVerticalLine(x - yy, y - xx, xx << 1, c); yy++; re += yc; yc += 2; if ((re << 1) + xc > 0) { xx--; re += xc; xc += 2; } } } /* KS0108__gotoXY: for internal use; * but you need to use this function instead of KS0108_gotoXY(), * if you want to write a character or a string and do not * use KS0108_charGotoXY() */ void KS0108__gotoXY(uint8_t x, uint8_t y) { KS0108_x = x; KS0108_y = y; if (KS0108_x < 64) { KS0108_CONTROL_ONLY_CSB /* middle part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (0)); KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (0)); KS0108_CONTROL_NO_CS /* left part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | KS0108_x); } else if (KS0108_x < 128) { KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (0)); KS0108_CONTROL_ONLY_CSB /* middle part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (KS0108_x - 64)); } else { KS0108_CONTROL_ONLY_CSA /* right part of the display */ KS0108_writeCommand(KS0108_DISPLAY_SET_PAGE | (KS0108_y >> 3)); KS0108_writeCommand(KS0108_DISPLAY_SET_ADDRESS | (KS0108_x - 128)); } } /* KS0108_drawBitmap: draws a bitmap * "x" and "width" may be any * "y" % 8 should be 0, "height" % 8 should be 0 */ void KS0108_drawBitmap(const uint8_t *bmp, uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c) { register uint8_t xx; uint8_t yy, y2; y = (y >> 3) << 3; height = (height >> 3) << 3; y2 = height + y; for (yy = y; yy < y2; yy += 8) { KS0108__gotoXY(x, yy); if (c == SET_PIXEL) for(xx = 0; xx < width; xx++) KS0108_writeData(pgm_read_byte(bmp++)); else for(xx = 0; xx < width; xx++) KS0108_writeData(~pgm_read_byte(bmp++)); } } /* KS0108_drawSprite: draws a sprite * "x", "y", "width" and "height" may be any */ void KS0108_drawSprite(const uint8_t *bmp, uint8_t x, uint8_t y, uint8_t width, uint8_t height, int8_t c) { register uint8_t xx; uint8_t tmp, yy, yyMul8PlusY; uint8_t yyMax, yyMulWidth; uint8_t (*doBits)(uint8_t, uint8_t) = ((c == SET_PIXEL) ? (&setBits) : (&clearBits)); yyMax = (height >> 3) + ((height % 8) ? 1 : 0); for (yy = 0; yy <= yyMax; yy++) { yyMulWidth = yy * width; yyMul8PlusY = y + (yy << 3); for (xx = 0; xx < width; xx++) { KS0108_gotoXY(x + xx, yyMul8PlusY); KS0108_readData(); KS0108_gotoXY(x + xx, yyMul8PlusY); /* ... to do this twice */ tmp = KS0108_readData(); KS0108_gotoXY(x + xx, yyMul8PlusY); if (yy == 0) KS0108_writeData(doBits(tmp, pgm_read_byte(&bmp[xx]) << (y % 8))); else if (yy < yyMax) KS0108_writeData(doBits(tmp, (pgm_read_byte(&bmp[yyMulWidth - width + xx]) >> (8 - (y % 8))) | (pgm_read_byte(&bmp[yyMulWidth + xx]) << (y % 8)))); else /* yy == yyMax */ KS0108_writeData(doBits(tmp, pgm_read_byte(&bmp[yyMulWidth - width + xx]) >> (8 - (y % 8)))); } } } /* KS0108_charGotoXY: sets X, Y position for displaying of characters; * for 192x64 graphics display - x:<0, 31>, y:<0, 7> */ void KS0108_charGotoXY(uint8_t x, uint8_t y) { KS0108__gotoXY(x * 6, y << 3); } /* KS0108_writeChar: writes a single character */ void inline KS0108_writeChar(uint8_t ch, int8_t c) { uint16_t n = (ch - 32) * 5; if (c == SET_PIXEL) { KS0108_writeData(pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(pgm_read_byte(fonts5x8 + n)); KS0108_writeData(0x00); } else { KS0108_writeData(~pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(~pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(~pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(~pgm_read_byte(fonts5x8 + n++)); KS0108_writeData(~pgm_read_byte(fonts5x8 + n)); KS0108_writeData(0xff); } if (KS0108_x == 0) { KS0108_y += 8; KS0108_charGotoXY(0, KS0108_y >> 3); } } /* KS0108_writeCharUTF8: writes a single character in UTF-8 */ void inline KS0108_writeCharUTF8(uint32_t n, int8_t c) { uint16_t j; int16_t min = 0, max = FONTS5X8_UTF8_MAX - 1, mid; union { struct { uint8_t b0; uint8_t b1; uint16_t b23; } s; uint32_t w2; } ww; /* binary search */ do { mid = min + ((max - min) >> 1); j = mid << 3; ww.s.b23 = pgm_read_byte(fonts5x8_UTF8 + j); ww.s.b1 = pgm_read_byte(fonts5x8_UTF8 + j + 1); ww.s.b0 = pgm_read_byte(fonts5x8_UTF8 + j + 2); if (n > ww.w2) min = mid + 1; else max = mid - 1; } while ((ww.w2 != n) && (min <= max)); if (ww.w2 != n) /* no such character found */ j = 0; j += 3; if (c == SET_PIXEL) { KS0108_writeData(pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(pgm_read_byte(fonts5x8_UTF8 + j)); KS0108_writeData(0x00); } else { KS0108_writeData(~pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(~pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(~pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(~pgm_read_byte(fonts5x8_UTF8 + j++)); KS0108_writeData(~pgm_read_byte(fonts5x8_UTF8 + j)); KS0108_writeData(0xff); } if (KS0108_x == 0) { KS0108_y += 8; KS0108_charGotoXY(0, KS0108_y >> 3); } } /* KS0108_writeCharSprite: writes a single character as a sprite */ void inline KS0108_writeCharSprite(uint8_t ch, int8_t c) { uint16_t n = (ch - 32) * 5; KS0108_drawSprite(fonts5x8 + n, KS0108_x, KS0108_y, 5, 8, c); } /* KS0108_writeCharUTF8Sprite: writes a single character in UTF-8 as a sprite */ void inline KS0108_writeCharUTF8Sprite(uint32_t n, int8_t c) { uint16_t j; int16_t min = 0, max = FONTS5X8_UTF8_MAX - 1, mid; union { struct { uint8_t b0; uint8_t b1; uint16_t b23; } s; uint32_t w2; } ww; /* binary search */ do { mid = min + ((max - min) >> 1); j = mid << 3; ww.s.b23 = pgm_read_byte(fonts5x8_UTF8 + j); ww.s.b1 = pgm_read_byte(fonts5x8_UTF8 + j + 1); ww.s.b0 = pgm_read_byte(fonts5x8_UTF8 + j + 2); if (n > ww.w2) min = mid + 1; else max = mid - 1; } while ((ww.w2 != n) && (min <= max)); if (ww.w2 != n) /* no such character found */ j = 0; j += 3; KS0108_drawSprite(fonts5x8_UTF8 + j, KS0108_x, KS0108_y, 5, 8, c); } /* KS0108_writeString: writes a string */ void KS0108_writeString(const uint8_t *s, int8_t c) { for ( ; *s; s++) KS0108_writeChar(*s, c); } /* KS0108_writeStringUTF8: writes a string in UTF-8 encoding; * only two and three bytes UTF-8 supported */ void KS0108_writeStringUTF8(const uint8_t *s, int8_t c) { for ( ; *s; s++) { if ((*s) & 0x80) { /* UTF8 */ union { struct { uint8_t b0; uint8_t b1; uint16_t b23; } s; uint32_t w2; } ww; if (((*s) & 0xe0) == 0xc0) { /* two bytes UTF8 */ ww.s.b23 = 0x00; ww.s.b1 = *s++; ww.s.b0 = *s; KS0108_writeCharUTF8(ww.w2, c); } else { /* three bytes and more; max three bytes supported */ ww.s.b23 = *s++; ww.s.b1 = *s++; ww.s.b0 = *s; KS0108_writeCharUTF8(ww.w2, c); } } else KS0108_writeChar(*s, c); } } /* KS0108_writeStringSprite: writes a string as a sprite */ void KS0108_writeStringSprite(const uint8_t *s, int8_t c) { uint8_t x = KS0108_x, y = KS0108_y; for ( ; *s; s++) { KS0108_writeCharSprite(*s, c); x += 6; KS0108_x = x; KS0108_y = y; } } /* KS0108_writeStringUTF8Sprite: writes a string in UTF-8 encoding as a sprite; * only two and three bytes UTF-8 supported */ void KS0108_writeStringUTF8Sprite(const uint8_t *s, int8_t c) { uint8_t x = KS0108_x, y = KS0108_y; for ( ; *s; s++) { if ((*s) & 0x80) { /* UTF8 */ union { struct { uint8_t b0; uint8_t b1; uint16_t b23; } s; uint32_t w2; } ww; if (((*s) & 0xe0) == 0xc0) { /* two bytes UTF8 */ ww.s.b23 = 0x00; ww.s.b1 = *s++; ww.s.b0 = *s; KS0108_writeCharUTF8Sprite(ww.w2, c); } else { /* three bytes and more; max three bytes supported */ ww.s.b23 = *s++; ww.s.b1 = *s++; ww.s.b0 = *s; KS0108_writeCharUTF8Sprite(ww.w2, c); } } else KS0108_writeCharSprite(*s, c); x += 6; KS0108_x = x; KS0108_y = y; } }
Kod źródłowy pliku "fonts5x8.h":
/* fonts5x8: fonts and national UTF8 fonts * * Sebastian Pawlak, 2011, v1.0 */ #include <avr/pgmspace.h> #ifndef _FONTS_5X8_ #define _FONTS_5X8_ uint8_t fonts5x8[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, // SP 0x00, 0x00, 0x5F, 0x00, 0x00, // ! 0x00, 0x07, 0x00, 0x07, 0x00, // " 0x14, 0x7F, 0x14, 0x7F, 0x14, // # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $ 0x23, 0x13, 0x08, 0x64, 0x62, // % 0x36, 0x49, 0x55, 0x22, 0x50, // & 0x00, 0x00, 0x07, 0x00, 0x00, // ' 0x00, 0x1C, 0x22, 0x41, 0x00, // ( 0x00, 0x41, 0x22, 0x1C, 0x00, // ) 0x14, 0x08, 0x3e, 0x08, 0x14, // * 0x08, 0x08, 0x3E, 0x08, 0x08, // + 0x00, 0x50, 0x30, 0x00, 0x00, // , 0x08, 0x08, 0x08, 0x08, 0x08, // - 0x00, 0x30, 0x30, 0x00, 0x00, // . 0x20, 0x10, 0x08, 0x04, 0x02, // / 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 0x42, 0x61, 0x51, 0x49, 0x46, // 2 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 0x27, 0x45, 0x45, 0x45, 0x39, // 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 0x01, 0x71, 0x09, 0x05, 0x03, // 7 0x36, 0x49, 0x49, 0x49, 0x36, // 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 0x00, 0x36, 0x36, 0x00, 0x00, // : 0x00, 0x56, 0x36, 0x00, 0x00, // ; 0x00, 0x08, 0x14, 0x22, 0x41, // < 0x14, 0x14, 0x14, 0x14, 0x14, // = 0x41, 0x22, 0x14, 0x08, 0x00, // > 0x02, 0x01, 0x51, 0x09, 0x06, // ? 0x3e, 0x41, 0x5d, 0x55, 0x0e, // @ 0x7E, 0x11, 0x11, 0x11, 0x7E, // A 0x7F, 0x49, 0x49, 0x49, 0x36, // B 0x3E, 0x41, 0x41, 0x41, 0x22, // C 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 0x7F, 0x49, 0x49, 0x49, 0x41, // E 0x7F, 0x09, 0x09, 0x01, 0x01, // F 0x3E, 0x41, 0x49, 0x49, 0x3a, // G 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 0x00, 0x41, 0x7F, 0x41, 0x00, // I 0x20, 0x40, 0x41, 0x3F, 0x01, // J 0x7F, 0x08, 0x14, 0x22, 0x41, // K 0x7F, 0x40, 0x40, 0x40, 0x40, // L 0x7F, 0x02, 0x04, 0x02, 0x7F, // M 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 0x7F, 0x09, 0x09, 0x09, 0x06, // P 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 0x7F, 0x09, 0x19, 0x29, 0x46, // R 0x46, 0x49, 0x49, 0x49, 0x31, // S 0x01, 0x01, 0x7F, 0x01, 0x01, // T 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 0x7F, 0x20, 0x18, 0x20, 0x7F, // W 0x63, 0x14, 0x08, 0x14, 0x63, // X 0x03, 0x04, 0x78, 0x04, 0x03, // Y 0x61, 0x51, 0x49, 0x45, 0x43, // Z 0x00, 0x00, 0x7F, 0x41, 0x41, // [ 0x02, 0x04, 0x08, 0x10, 0x20, // '\' 0x41, 0x41, 0x7F, 0x00, 0x00, // ] 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 0x40, 0x40, 0x40, 0x40, 0x40, // _ 0x00, 0x01, 0x02, 0x04, 0x00, // ` 0x20, 0x54, 0x54, 0x54, 0x78, // a 0x7F, 0x48, 0x44, 0x44, 0x38, // b 0x38, 0x44, 0x44, 0x44, 0x28, // c 0x38, 0x44, 0x44, 0x48, 0x7F, // d 0x38, 0x54, 0x54, 0x54, 0x18, // e 0x08, 0x7E, 0x09, 0x01, 0x02, // f 0x08, 0x54, 0x54, 0x54, 0x3C, // g 0x7F, 0x08, 0x04, 0x04, 0x78, // h 0x00, 0x44, 0x7D, 0x40, 0x00, // i 0x20, 0x40, 0x44, 0x3D, 0x00, // j 0x00, 0x7F, 0x10, 0x28, 0x44, // k 0x00, 0x41, 0x7F, 0x40, 0x00, // l 0x7C, 0x04, 0x18, 0x04, 0x78, // m 0x7C, 0x08, 0x04, 0x04, 0x78, // n 0x38, 0x44, 0x44, 0x44, 0x38, // o 0x7C, 0x14, 0x14, 0x14, 0x08, // p 0x08, 0x14, 0x14, 0x18, 0x7C, // q 0x7C, 0x08, 0x04, 0x04, 0x08, // r 0x48, 0x54, 0x54, 0x54, 0x24, // s 0x04, 0x3F, 0x44, 0x40, 0x20, // t 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 0x44, 0x28, 0x10, 0x28, 0x44, // x 0x0C, 0x50, 0x50, 0x50, 0x3C, // y 0x44, 0x64, 0x54, 0x4C, 0x44, // z 0x00, 0x08, 0x36, 0x41, 0x00, // { 0x00, 0x00, 0x7F, 0x00, 0x00, // | 0x00, 0x41, 0x36, 0x08, 0x00, // } 0x08, 0x04, 0x08, 0x10, 0x08, // ~ 0x00, 0x00, 0x08, 0x00, 0x00, // DEL }; enum { FONTS5X8_UTF8_MAX = 30, }; uint8_t fonts5x8_UTF8[FONTS5X8_UTF8_MAX * 8] PROGMEM = { /* UTF8-code |------- character --------| */ 0x00,0x00,0x00, 0xff, 0x81, 0x81, 0x81, 0xff, // default character 0x00,0xc2,0xb0, 0x00, 0x06, 0x09, 0x09, 0x06, // degree sign 0x00,0xc2,0xb1, 0x24, 0x24, 0x3f, 0x24, 0x24, // plus-minus sign 0x00,0xc2,0xb2, 0x00, 0x19, 0x15, 0x12, 0x00, // superscript two 0x00,0xc2,0xb3, 0x00, 0x15, 0x15, 0x0a, 0x00, // superscript three 0x00,0xc2,0xb5, 0xfc, 0x20, 0x20, 0x20, 0x1c, // micro sign 0x00,0xc2,0xbc, 0x13, 0x08, 0x64, 0x52, 0xf1, // vulgar fraction one quarter 0x00,0xc2,0xbd, 0x13, 0x08, 0x04, 0xd2, 0xb1, // vulgar fration one half 0x00,0xc3,0x93, 0x3c, 0x42, 0x43, 0x42, 0x3c, // capital letter O with acute 0x00,0xc3,0xb3, 0x38, 0x44, 0x46, 0x45, 0x38, // small letter O with acute 0x00,0xc4,0x84, 0x7E, 0x11, 0x11, 0x91, 0x7E, // capital letter A with ogonek 0x00,0xc4,0x85, 0x20, 0x54, 0x54, 0xd4, 0x78, // small letter A with ogonek 0x00,0xc4,0x86, 0x3c, 0x42, 0x43, 0x42, 0x24, // capital letter C with acute 0x00,0xc4,0x87, 0x38, 0x44, 0x46, 0x45, 0x28, // small letter C with acute 0x00,0xc4,0x98, 0x7f, 0x49, 0x49, 0xc9, 0x41, // capital letter E with ogonek 0x00,0xc4,0x99, 0x38, 0x54, 0x54, 0xd4, 0x18, // small letter E with ogonek 0x00,0xc5,0x81, 0x7F, 0x48, 0x44, 0x40, 0x40, // capital letter L with stroke 0x00,0xc5,0x82, 0x00, 0x49, 0x7f, 0x44, 0x00, // small letter L with stroke 0x00,0xc5,0x83, 0x7e, 0x20, 0x12, 0x09, 0x7e, // capital letter N with acute 0x00,0xc5,0x84, 0x7c, 0x08, 0x06, 0x05, 0x78, // small letter N with acute 0x00,0xc5,0x9a, 0x44, 0x4a, 0x4b, 0x4a, 0x32, // capital letter S with acute 0x00,0xc5,0x9b, 0x48, 0x54, 0x56, 0x55, 0x24, // small letter S with acute 0x00,0xc5,0xb9, 0x44, 0x64, 0x56, 0x4d, 0x44, // capital letter Z with acute 0x00,0xc5,0xba, 0x44, 0x64, 0x56, 0x4d, 0x44, // small letter Z with acute 0x00,0xc5,0xbb, 0x42, 0x62, 0x53, 0x4a, 0x46, // capital Z with dot above 0x00,0xc5,0xbc, 0x44, 0x64, 0x55, 0x4C, 0x44, // small Z with dot above 0xe2,0x86,0x90, 0x08, 0x1c, 0x3e, 0x08, 0x08, // leftwards arrow 0xe2,0x86,0x91, 0x04, 0x06, 0x7f, 0x06, 0x04, // upwards arrow 0xe2,0x86,0x92, 0x08, 0x08, 0x3e, 0x1c, 0x08, // rightwards arrow 0xe2,0x86,0x93, 0x10, 0x30, 0x7f, 0x30, 0x10, // downwards arrow }; #endif
Kod źródłowy pliku "main.c":
/* How to use libKS0108 * * Sebastian Pawlak, 2011 */ #include <stdlib.h> #include <avr/io.h> #include <avr/pgmspace.h> #include "libKS0108.h" /* E=mc2 */ uint8_t bitmap1[] PROGMEM = { 0x00, 0x00, 0x18, 0x38, 0x38, 0x38, 0xf8, 0xf8, 0xf8, 0x30, 0x38, 0x38, 0x3c, 0x1c, 0x3c, 0x38, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, 0x3c, 0x06, 0x86, 0x86, 0xce, 0xf8, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x38, 0x38, 0x78, 0x7e, 0x3c, 0x00, 0x00, 0x07, 0x87, 0x86, 0x00, 0x98, 0xb8, 0x98, 0xbc, 0x9c, 0x9c, 0x9c, 0xbc, 0x98, 0x98, 0x00, 0x02, 0x06, 0x7e, 0xfe, 0xfe, 0x0e, 0x0f, 0x07, 0x2f, 0xfe, 0xfe, 0x1e, 0x07, 0x07, 0xff, 0xff, 0xd0, 0x00, 0x00, 0xe0, 0xf8, 0xfe, 0x0e, 0x07, 0x07, 0x03, 0x07, 0x3f, 0x7f, 0x7e, 0x7c, 0x00, 0x10, 0x1e, 0x1f, 0x1b, 0x39, 0x31, 0x10, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x60, 0x60, 0xe0, 0xf0, 0xfb, 0xff, 0xff, 0xf0, 0xe0, 0xe0, 0x70, 0xf0, 0xf0, 0x70, 0x7f, 0x7f, 0x7b, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x60, 0xf2, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, 0x3f, 0x39, 0x00, 0x00, 0x20, 0xfd, 0xff, 0xef, 0x60, 0x00, 0x03, 0x1f, 0x3d, 0x38, 0x70, 0xe0, 0xf0, 0x60, 0x20, 0x30, 0x1e, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; /* ! */ uint8_t bitmap2[] PROGMEM = { 0xe0, 0xf8, 0xfc, 0xfe, 0xfe, 0xff, 0x03, 0x03, 0xff, 0xfe, 0xfe, 0xfc, 0xf8, 0xe0, 0x01, 0x07, 0x0f, 0x1f, 0x1f, 0x3f, 0x33, 0x33, 0x3f, 0x1f, 0x1f, 0x0f, 0x07, 0x01, }; int main(void) { int16_t i; volatile int16_t k, l; int8_t c = SET_PIXEL; KS0108_init(); KS0108_displayOn(); srand(1); while (1) { if (c == SET_PIXEL) { KS0108_clearDisplay(); for (i = 0; i < 192; i += 2) KS0108_setPixelXY(i,0), KS0108_setPixelXY(i, 63); for (i = 0; i < 64; i += 2) KS0108_setPixelXY(0,i), KS0108_setPixelXY(191, i); } else { KS0108_setDisplay(); for (i = 0; i < 192; i += 2) KS0108_clearPixelXY(i,0), KS0108_clearPixelXY(i, 63); for (i = 0; i < 64; i += 2) KS0108_clearPixelXY(0,i), KS0108_clearPixelXY(191, i); } KS0108_drawRectangle(2, 2, 32, 30, c); if (c == SET_PIXEL) for (i = 0; i < 200; i++) KS0108_setPixelXY((rand() % 32) + 2, (rand() % 30) + 2); else for (i = 0; i < 200; i++) KS0108_clearPixelXY((rand() % 32) + 2, (rand() % 30) + 2); KS0108_drawFilledRectangle(2, 32, 32, 30, c); if (c == SET_PIXEL) for (i = 0; i < 200; i++) KS0108_clearPixelXY((rand() % 32) + 2, (rand() % 30) + 32); else for (i = 0; i < 200; i++) KS0108_setPixelXY((rand() % 32) + 2, (rand() % 30) + 32); for (i = -12; i <= 12; i += 4) KS0108_drawLine(35, 15 - i, 67, 15 + i, c); for (i = -12; i <= 12; i += 4) KS0108_drawLineFaster(51 + i, 29, 51 - i, 61, c); KS0108_drawCircle(84, 17, 13, c); KS0108_drawFilledCircle(84, 48, 13, c); KS0108_charGotoXY(18, 1); KS0108_writeString("ABcd", c); KS0108_charGotoXY(22, 1); KS0108_writeString("12$%", (c == SET_PIXEL) ? CLEAR_PIXEL : SET_PIXEL); KS0108_drawHorizontalLine(170, 10, 18, c); KS0108_drawVerticalLine(180, 4, 14, c); KS0108_drawVerticalLine(182, 8, 14, c); KS0108_drawVerticalLine(184, 8, 8, c); KS0108_drawVerticalLine(186, 8, 9, c); KS0108_drawVerticalLine(188, 8, 16, c); KS0108_charGotoXY(18, 2); KS0108_writeStringUTF8("G""\xc5\xbc""eg""\xc5\xbc" "\xc3\xb3""\xc5\x82""ka""\xe2\x86\x93", c); KS0108_charGotoXY(18, 3); KS0108_writeStringUTF8("Gżegżółka↓", c); KS0108__gotoXY(174, 13); KS0108_writeStringSprite("@", c); KS0108__gotoXY(174, 21); KS0108_writeStringUTF8Sprite("\xe2\x86\x92", c); KS0108_drawBitmap(bitmap1, 110, 32, 73, 24, c); KS0108_drawSprite(bitmap2, rand() % (192 - 14), rand() % (64 - 14), 14, 14, c); if (c == SET_PIXEL) c = CLEAR_PIXEL; else c = SET_PIXEL; for (k = 0; k < 1000; k++) for (l = 0; l < 2000; l++) ; } return 0; }