CC2530使用OLED實現自動換行垂直滾動顯示

實驗平臺:CC2350
屏幕參數:128*64
驅動芯片: SSD1306

使用OLED時,想要重定向piintf輸出到OLED屏幕上,並實現橫向128列輸出完畢後或者遇到 ‘\n’ 時自動換行顯示,並且將已輸入內容向上移動一行,類似win的命令行窗口。實現的主要思路爲SSD1306的設置顯示偏移量( Set Display Offset (D3h) )

Set Display Offset (D3h)
This is a double byte command. The second command specifies the mapping of the display start line to one of COM0~COM63 (assuming that COM0 is the display start line then the display start line register is equal to 0).
For example, to move the COM16 towards the COM0 direction by 16 lines the 6-bit data in the second byte should be given as 010000b. To move in the opposite direction by 16 lines the 6-bit data should be given by 64 – 16, so the second byte would be 100000b. The following two tables (Table 10-1, Table 10-2) show the example of setting the command C0h/C8h and D3h.

SSD1306數據手冊中設置偏移量的效果圖
基於這種辦法,我們只要將偏移量移動字體的高度值,然後清空移動後行,指定新的輸入點即可,比如我使用8*16的字體,那麼我只要將偏移地址移動16即可,即從COM0移動到COM16,數值爲從0x40到0x50。下面是我的實現辦法,代碼的適應性爲0,後續繼續改進。

  1. 實現偏移
uint8 OLED_VerticalScrolling(uint8 addr)
{
  //使用8*16字體
  if(addr >= 0x40 && addr < 0x50){  //第一行
    addr = 0x50; //切換到第二行開始
  }
  else if(addr >= 0x50 && addr < 0x60)//第二行
  {
    addr = 0x60; //切換到第三行開始
  }
  else if(addr >= 0x60 && addr < 0x70)//第三行
  {
    addr = 0x70; //切換到第四行開始
  }
  else{                                 //第四行
    addr = 0x40; //切換到第一行開始
  }
  OLED_WR_Byte(0xD3,OLED_CMD);        //設置起始位
  OLED_WR_Byte(addr,OLED_CMD);        //起始位移動16位
    
  return addr;
}
  1. 實現清空移動後的行
void OLED_ClearForPrintf(uint8 addr)
{
    unsigned char y,x; 
    unsigned char i,j;
    
  //使用8*16字體
  if(addr >= 0x40 && addr < 0x50){  //第一行
	i = 0;
	j =3;   
  }
  else if(addr >= 0x50 && addr < 0x60)//第二行
  {
	i = 2;
	j =4;    
  }
  else if(addr >= 0x60 && addr < 0x70)//第三行
  {
	i = 4;
	j =6;   
  }
  else{//第四行
  	i = 6;
	j =8; 
  }
  for(y=i;y<j;y++)
    {
        LCD_WrCmd(0xb0+y);
        LCD_WrCmd(0x01);
        LCD_WrCmd(0x10); 
        for(x=0;x<X_WIDTH;x++)
            LCD_WrDat(0);
    }    
}
  1. 重定向printf
__near_func int putchar(int c)//printf輸出重定向
{
    static uint8_t x = 0, y = 0,state = 0;
    static uint8_t addr_next = 0x40;//默認第一行開始移動
    static uint8_t addr_now;
      
    if((x + 8 > 128) || c == '\n')    //換行 
    { 
      x = 0; 
      if(state ==1)
      {
        
          OLED_ClearForPrintf(addr_next);            //清除顯示的最後一行
          addr_now = addr_next;                     //清除後成爲當前編輯行
          addr_next = OLED_VerticalScrolling(addr_now); //垂直滾動2頁,返回顯示的最後一行的地址

          
          //使用8*16字體
          if(addr_now >= 0x40 && addr_now < 0x50){  //第一行
            y=0;
          }
          else if(addr_now >= 0x50 && addr_now < 0x60)//第二行
          {
            y=2;
          }
          else if(addr_now >= 0x60 && addr_now < 0x70)//第三行
          {
            y=4;
          }
          else{                                 //第四行
            y=6;
          }
        return c; 
      }
      else {
        y += 2;
        if(y > 4 ) 
          state = 1;
        return c;
      }
    }
    
    OLED_ShowChar(x, y, (uint8_t)c ,16);         //打印字符ch 
    x += 8;                                      //跳轉到下一個位置, 是否越界有上面函數判斷
    return c; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章