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;
}





