390 lines
11 KiB
C++
390 lines
11 KiB
C++
#include "tft.h"
|
|
|
|
#ifdef HZK_FONT
|
|
|
|
#include "font_chuc.h"
|
|
|
|
#endif
|
|
|
|
#ifdef TFT_ST7735
|
|
|
|
#include "ST7735.h"
|
|
#include "ascii_font.h"
|
|
|
|
uint8_t *cmdIndex = (uint8_t *) st7735initcmd;
|
|
#endif
|
|
|
|
|
|
void TFT_Init(TFT_T *dev) {
|
|
uint8_t count, temp;
|
|
|
|
while (*cmdIndex) {
|
|
temp = *cmdIndex++;
|
|
count = temp & 0x7F;
|
|
dev->cmd(cmdIndex, 1);
|
|
if (count > 1) {
|
|
dev->data(cmdIndex + 1, count - 1);
|
|
}
|
|
cmdIndex += count;
|
|
|
|
if (0x81 == temp) {
|
|
dev->delay(TFT_DELAY);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t TFT_ReadID(TFT_T *dev) {
|
|
uint32_t id = 0;
|
|
#ifdef TFT_ST7735
|
|
ST7735_ReadID(dev, id);
|
|
#endif
|
|
return id;
|
|
}
|
|
|
|
void TFT_SetDir(TFT_T *dev, TFT_DIR_T dir) {
|
|
uint8_t tmp = TFT_DIR_CMD;
|
|
dev->cmd(&tmp, 1);
|
|
tmp = DIR_MASK(dir);
|
|
dev->data(&tmp, 1);
|
|
}
|
|
|
|
void TFT_SetCur(TFT_T *dev, uint16_t x, uint16_t y) {
|
|
if (dev->dir <= LONGITUDINAL_180) {//竖屏
|
|
x += TFT_X_OFFSET;
|
|
y += TFT_Y_OFFSET;
|
|
} else {
|
|
x += TFT_Y_OFFSET;
|
|
y += TFT_X_OFFSET;
|
|
}
|
|
uint8_t tmp[2];
|
|
tmp[0] = TFT_XPOS_CMD;
|
|
dev->cmd(&tmp[0], 1);
|
|
tmp[0] = x >> 8U;
|
|
tmp[1] = x & 0xFFU;
|
|
dev->data(tmp, 2);
|
|
|
|
tmp[0] = TFT_YPOS_CMD;
|
|
dev->cmd(&tmp[0], 1);
|
|
tmp[0] = y >> 8U;
|
|
tmp[1] = y & 0xFFU;
|
|
dev->data(tmp, 2);
|
|
|
|
tmp[0] = TFT_WRITE_RAM;
|
|
dev->cmd(tmp, 1);
|
|
}
|
|
|
|
void TFT_SetWindow(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
|
|
if (dev->dir <= LONGITUDINAL_180) {//竖屏
|
|
x += TFT_X_OFFSET;
|
|
y += TFT_Y_OFFSET;
|
|
} else {
|
|
x += TFT_Y_OFFSET;
|
|
y += TFT_X_OFFSET;
|
|
}
|
|
uint8_t tmp[4];
|
|
tmp[0] = TFT_XPOS_CMD;
|
|
dev->cmd(&tmp[0], 1);
|
|
tmp[0] = x >> 8U;
|
|
tmp[1] = x & 0xFFU;
|
|
tmp[2] = (x + width - 1) >> 8U;
|
|
tmp[3] = (x + width - 1) & 0xFFU;
|
|
dev->data(tmp, 4);
|
|
|
|
tmp[0] = TFT_YPOS_CMD;
|
|
dev->cmd(&tmp[0], 1);
|
|
tmp[0] = y >> 8U;
|
|
tmp[1] = y & 0xFFU;
|
|
tmp[0] = (y + height - 1) >> 8U;
|
|
tmp[1] = (y + height - 1) & 0xFFU;
|
|
dev->data(tmp, 4);
|
|
|
|
tmp[0] = TFT_WRITE_RAM;
|
|
dev->cmd(tmp, 1);
|
|
}
|
|
|
|
TFT_Color_t TFT_GetPixel(TFT_T *dev, uint16_t x, uint16_t y) {
|
|
uint8_t pixel_lsb, pixel_msb;
|
|
uint8_t tmp;
|
|
TFT_Color_t rec;
|
|
/* Set Cursor */
|
|
TFT_SetCur(dev, x, y);
|
|
/* Prepare to read LCD RAM */
|
|
tmp = TFT_READ_RAM;
|
|
dev->cmd(&tmp, 1);
|
|
/* Dummy read */
|
|
dev->read(&tmp, 1);
|
|
/* Read first part of the RGB888 data */
|
|
dev->read(&pixel_lsb, 1);
|
|
/* Read first part of the RGB888 data */
|
|
dev->read(&pixel_msb, 1);
|
|
rec.color = ((uint32_t) (pixel_lsb)) + ((uint32_t) (pixel_msb) << 8);
|
|
return rec;
|
|
}
|
|
|
|
void TFT_SetPixel(TFT_T *dev, uint16_t x, uint16_t y, TFT_Color_t color) {
|
|
if ((x >= dev->width) || (y >= dev->height)) { return; }
|
|
TFT_SetCur(dev, x, y);
|
|
dev->data(color.u8, 2);
|
|
}
|
|
|
|
void TFT_SetBacklight(TFT_T *dev, uint8_t value) {
|
|
dev->blacklight(value);
|
|
}
|
|
|
|
void TFT_FillRect(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t *color) {
|
|
if (x + width > dev->width || y + height > dev->height)return;
|
|
uint32_t size = width + height - 2;
|
|
TFT_SetWindow(dev, x, y, width, height);
|
|
dev->data(color->u8, size);
|
|
}
|
|
|
|
void TFT_Fill(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t color) {
|
|
if (x + width > dev->width || y + height > dev->height)return;
|
|
uint32_t size = width + height - 2;
|
|
TFT_SetWindow(dev, x, y, width, height);
|
|
while (size--) {
|
|
dev->data(color.u8, 2);
|
|
}
|
|
}
|
|
|
|
void TFT_FillColor(TFT_T *dev, TFT_Color_t color) {
|
|
dev->data(color.u8, 2);
|
|
}
|
|
|
|
void TFT_DrawLine(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
|
|
uint16_t i, k, k1, k2;
|
|
if ((x1 < 0) || (x2 > dev->width) || (y1 < 0) || (y2 > dev->height) || (x1 > x2) || (y1 > y2))return;
|
|
if (x1 == x2) //画竖线
|
|
{
|
|
for (i = 0; i < (y2 - y1); i++) {
|
|
TFT_SetPixel(dev, x1, y1 + i, POINT_COLOR);
|
|
}
|
|
} else if (y1 == y2) //画横线
|
|
{
|
|
for (i = 0; i < (x2 - x1); i++) {
|
|
TFT_SetPixel(dev, x1 + i, y1, POINT_COLOR);
|
|
}
|
|
} else //画斜线
|
|
{
|
|
k1 = y2 - y1;
|
|
k2 = x2 - x1;
|
|
k = k1 * 10 / k2;
|
|
for (i = 0; i < (x2 - x1); i++) {
|
|
TFT_SetPixel(dev, x1 + i, y1 + i * k / 10, POINT_COLOR);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TFT_DrawRect(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
|
|
TFT_DrawLine(dev, x1, y1, x2, y1); // Top side
|
|
TFT_DrawLine(dev, x1, y1, x1, y2); // Left side
|
|
TFT_DrawLine(dev, x2, y1, x2, y2); // Right side
|
|
TFT_DrawLine(dev, x1, y2, x2, y2); // Bottom side
|
|
}
|
|
|
|
void TFT_DrawCircle(TFT_T *dev, uint16_t x, uint16_t y, uint16_t r) {
|
|
int a, b, num;
|
|
a = 0;
|
|
b = r;
|
|
while (2 * b * b >= r * r) {
|
|
TFT_SetPixel(dev, x + a, y - b, POINT_COLOR);
|
|
TFT_SetPixel(dev, x - a, y - b, POINT_COLOR);
|
|
TFT_SetPixel(dev, x - a, y + b, POINT_COLOR);
|
|
TFT_SetPixel(dev, x + a, y + b, POINT_COLOR);
|
|
TFT_SetPixel(dev, x + b, y + a, POINT_COLOR);
|
|
TFT_SetPixel(dev, x + b, y - a, POINT_COLOR);
|
|
TFT_SetPixel(dev, x - b, y - a, POINT_COLOR);
|
|
TFT_SetPixel(dev, x - b, y + a, POINT_COLOR);
|
|
|
|
a++;
|
|
num = (a * a + b * b) - r * r;//计算画的点离圆心的距离
|
|
if (num > 0) {
|
|
b--;
|
|
a--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TFT_ShowChar(TFT_T *dev, uint16_t x, uint16_t y, uint16_t chr, uint16_t size1) {
|
|
uint16_t i, m, temp, size2, chr1;
|
|
uint16_t ys = y;
|
|
size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数
|
|
chr1 = chr - ' '; //计算偏移后的值
|
|
for (i = 0; i < size2; i++) {
|
|
if (size1 == 12) { temp = asc2_1206[chr1][i]; } //调用1206字体
|
|
else if (size1 == 16) { temp = asc2_1608[chr1][i]; } //调用1608字体
|
|
else if (size1 == 24) { temp = asc2_2412[chr1][i]; } //调用2412字体
|
|
else return;
|
|
for (m = 0; m < 8; m++) //写入数据
|
|
{
|
|
if (temp & 0x80)TFT_SetPixel(dev, x, ys, POINT_COLOR);
|
|
else TFT_SetPixel(dev, x, ys, BACK_COLOR);
|
|
temp <<= 1;
|
|
ys++;
|
|
if ((ys - y) == size1) {
|
|
ys = y;
|
|
x++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TFT_ShowString(TFT_T *dev, uint16_t x, uint16_t y, uint16_t *str, uint16_t size1) {
|
|
while ((*str >= ' ') && (*str <= '~'))//判断是不是非法字符!
|
|
{
|
|
TFT_ShowChar(dev, x, y, *str, size1);
|
|
x += size1 / 2;
|
|
if (x > dev->width - size1) //换行
|
|
{
|
|
x = 0;
|
|
y += 2;
|
|
}
|
|
str++;
|
|
}
|
|
}
|
|
|
|
#ifdef HZK_FONT
|
|
|
|
void TFT_ShowCHChr(TFT_T *dev, uint16_t x, uint16_t y, Chinese_t *hzk) {
|
|
uint16_t i, size2 = Hzk_size * ((Hzk_size + 7) / 8 * 8) / 8;
|
|
uint16_t ziku_byte_n, ziku_bytes = ((Hzk_size + 7) / 8 * 8) / 8;
|
|
ziku_byte_n = 0;
|
|
TFT_Color_t temp;
|
|
for (i = 0; i < size2; i++) {
|
|
temp = hzk->data[i] ? POINT_COLOR : BACK_COLOR;
|
|
TFT_SetPixel(dev, x + ziku_byte_n * 8, y, temp);
|
|
ziku_byte_n++;
|
|
if (ziku_byte_n >= ziku_bytes) {
|
|
ziku_byte_n = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef UTF8_TO_UNICODE
|
|
|
|
#include "font.h"
|
|
|
|
#define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */
|
|
#define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */
|
|
|
|
void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) {
|
|
uint32_t unicode_letter;
|
|
uint16_t step;
|
|
while (*str != '\0') {
|
|
bool found = false;
|
|
step = Font_utf8_to_unicode(str, &unicode_letter);
|
|
if (step != 0) {
|
|
Chinese_t *hzk = find_chinese_data(GET_LOW_BYTE1(unicode_letter), GET_LOW_BYTE0(unicode_letter));
|
|
if (hzk != NULL) {
|
|
TFT_ShowCHChr(dev, x, y, hzk);
|
|
x += Hzk_size;
|
|
str += step;
|
|
found = true;
|
|
}
|
|
}
|
|
if (!found) {
|
|
TFT_ShowChar(dev, x, y, *str, Hzk_size);
|
|
x += Hzk_size / 2;
|
|
str++;
|
|
}
|
|
if (x > dev->width - Hzk_size) {
|
|
x = 0;
|
|
y += Hzk_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
#else
|
|
void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) {
|
|
uint16_t index;
|
|
while (*str != '\0') {
|
|
bool found = false;
|
|
for (index = 0; index < sizeof(Hzk) / sizeof(Chinese_t); index++) {
|
|
if (Hzk[index].unicode[0] == str[0] && Hzk[index].unicode[1] == str[1]) // 对比汉字区码位码
|
|
{
|
|
TFT_ShowCHChr(dev, x, y, &Hzk[index]);
|
|
x += Hzk_size;
|
|
str++;
|
|
str++;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
TFT_ShowChar(dev, x, y, *str, Hzk_size);
|
|
x += Hzk_size / 2;
|
|
str++;
|
|
}
|
|
if (x > dev->width - Hzk_size) {
|
|
x = 0;
|
|
y += Hzk_size;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
#ifdef LVGL_FONT
|
|
#include "font.h"
|
|
void draw_rect(Font_f_t *fd, uint16_t *data, size_t len) {
|
|
TFT_T *dev=(TFT_T*)fd->dev;
|
|
TFT_Color_t tmp;
|
|
TFT_SetCur(dev,fd->x,fd->y);
|
|
while (len--){
|
|
tmp.color=*data;
|
|
TFT_FillColor(dev,tmp);
|
|
data++;
|
|
}
|
|
}
|
|
|
|
void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y) {
|
|
uint32_t unicode_letter;
|
|
Font_f_t fd = {.dev=dev, .dev_w=dev->width, .show=draw_rect};
|
|
while (*s) {
|
|
if (font) {
|
|
s += Font_utf8_to_unicode(s, &unicode_letter);
|
|
x += Font_draw_letter(font, &fd, unicode_letter, x, y);
|
|
x += 0; //字间距
|
|
} else {
|
|
TFT_ShowChar(dev, x, y, *s, 12);
|
|
x += 12;
|
|
s++;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
uint32_t TFT_Pow(uint8_t m, uint8_t n) {
|
|
uint32_t result = 1;
|
|
while (n--) {
|
|
result *= m;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void TFT_ShowNum(TFT_T *dev, uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1) {
|
|
uint8_t t, temp;
|
|
for (t = 0; t < len; t++) {
|
|
temp = (num / TFT_Pow(10, len - t - 1)) % 10;
|
|
if (temp == 0) {
|
|
TFT_ShowChar(dev, x + (size1 / 2) * t, y, '0', size1);
|
|
} else {
|
|
TFT_ShowChar(dev, x + (size1 / 2) * t, y, temp + '0', size1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TFT_ShowPic(TFT_T *dev, uint8_t x0, uint8_t y0, uint8_t w, uint8_t h, TFT_Color_t *bmp) {
|
|
size_t index;
|
|
uint16_t x = x0, y = y0;
|
|
for (index = 0; index < (w * h) / 8; index++) {
|
|
TFT_SetPixel(dev, x, y, bmp[index]);
|
|
x++;
|
|
if ((x - x0) == w) {
|
|
y += 8;
|
|
x = x0;
|
|
}
|
|
}
|
|
}
|