HW_Lib/lib/tft/tft.cpp

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