找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3895|回复: 5
收起左侧

显示透明背景字符在单片机上咋弄? 俺来支招。

[复制链接]
ID:12202 发表于 2017-8-29 12:58 | 显示全部楼层 |阅读模式
       地球上的爱好者或没有留意,若在已有的界面上叠加透明背景字,不大影响界面表现,但却美美地新增了文字信息,似乎平添了一“显示域”。但是流行字符显示方法却硬要把背景与字迹一同写出,出字就见方疤,放哪哪不爽。以俺《触摸屏》贴为例,空心透明的键控符号很大方,杵那都不讨嫌,明示却不妨图,可谓亲和也。
招式描述:
1、其实忒简单,也非俺发明,竟然就是LCD都支持的“直接写点”法,属于捡来的应用招式(习惯性的口出“招式”、“命门”之类,都怪金庸侠文给闹的)。
及有字迹的地方就写点,没有就不写,于是立马透明”了。可恨的是,所有LCD都笨笨的沿用写点自动递增屏点地址的搞法,不写他就不走,所以才不     成。
2、这要用到所有LCD屏都支持的的定位指令,如例程片段里的“  {LCD_SetDispAddr(x1,y1); LLCD_WRITE_DATA(color); y1++;} “。  然后不论写点与否都递增地址,这样行了。
3、靠谱的办法是把字库和图库放到SD卡或flash里。单片机的容量空间实在太金贵,STC单片机的容量最大的也只64K字节,俺用的单幅图片就要150K字节,那够消费呢? 好在STC的SPI接口与SD卡和flash都可直连,不要任何外围电路,忒方便。
4、”写点法“意外派生了新的名堂,及错位双写就有了立体字的效果。俺还利用错位双写异色透明图标的办法有效防止了同色背景淹没图标的现象。
5、动态显示透明字时会出现讨厌的字迹存留现象,需要背景整屏或局部刷新。此时正规的高端方法显得有用了,高端的方法是读出将被覆盖的图形显存内容,依序分别保存原始与最新图形内容备用,加入字库数据异或运算处理,然后回写之。得失轻重各有分说。


IMG_20170828_141829.jpg



IMG_20170828_141919.jpg



IMG_20170828_142025.jpg



IMG_20170828_142057.jpg



代码片段鉴赏:
//==================本地字库  16x24  写点成字=============================================
void LCD_X_HZ1624(unsigned char x, unsigned char y, unsigned int color,unsigned char const *lcdHZ)
{
    u8 k,x1=x,y1=y,CharCode,Cnt;
    for (k=0;k<48;k++){ CharCode = *lcdHZ;   
       for(Cnt=0;Cnt<8;Cnt++) {
            if((CharCode&0x80)==0x80){LCD_SetDispAddr(x1,y1); LLCD_WRITE_DATA(color); y1++;}
      else {y1++;}      
       if((y1-y)>15){x1++;y1=y;}  CharCode<<=1;}
         *lcdHZ++;      }                        
}            

//========SD字库 51x80  逐点写屏,透明背景(每字占512字节)======================
void LCD_X_ZF5180(u16 x, u16 y,u16 color,u32 add)
{
     u16 x1=x,y1=y;   u8 CharCode,Cnt;
     u16 temp,d=508;                             //每字符508字节。
   u8 table[]={0x51,0x00,0x00,0x00,0x00,0xff}; //写入读页命令帧CMD17
     add=add*512;
        table[1]=((add&0xff000000)>>24);         //填入地址
      table[2]=((add&0x00ff0000)>>16);
      table[3]=((add&0x0000ff00)>>8);
      table[4]=add;     
           SPI_SD_CS =0;                     
    do{ temp=write_cmd(table); }while(temp!=0);
     SPI_SendByte(0xff);
     while(SPI_SendByte(0xff)!=0xfe);            
       while(d--)                                //读SD卡直接写dX8个点
     {
             CharCode = SPI_SendByte(0xff);
          for(Cnt=0;Cnt<8;Cnt++) {
            if((CharCode&0x80)==0x80){LCD_SetDispAddr(x1,y1); LLCD_WRITE_DATA(color); y1++;}
        else {y1++;}      
          if((y1-y)>79){x1++;y1=y;}  CharCode<<=1;
                                   }
         }      
     SPI_SendByte(0xff);                      //空读校验码约定动作
     SPI_SendByte(0xff);
     SPI_SD_CS =1;
     SPI_SendByte(0xff);
}        

//=============读SD图形库直接写屏(每幅150K字节)============================
//-----------     LCD_WRITE_DATA(SPI_SendByte为写屏命令----------------------------------------------
//-----------     SPI_SendByte 为两用SD卡写读命令------------------------------------------------------------
void SD_TX_ALL(u32 add)
  {  
      u16 temp,c=300,d;                           //每幅图占150.36K字节,合300页。
      u8 table[]={0x51,0x00,0x00,0x00,0x00,0xff}; //写入读页命令帧CMD17  
      add=add*512;                    
      adderset(0,239,0,319);                                   //开窗  
   while(c--){         
        table[1]=((add&0xff000000)>>24);              //填入地址   
        table[2]=((add&0x00ff0000)>>16);
        table[3]=((add&0x0000ff00)>>8);     
        table[4]=add;     
            add=add+512;                                       //页递增   
     SPI_SD_CS =0;                     
    do{ temp=write_cmd(table); }while(temp!=0);     SPI_SendByte(0xff);
     while(SPI_SendByte(0xff)!=0xfe);          d=256;                                 //每次两字节搞256次为一页
     while(d--)                                                                                            //读SD卡直接写屏  
         { LCD_WRITE_DATA(SPI_SendByte(0xff),SPI_SendByte(0xff)); }
     SPI_SendByte(0xff);                                                                         //空读校验码约定动作   
     SPI_SendByte(0xff);
     SPI_SD_CS =1;     
     SPI_SendByte(0xff);
                }   
}

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:149799 发表于 2023-3-12 20:59 | 显示全部楼层
这样做确实美观,又增加了功能,谢谢分享经验。
回复

使用道具 举报

ID:777208 发表于 2023-3-12 17:00 | 显示全部楼层
请教一下,LCD_SetDispAddr(x1,y1)函数内容是什么?
回复

使用道具 举报

ID:777208 发表于 2023-3-12 16:02 | 显示全部楼层
我想显示一个透明无背景的进度条图标怎么实现呀?
回复

使用道具 举报

ID:517951 发表于 2021-7-30 08:54 | 显示全部楼层
AT89C52 肯定干不了,速度太慢。 STM32F10x系列72Mhz的LCD总线连接+DMA方式应该可以
回复

使用道具 举报

ID:507641 发表于 2021-7-29 12:11 | 显示全部楼层
初学,还没看懂多看看呗,有原型更直接,51也能实现吧?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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