发新帖本帖赏金 0.10元(功能说明)我要提问
返回列表
打印
[STM32]

T6963C 240*128如何显示9行汉字

[复制链接]
1709|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
LcwSwust| | 2020-6-10 15:21 | 只看该作者
https://bbs.21ic.com/icview-1008978-1-1.html
其实,先写一个在任意位置显示任意大小的图片的函数,然后把汉字当成图片来显示就行了。

使用特权

评论回复
板凳
Cjy_JDxy|  楼主 | 2020-6-10 16:52 | 只看该作者
LcwSwust 发表于 2020-6-10 15:21
https://bbs.21ic.com/icview-1008978-1-1.html
其实,先写一个在任意位置显示任意大小的图片的函数,然后 ...


谢谢!现在可以显示9行了。但是每个汉字横向距离太远,有什么办法让它们近一些,可以每行多显示几个汉字。

使用特权

评论回复
地板
LcwSwust| | 2020-6-10 17:00 | 只看该作者
Cjy_JDxy 发表于 2020-6-10 16:52
谢谢!现在可以显示9行了。但是每个汉字横向距离太远,有什么办法让它们近一些,可以每行多显示几个汉字 ...

这算问题吗?我不能理解。

使用特权

评论回复
5
Cjy_JDxy|  楼主 | 2020-6-10 17:31 | 只看该作者
LcwSwust 发表于 2020-6-10 17:00
这算问题吗?我不能理解。


你看这个图,破型起限那一行显示不开,不好看。

使用特权

评论回复
6
LcwSwust| | 2020-6-10 21:34 | 只看该作者
Cjy_JDxy 发表于 2020-6-10 17:31
你看这个图,破型起限那一行显示不开,不好看。

显示文字的X座标是怎么控制的?

使用特权

评论回复
7
ningling_21| | 2020-6-10 21:41 | 只看该作者
Cjy_JDxy 发表于 2020-6-10 16:52
谢谢!现在可以显示9行了。但是每个汉字横向距离太远,有什么办法让它们近一些,可以每行多显示几个汉字 ...

控制汉字的起始左标

使用特权

评论回复
8
Cjy_JDxy|  楼主 | 2020-6-11 07:54 | 只看该作者
LcwSwust 发表于 2020-6-10 21:34
显示文字的X座标是怎么控制的?

第一个字X 0
第二个字X 2

使用特权

评论回复
9
LcwSwust| | 2020-6-11 08:21 | 只看该作者
Cjy_JDxy 发表于 2020-6-11 07:54
第一个字X 0
第二个字X 2

哦,不是图形模式啊,那我就不知道了。
我的习惯是在图形模式下把文字当图片处理,想显示到哪里就显示到哪里。

使用特权

评论回复
10
Cjy_JDxy|  楼主 | 2020-6-11 08:33 | 只看该作者
LcwSwust 发表于 2020-6-11 08:21
哦,不是图形模式啊,那我就不知道了。
我的习惯是在图形模式下把文字当图片处理,想显示到哪里就显示到 ...

是在图形模式。搞不清楚你怎么当图片处理,字模是一个一个的。你能给个例子吗?谢谢

使用特权

评论回复
11
LcwSwust| | 2020-6-11 10:00 | 只看该作者
Cjy_JDxy 发表于 2020-6-11 08:33
是在图形模式。搞不清楚你怎么当图片处理,字模是一个一个的。你能给个例子吗?谢谢 ...

若是16*16点的汉字,x座标在显示一个汉字之后应该是加16,不知你用多大的字?x加的多少?
我的思路一般是在内存中绘图然后整体刷新到显示屏。
绘图函数:
//-------------------------------------------------------
//绘图
//x,y为座标,w为宽度,h为高度,buf为数据
//m 为模式:B0:0正常,1取反,B2&B1:00正常,01:OR,10:AND,11:XOR
//-------------------------------------------------------
void GUI_DrawPic(S16 x0,S16 y0,S16 w,S16 h,U8 m,U8* buf)
{
        S16 x,y,bs,px=0,dx=0,dw,m1,n=0;
        U16 temp;
        U16 ps;
        dw=(w+7)>>3;//图像数组横向占用的字节数
        //一个横向16位里可能有3个字节
        px=x0&0x07;//x方向的偏移(余数)
        bs=px;//起始位
        m1=(m>>1)&0x03;//模式
        for(x=x0;(x<x0+w)&&(x<LCD_WIDTH);x++)
        {
                n++;//显示点数统计
                if(((x&0x07)==0x07)||((x+1)==(x0+w)||((x+1)==LCD_WIDTH)))//横向8位
                {
                        for(y=y0;(y<y0+h)&&(y<LCD_HEIGHT);y++)
                        {
                                ps=y-y0;
                                ps=ps*dw+dx;//数组中的位置
                                temp=((U16)buf[ps-1]<<8)|buf[ps];//连续取两个字节
                                if(m&BIT(0))temp=~temp;//数据取反
                                //temp=(temp>>px)&((0xff<<(8-n))>>bs);//从bs位开始取n个位
                                temp=(temp>>px)&((U8)(0xff<<(8-n))>>bs);
                                //---------------------------对绘图模式的处理->
                                if((n<8)||(m>0))//小于8位,或在非正常模式,需要读出原位置的数据来处理
                                        ps=GUI_Buf_Read(x>>3,y);//LCD_Read16(x>>4,y);
                                if(m1==0)//正常
                                {
                                        if(n<8)
                                        {
                                                temp=ps&(~((U8)(0xff<<(8-n))>>bs))|temp;
                                                //将读出的数从bs位开始n个位清0,再或上temp
                                        }
                                }
                                else if(m1==1)//OR
                                {
                                        temp|=ps;
                                }
                                else if(m1==2)//AND
                                {
                                        temp&=ps;
                                }
                                else if(m1==3)//XOR
                                {
                                        temp^=ps;
                                }
                                //---------------------------对绘图模式的处理<-
                                GUI_Buf_Write(x>>3,y,temp);                                
                        }
                        dx++;//数组指向下一个
                        if(n>8)dx++;//数据位多于8个,就要再向下移一个字节
                        px&=0x07;//偏移没那么多了
                        n=0;//数据位清0
                        bs=0;//之后的起始位就为0了
                }
        }
}


显示汉字:
//--------------------------------------------------
//                显示一个字
//--------------------------------------------------
void GUI_PutChar(U16 asc)
{
        U8 w,h,i;
        U16 id;
        U8* p;
        if(asc>0xA0A0)//汉字,16*16
        {
                for(i=0;i<ARRLEN(CH16x16_tab);i++)//
                {
                        id=MAKE16(CH16x16_tab[i].id[0],CH16x16_tab[i].id[1]);
                        if(asc==id)
                        {
                                w=pGUIFont->Width*2;//两个字符宽
                                h=pGUIFont->Height;        
                                p=CH16x16_tab[i].buf;//字库
                                GUI_DrawPic(GUI_Px,GUI_Py,w,h,GUIFont_Dm,p);//画图
                                break;
                        }
                }
                GUI_Px+=w;
        }
        else//英文
        {
                if(asc < pGUIFont->AscFirst)return;
                if(asc > pGUIFont->AscLast)return;
                w=pGUIFont->Width;
                h=pGUIFont->Height;        
                p=pGUIFont->lib;
                p+=(asc-pGUIFont->AscFirst)* pGUIFont->BPL * pGUIFont->Height;//找到字母所在的地址
                GUI_DrawPic(GUI_Px,GUI_Py,w,h,GUIFont_Dm,p);
                GUI_Px+=pGUIFont->Width;
        }
}

使用特权

评论回复
12
Cjy_JDxy|  楼主 | 2020-6-11 10:08 | 只看该作者
LcwSwust 发表于 2020-6-11 10:00
若是16*16点的汉字,x座标在显示一个汉字之后应该是加16,不知你用多大的字?x加的多少?
我的思路一般是 ...

我用的12*12的x+2

使用特权

评论回复
13
LcwSwust| | 2020-6-11 10:10 | 只看该作者
本帖最后由 LcwSwust 于 2020-6-11 10:11 编辑

你的x坐标不对应像素点?真奇怪,那么如果想在任意指定位置画一个点怎么办呢?
看来需要横向移位处理了,先在内存中处理好再输出到显示屏。

使用特权

评论回复
14
LcwSwust| | 2020-6-11 10:26 | 只看该作者
先前11楼的代码应该是纵向8点的屏,
这里还有个横向16点的屏的程序,参考一下:

//-------------------------------------------------------
//        写16位图形数据,将原座标系:x(0~15),y(0~31)变换为x(0~7),y(0~63)
//mode为绘图模式:0:正常,1:或,2:与,3:取反
//-------------------------------------------------------
void LCD_Write16(U8 x,U8 y,U16 d,U8 mode)
{
        idata U16 temp;
        if(x>7)return;
        if(y>63)return;
        if(y>31){y-=32;x+=8;}
        LCD_W_Cmd(BIT(7)+y);//x
        LCD_W_Cmd(BIT(7)+x);//y       
        if(mode)
        {
                LCD_R_Dat();
                temp=LCD_R_Dat();
                temp=(temp<<8)|LCD_R_Dat();//读出数据
                LCD_W_Cmd(BIT(7)+y);//x
                LCD_W_Cmd(BIT(7)+x);//y        //读取参数过后地址会改变,需重新设置地址
                if(mode==1)//or
                        d|=temp;
                else if(mode==2)//and
                        d&=temp;
                else if(mode==3)//xor
                        d^=temp;
        }
        LCD_W_Dat(d>>8);
        LCD_W_Dat(d);
}
//-------------------------------------------------------
//        读16位图形数据,将原座标系:x(0~15),y(0~31)变换为x(0~7),y(0~63)
//-------------------------------------------------------
U16 LCD_Read16(U8 x,U8 y)
{
        idata U16 d=0;
        if(x>7)return 0;
        if(y>63)return 0;
        if(y>31){y-=32;x+=8;}
        LCD_W_Cmd(BIT(7)+y);//x
        LCD_W_Cmd(BIT(7)+x);//y       
        LCD_R_Dat();
        d=LCD_R_Dat();
        d=(d<<8)|LCD_R_Dat();//读出数据
        return d;       
}
//-------------------------------------------------------
//绘图
//x,y为座标,w为宽度,h为高度,d为数据
//m 为模式:B0:0正常,1取反,B2&B1:00正常,01:OR,10:AND,11:XOR
//-------------------------------------------------------
void LCD_DrawPic(U8 x0,U8 y0,U8 w,U8 h,U8 m,U8* d)
{
        idata U8 x,y,bs,px=0,dx=0,dw,m1,n=0;
        idata U32 temp;
        idata U16 ps;
        dw=(w+7)>>3;//数组横向字节数
        //一个横向16位里可能有3个字节
        px=x0&0x0f;//x方向的偏移(余数)
        bs=px;//起始位
        m1=(m>>1)&0x03;
        for(x=x0;(x<x0+w)&&(x<128);x++)
        {
                n++;
                if(((x&0x0f)==0x0f)||((x+1)==(x0+w)||((x+1)==128)))//横向16位
                {
                        for(y=y0;(y<y0+h)&&(y<64);y++)
                        {
                                ps=y-y0;
                                ps=ps*dw+dx;//数组中的位置
                                temp=((U32)d[ps-1]<<16)|((U16)d[ps]<<8)|d[ps+1];//连续取三个字节
                                if(m&BIT(0))temp=~temp;//数据取反
                                temp=(temp>>px)&((0xffff<<(16-n))>>bs);//从bs位开始取n个位
                                //---------------------------对绘图模式的处理->
                                if((n<16)||(m>0))//小于16位,或在非正常模式,需要读出原位置的数据来处理
                                        ps=LCD_Read16(x>>4,y);
                                if(m1==0)//正常
                                {
                                        if(n<16)
                                        {
                                                temp=ps&(~((0xffff<<(16-n))>>bs))|temp;//ps|((0xffff<<(16-n))>>bs)&temp;
                                                //将读出的数从bs位开始n个位清0,再或上temp
                                        }
                                }
                                else if(m1==1)//OR
                                {
                                        temp|=ps;
                                }
                                else if(m1==2)//AND
                                {
                                        temp&=ps;
                                }
                                else if(m1==3)//XOR
                                {
                                        temp^=ps;
                                }
                                //---------------------------对绘图模式的处理<-
                                LCD_Write16(x>>4,y,temp,0);
                        }
                        dx++;//数组指向下一个
                        if(n>8)dx++;//数据位多于8个,就要再向下移一个字节
                        px&=0x07;//偏移没那么多了
                        n=0;//数据位清0
                        bs=0;//之后的起始位就为0了
                }
        }
}

使用特权

评论回复

打赏榜单

Cjy_JDxy 打赏了 0.10 元 2020-06-11
理由:很给力

15
LcwSwust| | 2020-6-11 13:49 | 只看该作者
程序写太多没注意,11楼的绘图函数其实和14楼一样,是横向16位的,以前用过一个型号是HJ12864,
纵向8位的屏是JLX12864,习惯是定义一个与屏大小相同的数组,绘图在数组中处理,然后整体刷新,代码:
//-------------------------------------------------------
//绘图
//x,y为座标,w为宽度,h为高度,d为数据
//m 为模式:B0:0正常,1取反,B2&B1:00正常,01:OR,10:AND,11:XOR
//-------------------------------------------------------
void LCD_DrawPic(S16 x0,S16 y0,S16 w,S16 h,U8 m,U8* d)
{
        idata S16 x,y,y1;
        idata U8 bs,py,n,dh;
        idata U8 temp,bitmask;
        idata U16 ps;//数组中的位置
        //-----------------计算y循环次数
        if(h==0)return;
        if(w==0)return;
        dh=((y0+h-1)>>3)-(y0>>3)+1;//dh=((y0+h-1)>>3)-(y0>>3)+1;               
        py=y0&0x07;        //y方向偏移(取数据时用)
        y1=y0>>3;//y1=y0>>3;        //Y启始位置
        bs=py;                //第一行起始位
        n=8-bs;                //第一行数据位数

        for(y=y1;(y<y1+dh)&&(y<LCD_HEIGHT);y++)//纵向dh次循环
        {                       
                if(y>=y1+dh-1)//最后一行
                {
                        if((h+y0)&0x07)
                                n=n-(8-((h+y0)&0x07));//减去下方空余
                }
                bitmask=0xff>>(8-n)<<bs;//从bs开始取n个位
                for(x=x0;(x<x0+w)&&(x<LCD_WIDTH);x++)//横向绘图
                {                       
                        ps=(y-y1)*w+(x-x0);//ps*dh+dx;//数组中的位置
                        temp=(d[ps-w]>>(8-py))+(d[ps]<<py);//本行显示上行数据的高位和本行数据的低位
                        if(m&BIT(0))temp=~temp;//数据取反                       
                        temp=temp & bitmask;//从bs开始取n个位
                         //---------------------------对绘图模式的处理->
                        if((n<8)||(m>0))//小于8位,或在非正常模式,需要读出原位置的数据来处理
                                ps=lcd_buf_read(x,y);//读取液晶屏数据
                        switch(m&0x06)
                        {
                                case 0://正常
                                        if(n<8)
                                                temp=ps&(~bitmask)|temp;
                                        break;
                                case 2://OR
                                        temp|=ps;
                                        break;
                                case 4://AND
                                        temp=ps&(temp|~bitmask);//只对bitmask为1的位取与
                                        break;
                                case 6://XOR
                                        temp^=ps;
                                        break;
                        }
                        //---------------------------对绘图模式的处理<-
                        lcd_buf_write(x,y,temp);//LCD_Write16(x>>4,y,temp,0);
                }               
                n=8;//从第2行开始为8位数
                bs=0;//从第2行开始启始位为0
        }
}

使用特权

评论回复
16
wangshujun| | 2020-6-12 14:06 | 只看该作者
12点的字库会让显示速度慢不少,而且处理不好容易破坏显示的上下行,不到万不得已尽量别用12点阵字库吧,显示效果真的差不少,效率又低

使用特权

评论回复
17
cjseng| | 2020-6-12 19:39 | 只看该作者
把不需要改变的文字,统一做成一个图片,显示这个图片,然后在上面叠加文字

使用特权

评论回复
发新帖 本帖赏金 0.10元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3530

帖子

19

粉丝