wskhsm 发表于 2024-8-7 00:02:13

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

最近想做个小玩意,用一块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 &= ~(1<<(y%8));
        else
                ShowBUFF |= 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== GBK12.gbn_bum12 )&&( gbk== GBK12.gbn_bum12 ))
      {
            for( j=0;j<12;j++ )
            {
                                                                p = GBK12.gbk_font12;
       
                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;
                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-' ')];
      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-' ')];
      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[]=



struct s_font12
{
    unsigned char gbk_font12;
    unsigned char gbn_bum12;
};

conststruct s_font12 code GBK12[]=       


程序比较乱,我就不贴上来了.

_NCY_ 发表于 2024-8-13 15:59:30

可以折中一下,开个小缓冲再刷屏

神农鼎 发表于 2024-8-14 14:19:58

128*64 = 128*8*8=1024*8
开个 1024字节的DMA缓存区, DMA-SPI去自动刷屏
让 CPU 去忙其他的事
页: [1]
查看完整版本: 修改OLED驱动在任意位置显示12x12汉字和字符