|
本帖最后由 topdog 于 2022-9-4 08:47 编辑
深圳晶彩智能3.5寸彩色屏采用分辨率480x320彩色液晶屏,驱动芯片是ST7796。唐代张若虚诗作《春江花月夜》是唐诗中最美的,那么用深圳晶彩智能3.5寸彩色屏研究一下中文显示,做一款中文提示器。主要用到的是u8g2针对彩屏文字显示推出的U8g2_for_Adafruit_GFX库和U8g2_for_TFT_eSPI库。通过实验后者速度明显快。
1,,Adafruit ST7796库地址:https://github.com/prenticedavid/Adafruit_ST7796S_kbv
2,U8g2_for_Adafruit_GFX库和U8g2_for_TFT_eSPI库用一个自定义中文字库见附录,非常感谢制作这个开源字库的创客。
3,U8g2_for_Adafruit_GFX库应用程序如下:
[pre]#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ST7796S_kbv.h"
#include "U8g2_for_Adafruit_GFX.h"
#include "gb2312.c"
#define BLACK 0x0000
#define WHITE 0xFFFF
const int TFT_CS = 15;
const int TFT_DC = 2;
const int TFT_MOSI = 13;
const int TFT_MISO = 12;
const int TFT_CLK = 14;
const int TFT_RST = -1;
const int TFT_BL = 27;
extern const uint8_t chinese_gb2312[254049] U8G2_FONT_SECTION("chinese_gb2312");
Adafruit_ST7796S_kbv display = Adafruit_ST7796S_kbv(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;
const char c_str[] =
"Chun Jiang Hua Yue Ye\n\n"
"春江花月夜\n"
"唐代张若虚诗作\n"
"春江潮水连海平,海上明月共潮生。\n"
"滟滟随波千万里,何处春江无月明!\n"
"江流宛转绕芳甸,月照花林皆似霰。\n"
"空里流霜不觉飞,汀上白沙看不见。\n"
"江天一色无纤尘,皎皎空中孤月轮。\n"
"江畔何人初见月?江月何年初照人?\n"
"人生代代无穷已,江月年年望相似。\n"
"不知江月待何人,但见长江送流水。\n"
"白云一片去悠悠,青枫浦上不胜愁。\n"
"谁家今夜扁舟子?何处相思明月楼?\n"
"可怜楼上月徘徊,应照离人妆镜台。\n"
"玉户帘中卷不去,捣衣砧上拂还来。\n"
"此时相望不相闻,愿逐月华流照君。\n"
"鸿雁长飞光不度,鱼龙潜跃水成文。\n"
"昨夜闲潭梦落花,可怜春半不还家。\n"
"江水流春去欲尽,江潭落月复西斜。\n"
"斜月沉沉藏海雾,碣石潇湘无限路。\n"
"不知乘月几人归,落月摇情满江树。\n";
char buf[48]; // 每行最多8个汉字,最大字体大小为8*3 = 24
uint8_t total_lines; // 故事的总台词数
uint8_t i; // 行循环变量
uint8_t line_cnt; //要绘制的线条数,通常等于lines_per_draw
uint8_t start_line; //最上面的可见行,派生自top_window_pos
uint8_t lines_per_draw; //根据字体和显示高度在屏幕上画多少行
uint16_t glyph_height; // 字形的高度
uint16_t glyph_width;
uint16_t top_window_pos; // 定义文本中以像素为单位的显示位置
uint16_t total_height; // 总高度(以像素为单位),由字体高度和total_lines派生
uint16_t top_offset; // 第一个可见线与显示器之间的偏移量
uint8_t u8x8_GetStringLineCnt(const char *str)
{
char e;
uint8_t line_cnt = 1;
if ( str == NULL )
return 0;
for (;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
line_cnt++;
}
return line_cnt;
}
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str )
{
char e;
uint8_t line_cnt = 1;
if ( line_idx == 0 )
return str;
for (;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
{
if ( line_cnt == line_idx )
return str;
line_cnt++;
}
}
return NULL; /* line not found */
}
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str)
{
if ( dest == NULL )
return;
str = u8x8_GetStringLineStart( line_idx, str );
if ( str != NULL )
{
for (;;)
{
if ( *str == '\n' || *str == '\0' )
break;
*dest = *str;
dest++;
str++;
}
}
*dest = '\0';
}
void setup() {
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
display.begin();
display.setRotation(0);
display.fillScreen(BLACK);
u8g2_for_adafruit_gfx.begin(display); // connect u8g2 procedures to Adafruit GFX
u8g2_for_adafruit_gfx.setFont(chinese_gb2312);
u8g2_for_adafruit_gfx.setForegroundColor(WHITE); // apply Adafruit GFX color
/* 按行计算文本的长度 */
total_lines = u8x8_GetStringLineCnt(c_str);
/* 得到符号的高度 */
//glyph_height = u8g2_for_adafruit_gfx.getMaxCharHeight();
glyph_height = u8g2_for_adafruit_gfx.u8g2.font_info.max_char_height;
glyph_width = u8g2_for_adafruit_gfx.u8g2.font_info.max_char_width;
/* 计算文本的像素高度 */
total_height = (uint16_t)total_lines * (uint16_t)glyph_height;
/* 计算屏幕上必须画多少条线 */
lines_per_draw = display.height() / glyph_height;
lines_per_draw += 3;
/*从文本的顶部开始 */
top_window_pos = 0;
start_line = top_window_pos / glyph_height;
top_offset = top_window_pos % glyph_height;
line_cnt = total_lines - start_line;
if ( line_cnt > lines_per_draw )
line_cnt = lines_per_draw;
//display.clearDisplay(); // 清除graphcis缓冲区
for ( i = 0; i < line_cnt; i++ )
{
/* 将文本的一行复制到本地缓冲区*/
u8x8_CopyStringLine(buf, i + start_line, c_str);
/* 绘制本地缓冲区的内容 */
u8g2_for_adafruit_gfx.drawUTF8(0, i * glyph_height - top_offset + glyph_height, buf);
}
}
void loop() {}[/pre]
4,TFT_eSPI 库User_Setup.h设置修改如下:
TFT_eSPI 库自带的字体没有用到,为了节约存储空间加快编译速度,涉及字体的键值对没有被引用。
[pre]#define ST7796_DRIVER // Full configuration option, define additional parameters below for this display
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
#define TFT_BACKLIGHT_ON HIGH // Level to turn ON back-light (HIGH or LOW)
#define TFT_MISO 12
#define TFT_MOSI 13 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 14
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST -1 // Reset pin (could connect to Arduino RESET pin)
#define TFT_BL 27 // LED back-light
#define TOUCH_CS 33 // Chip select pin (T_CS) of touch screen
#define SD_CS 5
#define SPI_FREQUENCY 65000000
// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000 //2500000
#define USE_HSPI_PORT[/pre]
5,U8g2_for_TFT_eSPI库应用程序如下:
[pre]#include "SPI.h"
#include "TFT_eSPI.h"
#include "U8g2_for_TFT_eSPI.h"
#include "gb2312.c"
extern const uint8_t chinese_gb2312[254049] U8G2_FONT_SECTION("chinese_gb2312");
TFT_eSPI tft = TFT_eSPI(); // tft instance
U8g2_for_TFT_eSPI u8f; // U8g2 font instance
const char c_str[] =
"Chun Jiang Hua Yue Ye\n\n"
"春江花月夜\n"
"唐代张若虚诗作\n"
"春江潮水连海平,海上明月共潮生。\n"
"滟滟随波千万里,何处春江无月明!\n"
"江流宛转绕芳甸,月照花林皆似霰。\n"
"空里流霜不觉飞,汀上白沙看不见。\n"
"江天一色无纤尘,皎皎空中孤月轮。\n"
"江畔何人初见月?江月何年初照人?\n"
"人生代代无穷已,江月年年望相似。\n"
"不知江月待何人,但见长江送流水。\n"
"白云一片去悠悠,青枫浦上不胜愁。\n"
"谁家今夜扁舟子?何处相思明月楼?\n"
"可怜楼上月徘徊,应照离人妆镜台。\n"
"玉户帘中卷不去,捣衣砧上拂还来。\n"
"此时相望不相闻,愿逐月华流照君。\n"
"鸿雁长飞光不度,鱼龙潜跃水成文。\n"
"昨夜闲潭梦落花,可怜春半不还家。\n"
"江水流春去欲尽,江潭落月复西斜。\n"
"斜月沉沉藏海雾,碣石潇湘无限路。\n"
"不知乘月几人归,落月摇情满江树。\n";
char buf[48]; // there are at most 8 chinese glyphs per line, max buf size is 8*3 = 24
uint8_t total_lines; // the total number of lines in the story
uint8_t i; // loop variable for the lines
uint8_t line_cnt; // number of lines to draw, usually equal to lines_per_draw
uint8_t start_line; // topmost visible line, derived from top_window_pos
uint8_t lines_per_draw; // how many lines to draw on the screen, derived from font and display height
uint16_t glyph_height; // height of the glyphs
uint16_t glyph_width;
uint16_t top_window_pos; // defines the display position in pixel within the text
uint16_t total_height; // total height in pixel, derived from font height and total_lines
uint16_t top_offset; // offset between the first visible line and the display
uint8_t u8x8_GetStringLineCnt(const char *str)
{
char e;
uint8_t line_cnt = 1;
if ( str == NULL )
return 0;
for(;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
line_cnt++;
}
return line_cnt;
}
/*
Assumes strings, separated by '\n' in "str".
Returns the string at index "line_idx". First strng has line_idx = 0
Example:
Returns "xyz" for line_idx = 1 with str = "abc\nxyz"
Support both UTF8 and normal strings.
*/
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str )
{
char e;
uint8_t line_cnt = 1;
if ( line_idx == 0 )
return str;
for(;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
{
if ( line_cnt == line_idx )
return str;
line_cnt++;
}
}
return NULL; /* line not found */
}
/* copy until first '\n' or '\0' in str */
/* Important: There is no string overflow check, ensure */
/* that the destination buffer is large enough */
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str)
{
if ( dest == NULL )
return;
str = u8x8_GetStringLineStart( line_idx, str );
if ( str != NULL )
{
for(;;)
{
if ( *str == '\n' || *str == '\0' )
break;
*dest = *str;
dest++;
str++;
}
}
*dest = '\0';
}
void setup() {
tft.begin();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
u8f.begin(tft); // connect u8g2 procedures to TFT_eSPI
u8f.setFont(chinese_gb2312);
u8f.setForegroundColor(TFT_WHITE); // apply color
/* calculate the length of the text in lines */
total_lines = u8x8_GetStringLineCnt(c_str);
/* get the height of the glyphs */
//glyph_height = u8f.getMaxCharHeight();
glyph_height = u8f.u8g2.font_info.max_char_height;
glyph_width = u8f.u8g2.font_info.max_char_width;
/* calculate the height of the text in pixel */
total_height = (uint16_t)total_lines * (uint16_t)glyph_height;
/* calculate how many lines must be drawn on the screen */
lines_per_draw = tft.height() / glyph_height;
lines_per_draw += 2;
/* start at the top of the text */
top_window_pos = 0;
start_line = top_window_pos / glyph_height;
top_offset = top_window_pos % glyph_height;
line_cnt = total_lines - start_line;
if ( line_cnt > lines_per_draw )
line_cnt = lines_per_draw;
for( i = 0; i < line_cnt; i++ )
{
/* copy a line of the text to the local buffer */
u8x8_CopyStringLine(buf, i+start_line, c_str);
/* draw the content of the local buffer */
u8f.drawUTF8(0, i*glyph_height-top_offset +glyph_height, buf);
}
}
void loop() {}[/pre]
6,效果图:
7,附件在这里呀!
tangshi.rar
(446.62 KB, 下载次数: 0)
|
|