2018年3月6日 星期二

用 Arduino MEGA 2560 SPI 介面和內含中英文字庫的 1.3吋 12864 點陣型 OLED 顯示器模組 (二)


本文主要介紹如何用內建中英文字型IC的 1.3吋 OLED 顯示器模組在 U8G2 繪圖函式庫顯示中英文字型。

Arduino Mega 2560 或 UNO,由於程式記憶體太小,因此無法放入BIG5繁體或GB2312簡體中文字型檔,因此我們用內建中英文字型IC的 OLED 顯示模組在U8G2繪圖函式庫來顯示中文字型。

我們所使用的內含中英文字型 IC 1.3吋 12864 點陣型 OLED 顯示器模組如下

https://seller.shopee.tw/portal/product/928548884
http://goods.ruten.com.tw/item/show?21808691338964.

硬體的連接方式如下:
Arduino MEGA 2560 到 OLED 顯示器模組

Arduino MEGA 2560   OLED 模組(含內建中英文字型)
46                                  CS2 (字型檔晶片選擇)              
47                                
48                                  CS1  (SH1106 晶片選擇)              
49                                  DC   (資料/命令設定)                    
50 MISO                       FSO (字型IC資料輸出)                  
51 MOSI                       MOSI (輸出資料到LCD/字型IC)    
52 SCK                          CLK                                                
53 SS                              ------                                                
3.3V                               3.3V                                                   
GND                              GND                                                

我們會在 OLED 屏上顯示以下的中英文字串。

uint8_t   TeststringGB231216by16[] = {'H','i','!',0xDC,0xBF,0xCD,0xA5,0xCA,0xF7,0xB9,0xA4,0xD7,0xF7,0xCA,0xD2,0};  // 芸(DCBF),"Hi!芸庭樹工作室"



內建中英文字型 IC 編號是 GT20L16S1Y (http://www.genitop.com/admin/upload/20150511105751675.pdf) 內建的中文是簡體中文 (GB2312)

由於 U8G2 的顯示方式和中文字型點陣資料不一樣,因此在讀取中英文字型 IC 的資料後,要先經過點陣資料轉換,才可使用 u8g2.drawXBM 的功能。

基本的程式如下。


void convert8by16FontBitMapforU8G2XBM(uint8_t *pfont)
{
  uint8_t i,j,k,*pfont1,tempbuffer[16], *pfont2, *pfontbase;
  uint8_t data,mask;

  pfont1 = pfont;     // the last byte for Chinese font bitmap
  pfont2 = &tempbuffer[0];
  for(i=0;i<16;i++)
  {
    *pfont2++ = *pfont1++;
  }

  pfont2 = pfont;
  pfontbase = &tempbuffer[0];
  for(k=0;k<2;k++,pfontbase+=8) {
    //Serial.print("k="); Serial.print(k,HEX); Serial.println(' ');
    mask=0x01;
    for(i=0; i<8; i++,mask<<=1) {
      for(j=0,data=0,pfont1=pfontbase; j<8; j++) {
        data >>= 1;
        if (*pfont1++ & mask)
          data |= 0x80; //0x8000;
      }
      *pfont2++ = data;
    }
  }
}

void convert16by16FontBitMapforU8G2XBM(uint8_t *pfont)
{
  uint8_t i,j,k,*pfont1,tempbuffer[32], *pfont2, *pfontbase, mask;
  uint16_t data;

  pfont1 = pfont;     // the last byte for Chinese font bitmap
  pfont2 = &tempbuffer[0];
  for(i=0;i<32;i++) {
    *pfont2++ = *pfont1++;
  }

  pfont2 = pfont;
  pfontbase = &tempbuffer[0];
  for(k=0; k<2; k++,pfontbase+=16) {
    for(i=0,mask=0x1,pfont1=pfontbase; i<8; i++,mask<<=1) {
      for(j=0,data=0,pfont1=pfontbase; j<16; j++) {    
          data >>= 1;
          if (*pfont1++ & mask)
            data |= 0x8000;    
      }
      *pfont2 = data & 0xff;
      *(pfont2+1) = ((data & 0xff00)>>8);
      pfont2 += 2;
    }
  }
}

void drawFontIC(uint8_t x, uint8_t y, uint8_t *pCodeString)
{

  while(*pCodeString) {
      fontIC.getFontBitMap(pCodeString,&FontBuffer[0]);
      if (*pCodeString > 127) {
        convert16by16FontBitMapforU8G2XBM(&FontBuffer[0]);  
        u8g2.drawXBM(x,y,16,16,&FontBuffer[0]);
        pCodeString += 2;
        x += 16;
      } else {
         convert8by16FontBitMapforU8G2XBM(&FontBuffer[0]);
         u8g2.drawXBM(x,y,8,16,&FontBuffer[0]);
         pCodeString++;
         x += 8;
      }  
  }
}

void setup(void) {
  Serial.begin(115200);
  pinMode(SPI_CS2,OUTPUT);
  digitalWrite(SPI_CS2,HIGH);
  pinMode(SPI_FSO,INPUT);
  u8g2.begin();
}

void loop(void) {

  u8g2.firstPage();
  do {
 
    u8g2.drawFrame(0,0,127,63);          
 
    drawFontIC(3,3,&TeststringGB231216by16[0]);

    u8g2.setFont(u8g2_font_t0_11_tf);
    u8g2.drawStr(20,32,"Font IC Test OK");

    u8g2.drawTriangle(20,38,5,56,35,56);
    u8g2.drawCircle(64,48,10,U8G2_DRAW_ALL);  
    u8g2.drawFilledEllipse(100,50,15,5,U8G2_DRAW_ALL);
    Serial.print(F("\r\n\r\n\r\n"));
  } while ( u8g2.nextPage() );
  delay(2000);
  while(1);
}

沒有留言:

張貼留言