在对开发板TFT屏幕显示进行了初步了解之后,这将完成了显示汉字的实验,同时写了一个可以用8*16点阵显示ASCII码和16*16点阵显示汉字的字符串函数,改进了原范例只能显示单个字符的缺陷。下图为显示的效果:
显示控制的代码如下图,可以在字符串中任意包含汉字或ASCII字符:
汉字字库的结构如下图:
字符串显示的函数如下:
/*!
\brief 从根据指定位置开始在液晶屏上显示字符串(8*16ASCII和16*16汉字字符集)
\param[in] x: the start position of row-coordinate X坐标
\param[in] y: the start position of column-coordinate Y坐标
\param[in] text: the char 要显示的字符串
\param[in] char_color: the color of char 字符颜色
\param[in] c_format: the structure of char format 字体(字库)
font: CHAR_FONT_8_16 or CHAR_FONT_16_24
direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
char_color: the color of char
bk_color: the color of background
\param[out] none
\retval none
*/
void lcd_strue_display(uint16_t x,uint16_t y,uint8_t *str,char_format_struct c_format)
{
uint8_t i,j,k,temp_char;
uint16_t X,Y;
X = x;
Y = y;
while(*str){
if(((uint8_t)(*str)) < 128){ //显示单字节ASCII(8*16)
if(*str > 31){
for (i = 0; i < 16; i++) { //显示16行的点阵
temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
lcd_point_set(X + j, Y + i, c_format.char_color);
} else {
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
}
}
str++;
X += 8;
}
else{ //显示双字节汉字(16*16)
for(k=0; k<200; k++){ //在汉字字符集中查找小于200次
if((GB_16ID[k][0] == *(str)) && (GB_16ID[k][1] == *(str + 1))){
for( i=0; i<16; i++){//显示16行的点阵(左半边)
temp_char = GB_16[(k * 32) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
lcd_point_set(X + j, Y + i, c_format.char_color);
} else {
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
}
for( i=0; i<16; i++){//显示16行的点阵(右半边)
temp_char = GB_16[(k * 32) + i + 16];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
lcd_point_set(X + j + 8, Y + i, c_format.char_color);
} else {
lcd_point_set(X + j + 8, Y + i, c_format.bk_color);
}
}
}
}
}
str += 2;
X += 16;
}
}
}
在这个函数中暂时还没有考虑改变字体方向的问题,稍后准备增加这项功能,以便与范例代码衔接。
不错不错!有木有字体点阵的设置方式,行扫描列扫描啥的,可以贴出图片来。
引用: w494143467 发表于 2021-1-12 22:19 不错不错!有木有字体点阵的设置方式,行扫描列扫描啥的,可以贴出图片来。
第二幅图片就是:横向取模左高位,数据排列从上到下从左到右。
引用: hujj 发表于 2021-1-13 09:34 第二幅图片就是:横向取模左高位,数据排列从上到下从左到右。
好嘞,到时候我试一下,这样就不用各种试方向了。
显示的代码如下:
显示的函数代码:
/*!
\brief 从根据指定位置开始在液晶屏上显示字符串(8*16ASCII和16*16汉字字符集)
\param[in] x: the start position of row-coordinate X坐标
\param[in] y: the start position of column-coordinate Y坐标
\param[in] text: the char 要显示的字符串
\param[in] char_color: the color of char 字符颜色
\param[in] c_format: the structure of char format 字体(字库)
font: CHAR_FONT_8_16 or CHAR_FONT_16_24
direction: CHAR_DIRECTION_HORIZONTAL or CHAR_DIRECTION_VERTICAL
char_color: the color of char
bk_color: the color of background
\param[out] none
\retval none
*/
void lcd_strue_display(uint16_t x,uint16_t y,uint8_t *str,char_format_struct c_format)
{
uint8_t i,j,k,temp_char;
uint16_t X,Y;
X = x;
Y = y;
while(*str){
if(((uint8_t)(*str)) < 128){ //显示单字节ASCII(8*16)
if(*str > 31){
if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){//水平显示
for (i = 0; i < 16; i++) { //显示16行的点阵
temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01) {
lcd_point_set(X - i, Y + j, c_format.char_color);
} else {
lcd_point_set(X - i, Y + j, c_format.bk_color);
}
}
}
Y += 8;
}else{
for (i = 0; i < 16; i++) { //显示16行的点阵
temp_char = ascii_8x16[((*str - 0x20) * 16) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j, Y + i, c_format.char_color);
else
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
X += 8;
}
}
str++;
}
else{ //显示双字节汉字(16*16)
for(k=0; k<200; k++){ //在汉字字符集中查找小于200次
if((GB_16ID[k][0] == *(str)) && (GB_16ID[k][1] == *(str + 1))){
if(CHAR_DIRECTION_HORIZONTAL == c_format.direction){ //水平显示
for( i=0; i<16; i++){//显示16行的点阵(左半边)
temp_char = GB_16[(k * 32) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X - i, Y + j, c_format.char_color);
else
lcd_point_set(X - i, Y + j, c_format.bk_color);
}
}
for( i=0; i<16; i++){//显示16行的点阵(右半边)
temp_char = GB_16[(k * 32) + i + 16];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X - i, Y + j + 8, c_format.char_color);
else
lcd_point_set(X - i, Y + j + 8, c_format.bk_color);
}
}
Y += 16;
} else {
for( i=0; i<16; i++){//显示16行的点阵(左半边)
temp_char = GB_16[(k * 32) + i];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j, Y + i, c_format.char_color);
else
lcd_point_set(X + j, Y + i, c_format.bk_color);
}
}
for( i=0; i<16; i++){//显示16行的点阵(右半边)
temp_char = GB_16[(k * 32) + i + 16];
for (j = 0; j < 8; j++) {
if (((temp_char >> (7 - j)) & 0x01) == 0x01)
lcd_point_set(X + j + 8, Y + i, c_format.char_color);
else
lcd_point_set(X + j + 8, Y + i, c_format.bk_color);
}
}
X += 16;
}
}
}
str += 2;
}
}
}
引用: caizhiwei 发表于 2021-1-14 08:18 牛!昨天晚上还在研究这个,没搞出来~
这是参照范例照葫芦画瓢,就是水平(横向)和垂直(竖向)有点懵圈,测试了多次才成功的。
这个软件也是从网上获得的,我已经用习惯了,感觉很好用,完全可以满足我的需要。顺便感谢一下软件的作者!
引用: csfc 发表于 2024-5-15 13:58 大佬能发个完整的吗,对照着改入GD32F303中,运行报错了,想看看那一块的问题。
这是当时保存的项目文件,希望能够帮助到您。
引用: hujj 发表于 2024-5-16 11:46 这是当时保存的项目文件,希望能够帮助到您。
感谢大佬,我看看