feat: demo of spi - st7567 12864 lcd

This commit is contained in:
IOsetting 2022-01-02 17:46:54 +08:00
parent 37dacac881
commit a46612e2c3
7 changed files with 961 additions and 0 deletions

540
demo/spi/st7567/st7567.c Normal file
View File

@ -0,0 +1,540 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "st7567.h"
#include <string.h>
/* Absolute value */
#define ABS(x) ((x) > 0 ? (x) : -(x))
/* ST7567 data buffer */
static __XDATA uint8_t ST7567_Buffer_all[(ST7567_WIDTH + ST7567_SEG_EXPAND) * ST7567_HEIGHT / 8];
/* Private ST7567 structure */
typedef struct {
uint16_t CurrentX;
uint16_t CurrentY;
uint8_t Inverted;
uint8_t Initialized;
} ST7567_t;
/* Private variable */
static __XDATA ST7567_t ST7567;
static void ST7567_TransmitByte(uint8_t dat)
{
ST7567_CS = 0;
SPI_TxRx(dat);
ST7567_CS = 1;
}
static void ST7567_Transmit(const uint8_t *pData, uint32_t Size)
{
ST7567_CS = 0;
while (Size--)
{
SPI_TxRx(*pData++);
}
ST7567_CS = 1;
}
void ST7567_WriteCommand(uint8_t command)
{
ST7567_DC = 0;
ST7567_TransmitByte(command);
ST7567_DC = 1;
}
void ST7567_WriteData(uint8_t dat)
{
ST7567_TransmitByte(dat);
}
void ST7567_Init(void)
{
ST7567_Reset();
ST7567_BackLight_On();
ST7567_WriteCommand(ST7567_RESET);
// adjust contrast
ST7567_WriteCommand(ST7567_SET_EV);
ST7567_WriteCommand(ST7567_SET_EV_MASK & 0x20);
// adjust regular voltage. LCD may fail to display if it is set too low.
ST7567_WriteCommand(ST7567_REGULATION_RATIO | ST7567_REGULATION_RATIO_5_0);
ST7567_WriteCommand(ST7567_BIAS_1_9);
ST7567_WriteCommand(ST7567_X_ORIENT);
ST7567_WriteCommand(ST7567_Y_ORIENT);
ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_OFF);
// Start from line 0
ST7567_WriteCommand(ST7567_SET_START_LINE | (0x00 & ST7567_SET_START_LINE_MASK));
// Start from page 0
ST7567_WriteCommand(ST7567_SET_PAGE_ADDRESS | (0x00 & ST7567_SET_PAGE_ADDRESS_MASK));
// Start from column 0
ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_MSB | (0x00 & ST7567_SET_COLUMN_ADDRESS_MSB_MASK));
ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_LSB | (0x00 & ST7567_SET_COLUMN_ADDRESS_LSB_MASK));
// power control, LCD may fail to display if it is not properly set.
// recommend to set them all
ST7567_WriteCommand(ST7567_POWER_CONTROL
|ST7567_POWER_CONTROL_VB
|ST7567_POWER_CONTROL_VR
|ST7567_POWER_CONTROL_VF);
ST7567_WriteCommand(ST7567_DISPLAY_ON);
ST7567_WriteCommand(ST7567_ALL_PIXEL_NORMAL);
}
void ST7567_Reset(void)
{
ST7567_RES = 0;
SYS_Delay(5);
ST7567_RES = 1;
}
void ST7567_BackLight_On(void)
{
ST7567_BL = 1;
}
void ST7567_BackLight_Off(void)
{
ST7567_BL = 0;
}
void ST7567_SetContrast(uint8_t val)
{
ST7567_WriteCommand(ST7567_SET_EV);
ST7567_WriteCommand(ST7567_SET_EV_MASK & val);
}
void ST7567_UpdateScreen(void)
{
ST7567_WriteCommand(ST7567_SET_PAGE_ADDRESS | (0x00 & ST7567_SET_PAGE_ADDRESS_MASK));
ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_MSB);
ST7567_WriteCommand(ST7567_SET_COLUMN_ADDRESS_LSB);
ST7567_Transmit(ST7567_Buffer_all, sizeof(ST7567_Buffer_all));
}
void ST7567_ToggleInvert(void)
{
/* Toggle invert */
ST7567.Inverted = !ST7567.Inverted;
if (ST7567.Inverted)
{
ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_ON);
}
else
{
ST7567_WriteCommand(ST7567_INVERSE_DISPLAY_OFF);
}
}
void ST7567_Fill(uint8_t color)
{
/* Set memory */
memset(ST7567_Buffer_all, (color == ST7567_COLOR_BACK) ? 0x00 : 0xFF, sizeof(ST7567_Buffer_all));
}
void ST7567_DrawPixel(uint16_t x, uint16_t y, uint8_t color)
{
if (x >= ST7567_WIDTH || y >= ST7567_HEIGHT)
{
/* Error */
return;
}
if (color == ST7567_COLOR_FRONT)
{
ST7567_Buffer_all[ST7567_X_OFFSET + x + (y / 8) * (ST7567_WIDTH + ST7567_SEG_EXPAND)] |= 1 << (y % 8);
}
else
{
ST7567_Buffer_all[ST7567_X_OFFSET + x + (y / 8) * (ST7567_WIDTH + ST7567_SEG_EXPAND)] &= ~(1 << (y % 8));
}
}
void ST7567_GotoXY(uint16_t x, uint16_t y)
{
/* Set write pointers */
ST7567.CurrentX = x;
ST7567.CurrentY = y;
}
char ST7567_Putc(char ch, FontDef_t* font, uint8_t color)
{
uint32_t i, b, j, k;
for (i = 0; i < font->height; i++)
{
for (j = 0; j < font->bytes; j++)
{
b = font->dat[((ch - 32) * font->height + i) * font->bytes + j];
if (font->order == 0)
{
for (k = 0; k < 8 && k < font->width - j * 8; k++)
{
if ((b << k) & 0x80)
{
ST7567_DrawPixel(ST7567.CurrentX + (j * 8) + k, (ST7567.CurrentY + i), (uint8_t) color);
}
else
{
ST7567_DrawPixel(ST7567.CurrentX + (j * 8) + k, (ST7567.CurrentY + i), (uint8_t) !color);
}
}
}
else
{
for (k = 0; k < 8 && k < font->width - j * 8; k++)
{
if (b & (0x0001 << k))
{
ST7567_DrawPixel(ST7567.CurrentX + (j * 8) + k, (ST7567.CurrentY + i), (uint8_t) color);
}
else
{
ST7567_DrawPixel(ST7567.CurrentX + (j * 8) + k, (ST7567.CurrentY + i), (uint8_t) !color);
}
}
}
}
}
/* Increase pointer */
ST7567.CurrentX += font->width + 1;
/* Return character written */
return ch;
}
char ST7567_Puts(char* str, FontDef_t* Font, uint8_t color)
{
/* Write characters */
while (*str)
{
/* Write character by character */
if (ST7567_Putc(*str, Font, color) != *str)
{
/* Return error */
return *str;
}
/* Increase string pointer */
str++;
}
/* Everything OK, zero should be returned */
return *str;
}
void ST7567_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c)
{
int16_t dx, dy, sx, sy, err, e2, i, tmp;
/* Check for overflow */
if (x0 >= ST7567_WIDTH)
{
x0 = ST7567_WIDTH - 1;
}
if (x1 >= ST7567_WIDTH)
{
x1 = ST7567_WIDTH - 1;
}
if (y0 >= ST7567_HEIGHT)
{
y0 = ST7567_HEIGHT - 1;
}
if (y1 >= ST7567_HEIGHT)
{
y1 = ST7567_HEIGHT - 1;
}
dx = (x0 < x1) ? (x1 - x0) : (x0 - x1);
dy = (y0 < y1) ? (y1 - y0) : (y0 - y1);
sx = (x0 < x1) ? 1 : -1;
sy = (y0 < y1) ? 1 : -1;
err = ((dx > dy) ? dx : -dy) / 2;
if (dx == 0)
{
if (y1 < y0)
{
tmp = y1;
y1 = y0;
y0 = tmp;
}
if (x1 < x0)
{
tmp = x1;
x1 = x0;
x0 = tmp;
}
/* Vertical line */
for (i = y0; i <= y1; i++)
{
ST7567_DrawPixel(x0, i, c);
}
/* Return from function */
return;
}
if (dy == 0)
{
if (y1 < y0)
{
tmp = y1;
y1 = y0;
y0 = tmp;
}
if (x1 < x0)
{
tmp = x1;
x1 = x0;
x0 = tmp;
}
/* Horizontal line */
for (i = x0; i <= x1; i++)
{
ST7567_DrawPixel(i, y0, c);
}
/* Return from function */
return;
}
while (1)
{
ST7567_DrawPixel(x0, y0, c);
if (x0 == x1 && y0 == y1)
{
break;
}
e2 = err;
if (e2 > -dx)
{
err -= dy;
x0 += sx;
}
if (e2 < dy)
{
err += dx;
y0 += sy;
}
}
}
static __CODE uint8_t Font3x5 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, // SP
0x02, 0x02, 0x02, 0x00, 0x02, // !
0x05, 0x05, 0x00, 0x00, 0x00, // "
0x05, 0x07, 0x05, 0x07, 0x05, // #
0x06, 0x03, 0x06, 0x03, 0x02, // $
0x01, 0x04, 0x02, 0x01, 0x04, // %
0x03, 0x03, 0x07, 0x05, 0x06, // &
0x02, 0x02, 0x00, 0x00, 0x00, // '
0x04, 0x02, 0x02, 0x02, 0x04, // (
0x01, 0x02, 0x02, 0x02, 0x01, // )
0x05, 0x02, 0x05, 0x00, 0x00, // *
0x00, 0x02, 0x07, 0x02, 0x00, // +
0x00, 0x00, 0x00, 0x02, 0x01, // ,
0x00, 0x00, 0x07, 0x00, 0x00, // -
0x00, 0x00, 0x00, 0x00, 0x02, // .
0x00, 0x04, 0x02, 0x01, 0x00, // /
0x07, 0x05, 0x05, 0x05, 0x07, // 0
0x02, 0x03, 0x02, 0x02, 0x07, // 1
0x07, 0x04, 0x07, 0x01, 0x07, // 2
0x07, 0x04, 0x06, 0x04, 0x07, // 3
0x05, 0x05, 0x07, 0x04, 0x04, // 4
0x07, 0x01, 0x07, 0x04, 0x07, // 5
0x07, 0x01, 0x07, 0x05, 0x07, // 6
0x07, 0x04, 0x04, 0x04, 0x04, // 7
0x07, 0x05, 0x07, 0x05, 0x07, // 8
0x07, 0x05, 0x07, 0x04, 0x07, // 9
0x00, 0x02, 0x00, 0x02, 0x00, // :
0x00, 0x02, 0x00, 0x02, 0x01, // ;
0x04, 0x02, 0x01, 0x02, 0x04, // <
0x00, 0x07, 0x00, 0x07, 0x00, // =
0x01, 0x02, 0x04, 0x02, 0x01, // >
0x07, 0x04, 0x02, 0x00, 0x02, // ?
0x02, 0x05, 0x07, 0x01, 0x06, // @
0x02, 0x05, 0x07, 0x05, 0x05, // A
0x03, 0x05, 0x03, 0x05, 0x03, // B
0x06, 0x01, 0x01, 0x01, 0x06, // C
0x03, 0x05, 0x05, 0x05, 0x03, // D
0x07, 0x01, 0x07, 0x01, 0x07, // E
0x07, 0x01, 0x07, 0x01, 0x01, // F
0x06, 0x01, 0x07, 0x05, 0x06, // G
0x05, 0x05, 0x07, 0x05, 0x05, // H
0x07, 0x02, 0x02, 0x02, 0x07, // I
0x04, 0x04, 0x04, 0x05, 0x02, // J
0x05, 0x05, 0x03, 0x05, 0x05, // K
0x01, 0x01, 0x01, 0x01, 0x07, // L
0x05, 0x07, 0x07, 0x05, 0x05, // M
0x05, 0x07, 0x07, 0x07, 0x05, // N
0x02, 0x05, 0x05, 0x05, 0x02, // O
0x03, 0x05, 0x03, 0x01, 0x01, // P
0x02, 0x05, 0x05, 0x05, 0x06, // Q
0x03, 0x05, 0x07, 0x03, 0x05, // R
0x06, 0x01, 0x02, 0x04, 0x03, // S
0x07, 0x02, 0x02, 0x02, 0x02, // T
0x05, 0x05, 0x05, 0x05, 0x02, // U
0x05, 0x05, 0x05, 0x02, 0x02, // V
0x05, 0x05, 0x07, 0x07, 0x05, // W
0x05, 0x05, 0x02, 0x05, 0x05, // X
0x05, 0x05, 0x02, 0x02, 0x02, // Y
0x07, 0x04, 0x02, 0x01, 0x07, // Z
0x03, 0x01, 0x01, 0x01, 0x03, // [
0x00, 0x01, 0x02, 0x04, 0x00, /* \ */
0x06, 0x04, 0x04, 0x04, 0x06, // ]
0x02, 0x05, 0x00, 0x00, 0x00, // ^
0x00, 0x00, 0x00, 0x00, 0x07, // _
0x01, 0x02, 0x00, 0x00, 0x00, // `
0x00, 0x03, 0x06, 0x05, 0x07, // a
0x01, 0x03, 0x05, 0x05, 0x03, // b
0x00, 0x06, 0x01, 0x01, 0x06, // c
0x04, 0x06, 0x05, 0x05, 0x06, // d
0x00, 0x06, 0x05, 0x03, 0x06, // e
0x04, 0x02, 0x07, 0x02, 0x02, // f
0x06, 0x05, 0x07, 0x04, 0x02, // g
0x01, 0x03, 0x05, 0x05, 0x05, // h
0x02, 0x00, 0x02, 0x02, 0x02, // i
0x04, 0x00, 0x04, 0x04, 0x03, // j
0x01, 0x05, 0x03, 0x03, 0x05, // k
0x03, 0x02, 0x02, 0x02, 0x07, // l
0x00, 0x07, 0x07, 0x07, 0x05, // m
0x00, 0x03, 0x05, 0x05, 0x05, // n
0x00, 0x02, 0x05, 0x05, 0x02, // o
0x00, 0x03, 0x05, 0x03, 0x01, // p
0x00, 0x06, 0x05, 0x06, 0x04, // q
0x00, 0x06, 0x01, 0x01, 0x01, // r
0x00, 0x06, 0x03, 0x06, 0x03, // s
0x02, 0x07, 0x02, 0x02, 0x06, // t
0x00, 0x05, 0x05, 0x05, 0x06, // u
0x00, 0x05, 0x05, 0x05, 0x02, // v
0x00, 0x05, 0x07, 0x07, 0x07, // w
0x00, 0x05, 0x02, 0x02, 0x05, // x
0x00, 0x05, 0x06, 0x04, 0x06, // y
0x00, 0x07, 0x06, 0x03, 0x07, // z
0x06, 0x02, 0x01, 0x02, 0x06, // {
0x02, 0x02, 0x02, 0x02, 0x02, // |
0x03, 0x02, 0x04, 0x02, 0x03, // }
0x00, 0x06, 0x03, 0x00, 0x00, // ~
0x07, 0x07, 0x07, 0x07, 0x07, // DEL
};
static __CODE uint8_t Font5x7 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, // !
0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, // "
0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a, // #
0x04, 0x1e, 0x05, 0x0e, 0x14, 0x0f, 0x04, // $
0x00, 0x19, 0x1a, 0x04, 0x0b, 0x13, 0x00, // %
0x06, 0x09, 0x05, 0x02, 0x15, 0x09, 0x16, // &
0x06, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, // '
0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08, // (
0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02, // )
0x00, 0x04, 0x15, 0x0e, 0x15, 0x04, 0x00, // *
0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, // +
0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x04, // ,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, // -
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, // .
0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // /
0x0e, 0x11, 0x19, 0x15, 0x13, 0x11, 0x0e, // 0
0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x0e, // 1
0x0e, 0x11, 0x10, 0x08, 0x04, 0x02, 0x1f, // 2
0x1f, 0x08, 0x04, 0x08, 0x10, 0x11, 0x0e, // 3
0x08, 0x0c, 0x0a, 0x09, 0x1f, 0x08, 0x08, // 4
0x1f, 0x01, 0x0f, 0x10, 0x10, 0x11, 0x0e, // 5
0x0c, 0x02, 0x01, 0x0f, 0x11, 0x11, 0x0e, // 6
0x1f, 0x10, 0x08, 0x04, 0x02, 0x02, 0x02, // 7
0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, // 8
0x0e, 0x11, 0x11, 0x1e, 0x10, 0x08, 0x06, // 9
0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, // :
0x00, 0x06, 0x06, 0x00, 0x06, 0x04, 0x02, // ;
0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, // <
0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, // =
0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, // >
0x0e, 0x11, 0x10, 0x08, 0x04, 0x00, 0x04, // ?
0x0e, 0x11, 0x10, 0x16, 0x1d, 0x11, 0x0e, // @
0x0e, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, // A
0x0f, 0x11, 0x11, 0x0f, 0x11, 0x11, 0x0f, // B
0x0e, 0x11, 0x01, 0x01, 0x01, 0x11, 0x0e, // C
0x07, 0x09, 0x11, 0x11, 0x11, 0x09, 0x07, // D
0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x1f, // E
0x1f, 0x01, 0x01, 0x0f, 0x01, 0x01, 0x01, // F
0x0e, 0x11, 0x01, 0x1d, 0x11, 0x11, 0x1e, // G
0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, // H
0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // I
0x1c, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, // J
0x11, 0x09, 0x05, 0x03, 0x05, 0x09, 0x11, // K
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, // L
0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11, // M
0x11, 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, // N
0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // O
0x0f, 0x11, 0x11, 0x0f, 0x01, 0x01, 0x01, // P
0x0e, 0x11, 0x11, 0x11, 0x15, 0x09, 0x16, // Q
0x0f, 0x11, 0x11, 0x0f, 0x05, 0x09, 0x11, // R
0x1e, 0x01, 0x01, 0x0e, 0x10, 0x10, 0x0f, // S
0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // T
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, // U
0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04, // V
0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a, // W
0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, // X
0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, // Y
0x1f, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, // Z
0x0e, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0e, // [
0x15, 0x0a, 0x15, 0x0a, 0x15, 0x0a, 0x15, /* \ */
0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, // ]
0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, // ^
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, // _
0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, // `
0x00, 0x00, 0x0e, 0x10, 0x1e, 0x11, 0x1e, // a
0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x0f, // b
0x00, 0x00, 0x0e, 0x01, 0x01, 0x11, 0x0e, // c
0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x1e, // d
0x00, 0x00, 0x0e, 0x11, 0x1f, 0x01, 0x0e, // e
0x0c, 0x12, 0x02, 0x07, 0x02, 0x02, 0x02, // f
0x00, 0x1e, 0x11, 0x11, 0x1e, 0x10, 0x0e, // g
0x01, 0x01, 0x0d, 0x13, 0x11, 0x11, 0x11, // h
0x04, 0x00, 0x06, 0x04, 0x04, 0x04, 0x0e, // i
0x08, 0x00, 0x0c, 0x08, 0x08, 0x09, 0x06, // j
0x01, 0x01, 0x09, 0x05, 0x03, 0x05, 0x09, // k
0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0e, // l
0x00, 0x00, 0x0b, 0x15, 0x15, 0x11, 0x11, // m
0x00, 0x00, 0x0d, 0x13, 0x11, 0x11, 0x11, // n
0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, // o
0x00, 0x00, 0x0f, 0x11, 0x0f, 0x01, 0x01, // p
0x00, 0x00, 0x16, 0x19, 0x1e, 0x10, 0x10, // q
0x00, 0x00, 0x0d, 0x13, 0x01, 0x01, 0x01, // r
0x00, 0x00, 0x0e, 0x01, 0x0e, 0x10, 0x0f, // s
0x02, 0x02, 0x07, 0x02, 0x02, 0x12, 0x0c, // t
0x00, 0x00, 0x11, 0x11, 0x11, 0x19, 0x16, // u
0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, // v
0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, // w
0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, // x
0x00, 0x00, 0x11, 0x11, 0x1e, 0x10, 0x0e, // y
0x00, 0x00, 0x1f, 0x08, 0x04, 0x02, 0x1f, // z
0x08, 0x04, 0x04, 0x02, 0x04, 0x04, 0x08, // {
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // |
0x02, 0x04, 0x04, 0x08, 0x04, 0x04, 0x02, // }
0x00, 0x00, 0x02, 0x15, 0x08, 0x00, 0x00, // ~
0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, //
};
__CODE FontDef_t Font_3x5 = {3, 5, 1, 1, Font3x5};
__CODE FontDef_t Font_5x7 = {5, 7, 1, 1, Font5x7};

274
demo/spi/st7567/st7567.h Normal file
View File

@ -0,0 +1,274 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __ST7567_H_
#define __ST7567_H_
#include "fw_hal.h"
#define ST7567_CS P35
#define ST7567_MOSI P34
#define ST7567_SCK P32
#define ST7567_RES P37
#define ST7567_DC P36
#define ST7567_BL P12
// X width
#define ST7567_WIDTH 128
// Y height
#define ST7567_HEIGHT 64
// Additional bytes in each row
#define ST7567_SEG_EXPAND 4
// X orientation
#define ST7567_X_ORIENT ST7567_SEG_DIRECTION_NORMAL
// Y orientation
#define ST7567_Y_ORIENT ST7567_COM_DIRECTION_REVERSE
/* ST7567 commands definitions */
#define ST7567_DISPLAY_OFF 0xAE /* 0xae: Display OFF (sleep mode) */
#define ST7567_DISPLAY_ON 0xAF /* 0xaf: Display ON in normal mode */
#define ST7567_SET_START_LINE 0x40 /* 0x40-7f: Set display start line */
#define ST7567_SET_START_LINE_MASK 0x3f
#define ST7567_SET_PAGE_ADDRESS 0xB0 /* 0xb0-b7: Set page start address, 0 - 7 */
#define ST7567_SET_PAGE_ADDRESS_MASK 0x07
#define ST7567_SET_COLUMN_ADDRESS_MSB 0x10 /* 0x10-0x1f: Set 8bit column address - high 4 bits */
#define ST7567_SET_COLUMN_ADDRESS_MSB_MASK 0x0f
#define ST7567_SET_COLUMN_ADDRESS_LSB 0x00 /* 0x00-0x0f: Set 8bit column address - low 4 bits */
#define ST7567_SET_COLUMN_ADDRESS_LSB_MASK 0x0F
/**
* SEG: 0 - 131
*/
#define ST7567_SEG_DIRECTION_NORMAL 0xA0 /* 0xa0: Column address 0 is mapped to SEG0 */
#define ST7567_SEG_DIRECTION_REVERSE 0xA1 /* 0xa1: Column address 128 is mapped to SEG0 */
/**
* COM: 0 - 63
*/
#define ST7567_COM_DIRECTION_NORMAL 0xC0 /* 0xc0: Set COM output direction, normal mode */
#define ST7567_COM_DIRECTION_REVERSE 0xC8 /* 0xc8: Set COM output direction, reverse mode */
#define ST7567_INVERSE_DISPLAY_OFF 0xA6 /* 0xa6: Normal display */
#define ST7567_INVERSE_DISPLAY_ON 0xA7 /* 0xa7: Inverse display */
#define ST7567_ALL_PIXEL_ON 0xA5 /* 0xa5: Entire display ON */
#define ST7567_ALL_PIXEL_NORMAL 0xA4 /* 0xa4: Resume to RAM content display */
#define ST7567_BIAS_1_9 0xA2 /* 0xa2: Select BIAS setting 1/9 */
#define ST7567_BIAS_1_7 0xA3 /* 0xa3: Select BIAS setting 1/7 */
#define ST7567_READ_MODIFY_WRITE_START 0xE0 /* 0xe0: Enter the Read Modify Write mode */
#define ST7567_READ_MODIFY_WRITE_END 0xEE /* 0xee: Leave the Read Modify Write mode */
#define ST7567_RESET 0xE2 /* 0xe2: Software RESET */
/**
* This instruction controls the built-in power circuits.
* Typically, these 3 flags are turned ON at the same time.
*/
#define ST7567_POWER_CONTROL 0x28
#define ST7567_POWER_CONTROL_VF 0x01
#define ST7567_POWER_CONTROL_VR 0x02
#define ST7567_POWER_CONTROL_VB 0x04
/**
* The operation voltage (V0) calculation formula is shown below:
* (RR comes from Regulation Ratio, EV comes from EV[5:0])
* V0 = RR X [ 1 (63 EV) / 162 ] X 2.1, or
* V0 = RR X [ ( 99 + EV ) / 162 ] X 2.1
*/
#define ST7567_REGULATION_RATIO 0x20
#define ST7567_REGULATION_RATIO_3_0 0x00
#define ST7567_REGULATION_RATIO_3_5 0x01
#define ST7567_REGULATION_RATIO_4_0 0x02
#define ST7567_REGULATION_RATIO_4_5 0x03
#define ST7567_REGULATION_RATIO_5_0 0x04 /* Default */
#define ST7567_REGULATION_RATIO_5_5 0x05
#define ST7567_REGULATION_RATIO_6_0 0x06
#define ST7567_REGULATION_RATIO_6_5 0x07
/**
* This is double byte instruction. The first byte set ST7567 into EV
* adjust mode and the following instruction will change the EV setting.
* That means these 2 bytes must be used together. They control the electronic
* volume to adjust a suitable V0 voltage for the LCD.
*/
#define ST7567_SET_EV 0x81
#define ST7567_SET_EV_MASK 0x3F
#define ST7567_SET_BOOSTER 0xF8 /* Set booster level */
#define ST7567_SET_BOOSTER_4X 0x00
#define ST7567_SET_BOOSTER_5X 0x01
#define ST7567_NOP 0xE3
#define ST7567_TEST 0xFE
#ifndef ST7567_TIMEOUT
#define ST7567_TIMEOUT 20000
#endif
#if ST7567_X_ORIENT == ST7567_SEG_DIRECTION_REVERSE
#define ST7567_X_OFFSET ST7567_SEG_EXPAND
#else
#define ST7567_X_OFFSET 0
#endif
/** Background color */
#define ST7567_COLOR_BACK 0x00
/** Front color */
#define ST7567_COLOR_FRONT 0x01
typedef struct {
uint8_t width;
uint8_t height;
uint8_t order;
uint8_t bytes;
const uint8_t *dat;
} FontDef_t;
extern __CODE FontDef_t Font_3x5;
extern __CODE FontDef_t Font_5x7;
/**
* @brief Initializes ST7567 LCD
* @param None
* @retval None
*/
void ST7567_Init(void);
/**
* @brief Hardware reset ST7567 LCD
* @param None
* @retval None
*/
void ST7567_Reset(void);
/**
* @brief Turn ST7567 LCD backlight on
* @param None
* @retval None
*/
void ST7567_BackLight_On(void);
/**
* @brief Turn ST7567 LCD backlight off
* @param None
* @retval None
*/
void ST7567_BackLight_Off(void);
/**
* @brief Turn ST7567 LCD backlight off
* @param val: value between 0x00 ~ 0x3F
* @retval None
*/
void ST7567_SetContrast(uint8_t val);
/**
* @brief Updates buffer from internal RAM to LCD
* @note This function must be called each time you do some changes to LCD, to update buffer from RAM to LCD
* @param None
* @retval None
*/
void ST7567_UpdateScreen(void);
/**
* @brief Toggles pixels invertion inside internal RAM
* @note @ref ST7567_UpdateScreen() must be called after that in order to see updated LCD screen
* @param None
* @retval None
*/
void ST7567_ToggleInvert(void);
/**
* @brief Fills entire LCD with desired color
* @note @ref ST7567_UpdateScreen() must be called after that in order to see updated LCD screen
* @param Color: Color to be used for screen fill. This parameter can be a value of @ref ST7567_COLOR_t enumeration
* @retval None
*/
void ST7567_Fill(uint8_t Color);
/**
* @brief Draws pixel at desired location
* @note @ref ST7567_UpdateScreen() must called after that in order to see updated LCD screen
* @param x: X location. This parameter can be a value between 0 and ST7567_WIDTH - 1
* @param y: Y location. This parameter can be a value between 0 and ST7567_HEIGHT - 1
* @param color: Color to be used for screen fill. This parameter can be a value of @ref ST7567_COLOR_t enumeration
* @retval None
*/
void ST7567_DrawPixel(uint16_t x, uint16_t y, uint8_t color);
/**
* @brief Sets cursor pointer to desired location for strings
* @param x: X location. This parameter can be a value between 0 and ST7567_WIDTH - 1
* @param y: Y location. This parameter can be a value between 0 and ST7567_HEIGHT - 1
* @retval None
*/
void ST7567_GotoXY(uint16_t x, uint16_t y);
/**
* @brief Puts character to internal RAM
* @note @ref ST7567_UpdateScreen() must be called after that in order to see updated LCD screen
* @param ch: Character to be written
* @param *Font: Pointer to @ref FontDef_t structure with used font
* @param color: Color used for drawing. This parameter can be a value of @ref ST7567_COLOR_t enumeration
* @retval Character written
*/
char ST7567_Putc(char ch, FontDef_t* Font, uint8_t color);
/**
* @brief Puts string to internal RAM
* @note @ref ST7567_UpdateScreen() must be called after that in order to see updated LCD screen
* @param *str: String to be written
* @param *Font: Pointer to @ref FontDef_t structure with used font
* @param color: Color used for drawing. This parameter can be a value of @ref ST7567_COLOR_t enumeration
* @retval Zero on success or character value when function failed
*/
char ST7567_Puts(char* str, FontDef_t* Font, uint8_t color);
/**
* @brief Draws line on LCD
* @note @ref ST7567_UpdateScreen() must be called after that in order to see updated LCD screen
* @param x0: Line X start point. Valid input is 0 to ST7567_WIDTH - 1
* @param y0: Line Y start point. Valid input is 0 to ST7567_HEIGHT - 1
* @param x1: Line X end point. Valid input is 0 to ST7567_WIDTH - 1
* @param y1: Line Y end point. Valid input is 0 to ST7567_HEIGHT - 1
* @param c: Color to be used. This parameter can be a value of @ref ST7567_COLOR_t enumeration
* @retval None
*/
void ST7567_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t c);
/**
* @brief Writes single byte command to slave
* @param command: command to be written
* @retval None
*/
void ST7567_WriteCommand(uint8_t command);
/**
* @brief Writes single byte data to slave
* @param data: data to be written
* @retval None
*/
void ST7567_WriteData(uint8_t data);
#endif // __ST7567_H_

View File

@ -0,0 +1,147 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/***
* Demo: ST7567 12864 LCD
* Board: STC8H3K32
*
* P37 -> RES, RESET 7 - 18
* P36 -> DC, A0 8 - 17
* P35 -> CSB, Chip Select 6 - 16
* P32 -> SCK, SCL, CLK, Clock 9 - 13
* P12 -> LED-A, Backlight 3 - 19
* P34 -> MOSI, SDA 10 - 15
* GND -> GND
* 3.3V -> VCC
*/
#include "fw_hal.h"
#include "st7567.h"
void SPI_Init(void)
{
// ST7567 doesn't work if SPI frequency is too high
SPI_SetClockPrescaler(SPI_ClockPreScaler_16);
// Clock idles low
SPI_SetClockPolarity(HAL_State_OFF);
// Data transfer is driven by lower SS pin
SPI_SetClockPhase(SPI_ClockPhase_LeadingEdge);
// MSB first
SPI_SetDataOrder(SPI_DataOrder_MSB);
// Define the output pins
SPI_SetPort(SPI_AlterPort_P35_P34_P33_P32);
// Ignore SS pin, use MSTR to swith between master/slave mode
SPI_IgnoreSlaveSelect(HAL_State_ON);
// Master mode
SPI_SetMasterMode(HAL_State_ON);
// Start SPI
SPI_SetEnableState(HAL_State_ON);
}
void GPIO_Init(void)
{
// Configure GPIO pins before SPI and device
// DIN(P34)
GPIO_P3_SetMode(GPIO_Pin_4, GPIO_Mode_InOut_QBD);
// SCLK(P32)
GPIO_P3_SetMode(GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7, GPIO_Mode_Output_PP);
GPIO_P1_SetMode(GPIO_Pin_2, GPIO_Mode_Output_PP);
}
int main(void)
{
int y1, y2;
uint8_t d1, d2;
SYS_SetClock();
GPIO_Init();
SPI_Init();
ST7567_Init();
while(1)
{
ST7567_DrawLine(0, 0, 127, 0, 1);
ST7567_DrawLine(0, 0, 0, 63, 1);
ST7567_DrawLine(127, 0, 127, 63, 1);
ST7567_DrawLine(0, 63, 127, 63, 1);
ST7567_GotoXY(3, 5);
ST7567_Puts("LCD:ST7567", &Font_5x7, 1);
ST7567_GotoXY(3, 13);
ST7567_Puts("STC8 FwLib Demo", &Font_5x7, 1);
ST7567_GotoXY(3, 21);
ST7567_Puts("It's a demo of ST7567 12864 LCD", &Font_3x5, 1);
ST7567_GotoXY(3, 27);
ST7567_Puts("Font size 3x5, nums:01234567890", &Font_3x5, 1);
ST7567_GotoXY(5, 52);
ST7567_Puts("Font size: 5x7", &Font_5x7, 1);
ST7567_UpdateScreen();
SYS_Delay(2000);
y1 = 10;
while (y1 <= 0x30)
{
ST7567_SetContrast(y1++);
SYS_Delay(100);
}
while (y1 >= 10)
{
ST7567_SetContrast(y1--);
SYS_Delay(100);
}
while (y1 <= 0x20)
{
ST7567_SetContrast(y1++);
SYS_Delay(100);
}
SYS_Delay(2000);
ST7567_ToggleInvert();
ST7567_UpdateScreen();
SYS_Delay(2000);
ST7567_ToggleInvert();
ST7567_UpdateScreen();
SYS_Delay(2000);
ST7567_Fill(0);
y1 = 64, y2 = 0;
while (y1 > 0)
{
ST7567_DrawLine(0, y1, 127, y2, 1);
ST7567_UpdateScreen();
y1 -= 2;
y2 += 2;
SYS_Delay(100);
}
SYS_Delay(1000);
ST7567_Fill(0);
y1 = 127, y2 = 0;
while (y1 > 0)
{
ST7567_DrawLine(y1, 0, y2, 63, 1);
ST7567_UpdateScreen();
y1 -= 2;
y2 += 2;
SYS_Delay(100);
}
SYS_Delay(1000);
ST7567_Fill(0);
ST7567_UpdateScreen();
SYS_Delay(2000);
}
}