OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6909|回复: 9

TFT彩屏 字体显示和描图程序理解问题

[复制链接]

21

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2014-3-12
在线时间
3 小时
发表于 2014-4-15 21:22:23 | 显示全部楼层 |阅读模式

这两天在研读TFT彩屏的绘图和写字程序,flash,SD 卡这些都没学,所以教程中的写字程序SD卡 flash也没怎么看懂,也没有很好理解字库制作的程序,于是就想着自己用字摸软件弄几个汉字,输出对应数组,然后自己写个字摸扫描程序读取这些数组从而显示字体。

目前来说写个函数包能够单个的显示一个汉字,也就是比如能够扫描自己做的单个汉字的一维数组。但二维数组传值就弄不来,先看一维数组单个汉字

比如制作了个16*16字体  const unsigned char CH_WORD1[72]=                                    {0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x03,0x80,0x1C,0x07,0x1F,0xFC,0x06,0x00,0x00,0x0C,0x00,0x00,0x19,0xC0,0x00,  0x31,0x80,0x00,0x03,0x80,0x0E,0x07,0x3F,0xF8,0x07,0x00,0xC0,0x0F,0x00,0xC0,0x1B,0x00,0xC0,0x33,0x00,0xC0,0x63,0x00,0xC0,
 0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x01,0xC0,0x03,0x0F,0xC0,0x03,0x03,0x80,0x00,0x00,0x00};


函数写成

//从左往右 从上往下扫描   横屏模式

void LCD_show_CH_WORD(u16 x,u16 y,u8 *CH,u8 size)
{
        u8 i,j;
 u8 temp;
 u8 byt=size*size/8;   //size 字体  16*16或12*12或24*24
 u8 px;       //像素点
 byt=size*size/8;
 for(j=0;j<size;j++)   //一个字体的第 j 行
 {
            for(i=0;i<(size/8);i++)   //一个字体第j行第 i 个字节
            {
                 temp=*CH++;   //导入单个汉字一维数组
                  for(px=0;px<8;px++)     //一个字节第j行的第 i 个字节的px位
                  {
                     if(temp&0x80)  LCD_DrawPoint(x+px+i*8,y+j);   // 画点
                     temp<<=1;    //高位先扫描
                  }
            }
        }
}

调用函数写为

LCD_show_CH_WORD(160, 160, (u8*)CH_WORD1, 24);

这个就显示一个24*24的汉字,调用一个一维数组 显示没问题。  但我现在想连续显示汉字字符串,也就是调用一个制作好的二维数组,每一维代表一个汉字,也写成一个函数包,形参里写入这个二维数组,问题就在于这个形参我写不好,就算写好了,这个形参在程序里我也不知如何用。网上也学了些C代码将讲解2维数组形参传值的例子,但始终用不好。   二维数组每一维代表一个汉字,

比如我现在要调用这个二维数组显示汉字串


unsigned char String_CH1[4][72]= {
                   { 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x03,0x80,0x1C,0x07,0x1F,0xFC,0x06,0x00,0x00,0x0C,0x00,0x00,0x19,0xC0,0x00,
                    0x31,0x80,0x00,0x03,0x80,0x0E,0x07,0x3F,0xF8,0x07,0x00,0xC0,0x0F,0x00,0xC0,0x1B,0x00,0xC0,0x33,0x00,0xC0,0x63,0x00,0xC0,
                    0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x00,0xC0,0x03,0x01,0xC0,0x03,0x0F,0xC0,0x03,0x03,0x80,0x00,0x00,0x00},
                    
                   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x1C,0x03,0xFF,0xFC,0x03,0x00,0x1C,0x03,0x00,0x1C,0x03,0x00,0x1C,
                    0x03,0x00,0x1C,0x03,0xFF,0xFC,0x03,0x00,0x1C,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x07,0x00,0x00,
                    0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},
                    
                   { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x70,0x07,0xFF,0xC0,0x00,0x1C,0x00,
                    0x00,0x1C,0x00,0x00,0x1C,0x0C,0x3F,0xFF,0xFE,0x00,0x1C,0x00,0x03,0x1C,0x00,0x03,0x9C,0x00,0x03,0x1C,0x30,0x07,0x1F,0xF8,
                    0x07,0x1C,0x00,0x07,0x9C,0x00,0x06,0xDC,0x00,0x0C,0x7C,0x00,0x1C,0x3E,0x00,0x18,0x0F,0xFE,0x30,0x00,0x3C,0x00,0x00,0x00},
                                                                      
                   {  0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x18,0x1C,0x0C,0x1F,0xFF,0xFC,0x1C,0x18,0x1C,0x1C,0x38,0x1C,
                    0x1C,0x3F,0x1C,0x1C,0x73,0xDC,0x1C,0xF9,0xDC,0x1D,0x9C,0xDC,0x1F,0x18,0x1C,0x1C,0x38,0x1C,0x1C,0x3E,0x1C,0x1C,0x73,0x9C,
                    0x1C,0xE1,0xDC,0x1D,0xC1,0xDC,0x1F,0x00,0xDC,0x1E,0x00,0x1C,0x1C,0x01,0xFC,0x1C,0x00,0x3C,0x18,0x00,0x30,0x00,0x00,0x00}
                 };


我目前把函数写成

void LCD_show_CH_STRING(u16 x, u16 y, u8 *CH, u8 num, u8 size)
{
  u8 j,i,n;
 u8 byte;
 u8 temp;
 u8 Index=0;
 u8 px;
 u8 *P1[4];
 
 byte=size*size/8;
 for(n=0;n<num;n++)   //写第n个汉字
 {  // P1[n]=CH[n];
       for(j=0;j<size;j++)   //第 J 行
       {
          for(i=0;i<(size/8);i++)   //第   i  个字节
          {
              //    temp=*((CH[n])+i);
             //   temp=CH[n];
              for(px=0;px<8;px++)     //第 px 个像素
              {
                  delay_ms(1);
                  if(temp&0x80) LCD_DrawPoint(x+px+i*8+n*size,y+j);  // 画点
                  temp<<=1;
              }
          }
      }     
   } 
}

调用函数我写成 

LCD_show_CH_STRING(160,  160,  (u8*)String_CH1,  4,  24);

上面注释掉的部分有错误,我参考网上的一些写法,但问题还是觉得形参这里调用二维数组有问题,或者调进函数后这个二维数组如何操作有问题。

我非常希望能在上面那个模板的情况下成功,但无能为力,编译报错,显示不出,等一系列问题。


我现在唯一能调用上面那个二维数组 连续写汉字的 办法就是


 for(j=0;j<num;j++)   //num是汉字个数
 {
    LCD_show_CH_WORD(x+Index,y,(u8*)String_CH1[j],size);  // 调用单个汉字一维数组的函数包。
    Index=Index+size+12;   // Index可控制间距 
  }

但这样我写成一个函数包的话   形参  是没发直接写上一个二维数组的名字, 如果我要调用不同的二维数组汉字串的话,我得不停修改 函数里面的 二维数组名字,这不是我想要的。

这里有哪位专家能指点我一下,这个而维数组怎么才能很好的传递到形参里然后 在函数内部怎么写,才能顺利扫描每一个二维数组元素呢?谢谢家!!!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

76

帖子

0

精华

高级会员

Rank: 4

积分
733
金钱
733
注册时间
2014-4-12
在线时间
210 小时
发表于 2014-4-15 23:02:56 | 显示全部楼层
回复【楼主位】duanyuzhong:
---------------------------------
我这两天也在看这个,跟其他人写的程序对比了下,移植了一个程序,你看下怎么样。

将自己做的字符数组放在main.c函数中,调用的时候使用 LCD_Char_24_24(0, 50, &CH_WORD1[72]);试试看。

void LCD_Char_24_24(u8 Xpos, u16 Ypos, uc8 *c) //芯嵌屏ILI9341,面朝上,上面是字符,下面是插针(座)
{ //X是列,从左到右递增,Y是行,从上到下递增。
  u32 index = 0, i = 0,Hang; //注意,一个字符: 行为24行,列是16列
  u8 Yaddress = 0;

  Yaddress = Ypos;

  for(Hang = 0; Hang < 24; Hang++)    //一个字符: 24行
  {
    
LCD_SetCursor(Xpos, Yaddress);   //第一个字节
LCD_WriteRAM_Prepare(); /* repare to write GRAM */
    for(i = 0; i < 8; i++){
      if((c[index + Hang] & (1 << i)) == 0x00){
        LCD_WriteRAM(BACK_COLOR);
      }else{
        LCD_WriteRAM(POINT_COLOR);
      }
    }
index++;

LCD_SetCursor(Xpos+8, Yaddress);        //第二个字节
LCD_WriteRAM_Prepare();

    for(i = 0; i < 8; i++){
      if((c[index + Hang] & (1 << i)) == 0x00){
        LCD_WriteRAM(BACK_COLOR);
      }else{
        LCD_WriteRAM(POINT_COLOR);
      }
    }
index++;

LCD_SetCursor(Xpos+16, Yaddress);        //第三个字节
LCD_WriteRAM_Prepare();

    for(i = 0; i < 8; i++){
      if((c[index + Hang] & (1 << i)) == 0x00){
        LCD_WriteRAM(BACK_COLOR);
      }else{
        LCD_WriteRAM(POINT_COLOR);
      }
    }

//    LCD_WriteRAM_Ready();
    Yaddress++;
    //LCD_SetCursor(Xpos, Yaddress);
  }
 }
回复 支持 反对

使用道具 举报

18

主题

53

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2014-4-15
在线时间
0 小时
发表于 2014-4-16 08:41:05 | 显示全部楼层
我也是新手,你试试将调用函数改为
LCD_show_CH_STRING(160,  160,  (u8*)String_CH1[0],  4,  24);
看下有没有用
回复 支持 反对

使用道具 举报

21

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2014-3-12
在线时间
3 小时
 楼主| 发表于 2014-4-16 16:23:30 | 显示全部楼层
回复【2楼】ringhui:
---------------------------------

这样应该是可以显示一个字符的,可以调用一个自几制作的字符,但要搞成字符串呵呵,就和我汉字要搞个汉字串一样,碰到上面的问题。 原子的字符串显示程序中,font.h文件中有一个12*12和16*16的字符ASC码表 ,只要你在程序中输入对应的字符,程序就会搜到那个ASC码对应的字符数组,然后的操作就和你上面的那段程序差不多,实现方法有些不同。
回复 支持 反对

使用道具 举报

9

主题

126

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2014-4-3
在线时间
18 小时
发表于 2014-4-16 17:10:48 | 显示全部楼层
struct __HZK_ZK
{
u16 code;
u8  HZCODE[32];
};

const struct __HZK_ZK sysHzzk[]=
{

{0xB3F5,
{0x20,0x00,0x10,0x00,0x01,0xFC,0xFC,0x44,0x08,0x44,0x10,0x44,0x10,0x44,0x34,0x44,
0x58,0x44,0x94,0x44,0x14,0x44,0x10,0x84,0x10,0x84,0x11,0x04,0x12,0x28,0x14,0x10}},/*"初",0*/
}

code就是GBK编码,找到编码输出汉字就可以了。联合体。比较方便。
回复 支持 反对

使用道具 举报

21

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2014-3-12
在线时间
3 小时
 楼主| 发表于 2014-4-16 17:52:52 | 显示全部楼层
回复【5楼】dixdsqaid:
---------------------------------
我现在就是在想办法把这段程序改成  函数包调入二维数组形参

for(j=0;j<num;j++)   //num是汉字个数
{
       LCD_show_CH_WORD(x+Index, y, (u8*)String_CH1[j],size);  // 调用单个汉字一维数组的函数包。
       Index=Index+size+12;   // Index可控制间距  
}

(u8*)String_CH1[j]    这是个二维数组名字,先在想把上面那段程序弄成函数包,形参里面就要有个能传二维数组的
形参变量

比如写成
LCD_show_CH_STRING(u8 x,  u8 y, 二维数组形参,u8 num, u8  size)
{
       LCD_show_CH_WORD(x+Index, y, 二维数组形参,size);  // 调用单个汉字一维数组的函数包。
       Index=Index+size+12;   // Index可控制间距  

}
这个二维数组形参这里怎么表示>
回复 支持 反对

使用道具 举报

21

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2014-3-12
在线时间
3 小时
 楼主| 发表于 2014-4-17 16:22:18 | 显示全部楼层

感谢大家的提点,虽然有些进展,有些头绪了,但还碰到了新的问题,现在主要想攻克二维数组问题,从新发个贴。

回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-4-17 21:19:06 | 显示全部楼层
回复【7楼】duanyuzhong:
---------------------------------
二维数组参数,貌似必须要确定一个维度,才可以。
楼主何不考虑下用结构体传输?
比如:
struct
{
u8 *p1;
u8 *p2;
u8 size1;
u8 size2;
}__ziku;

这样p1,p2,分别指向你二维数组的2个维度,size可以定义p1,p2的大小。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

21

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2014-3-12
在线时间
3 小时
 楼主| 发表于 2014-4-19 11:04:16 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
恩,看来这是个方法,试验中,一下子没弄出来。占时先放一下了。非常感谢!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-5-8
在线时间
0 小时
发表于 2016-5-8 13:30:40 | 显示全部楼层
你好,楼主,我想问一下你取模用的软件还有具体的设置可以吗?我取出来的模显示都是不一样的,麻烦了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 12:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表