找回密码
 立即注册
查看: 641|回复: 2

修改OLED驱动在任意位置显示12x12汉字和字符

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2025-02-28 16:59:12

5

主题

26

回帖

267

积分

中级会员

积分
267
发表于 2024-8-7 00:02:13 | 显示全部楼层 |阅读模式
最近想做个小玩意,用一块128X64OLED碰到个问题,要显示的内容多了点,OLED用16*16的字符显示不完,用8*8的字符显示汉字又看不清,OLED按页操作的特性有时侯还真不方便,比如说我现在就想把字体改小点,改成12X12的,既兼顾显示效果,又可以多显示点内容,问题就来了,即便我改了字体为12X12,显示内容还是只能显视4行,按理说Y方向64个像素显示5行12X12的文字那是还有富余的,问题就出在OLED按页操作上,OLED的Y方向分为8个区域,每个区域8X128像素,X方向可以在任意位置写入,Y方向只能按行写入,一行8个像素,每次写入只能从每一页的第一行写入,这就造成了12X12的字体也只能显示4行.本着能拿来就绝不动手的原则,网上搜了一通,啥都没找到,按理说我这也不算特殊需求吧,后来上来STC论坛找了一圈,发现了一个贴子"STC32G驱动OLED12864,SPI或I2C两种方式"https://www.stcaimcu.com/forum.php?mod=viewthread&tid=2592&highlight=oled&page=1&extra=#pid17762,驱动方式跟老刘示波器的差不多,但文字显示还是按页显示,没办法了,只能自已动脑了,思路很简单,参考TFT的显示方式,以点的方式驱动,需要的地方点亮,不需要的地方关掉,刚好这个贴子里有任意位置画点的函数,直接上函数:



/*新增任意位置显示字符和汉字*/
void OLED_BuffWritPoint(unsigned char x,unsigned char y,bit mode)                //OLED标记一个点,0写入,1清除
{
  if(mode)  
                ShowBUFF[y/8][x] &= ~(1<<(y%8));
        else
                ShowBUFF[y/8][x] |= 1<<(y%8);
}

void OLED_ShowChinese(u8 x,u8 y,char *gbk,bit mode)     //OLED任意位置显示12*12汉字
{
    unsigned char i;
    unsigned char j,k;
                u8 p;
       
    for( i=0;i<200;i++ )
    {
        if(( gbk[0]== GBK12.gbn_bum12[0] )&&( gbk[1]== GBK12.gbn_bum12[1] ))
        {
            for( j=0;j<12;j++ )
            {
                                                                p = GBK12.gbk_font12[j];
       
                for( k=0;k<8;k++ )
                {                    
                                                                        if(p & (0x01 << k))
                                                                                OLED_BuffWritPoint(x+j,y+k,mode);
                                                                        else
                                                                                OLED_BuffWritPoint(x+j,y+k,!mode);
                }
           }
                                                for( j=0;j<12;j++ )
            {
                                                                p = GBK12.gbk_font12[j+12];
                for( k=0;k<4;k++ )
                {                    
                                                                        if(p & (0x01 << k))
                                                                                OLED_BuffWritPoint(x+j,y+8+k,mode);
                                                                        else
                                                                                OLED_BuffWritPoint(x+j,y+8+k,!mode);
               }
            }
            break;
        }
    }   
}


取模方式请参考原文,测试一下显示正常,这个应该能愉快的做界面了吧,没想到我忘记写12号字体的字符函数了,没办法,继续烧脑


void OLED_ShowChar(unsigned char x,unsigned char y,char asc, bit mode)     //OLED显示一个6*12字符
{
    unsigned char j,k;
                u8 p;
       
    for( j=0;j<6;j++ )
    {
                                p = Ascll_12[(asc-' ')][j];
        for( k=0;k<8;k++ )
        {
            if(p & (0x01 << k))            
               OLED_BuffWritPoint(x+j,y+k,mode);
                                                else
                                                        OLED_BuffWritPoint(x+j,y+k,!mode);
        }
    }
                for( j=0;j<6;j++ )
    {
                                p = Ascll_12[(asc-' ')][j+6];
        for( k=0;k<4;k++ )
        {
            if(p & (0x01 << k))            
               OLED_BuffWritPoint(x+j,y+8+k,mode);
                                                else
                                                        OLED_BuffWritPoint(x+j,y+8+k,!mode);
        }
    }
}


字体数组定义如下:
const char code Ascll_12[][12]=



struct s_font12
{
    unsigned char gbk_font12[24];
    unsigned char gbn_bum12[2];
};

const  struct s_font12 code GBK12[]=       


程序比较乱,我就不贴上来了.
IMG_20240806_225429.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:21
  • 最近打卡:2025-04-04 22:11:37
已绑定手机

36

主题

287

回帖

824

积分

高级会员

积分
824
发表于 2024-8-13 15:59:30 来自手机 | 显示全部楼层
可以折中一下,开个小缓冲再刷屏
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:54
  • 最近打卡:2025-05-01 09:07:55

717

主题

1万

回帖

1万

积分

管理员

积分
15613
发表于 2024-8-14 14:19:58 | 显示全部楼层
128*64 = 128*8*8=1024*8
开个 1024字节的DMA缓存区, DMA-SPI去自动刷屏

让 CPU 去忙其他的事
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:10 , Processed in 0.127126 second(s), 62 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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