OLED裸屏學習(2016.8.31)


Type:LQ12864

單點長寬:0.154mm

焊盤:22

電源類型:

VCC:C=circuit 表示電路的意思, 即接入電路的電壓

VDD:D=device 表示器件的意思, 即器件內部的工作電壓;

VSS:S=series 表示公共連接的意思,通常指電路公共接地端電壓

液晶裸片大同小異,本以為沒什么好研究的,但之前周楚侖大神發現了一個底層BUG,導致所有像素點均反向且不可逆,這讓我很疑惑,於是今天靜下心來看了下底層。

關於兩個基本函數;

void OLED_Write_Command(unsigned char Cmd);

void OLED_Write_Data(unsigned char Data);

基本上所有液晶底層函數均基於這兩個函數,所以先從這兩個函數入手看看代碼。

  • 首先先看一下四個管腳定義

OLED_SCL  或者  ODO        或者    CLK      //時鍾
OLED_SDA  或者  OD1      或者  MOSI   //數據
OLED_RST  或者  ORST_2  或者  CS    //復位
OLED_DC    或者  ODC_2    或者  DC   //數據/命令控制     (使能位)

  • 然后看數據寫入函數

void OLED_Write_Data(unsigned char Data)
{
  unsigned char Temp_i=8;
  OLED_DC=1;;
  OLED_SCL=0;
     while(Temp_i--)
   {
      if(Data&0x80){OLED_SDA=1;}
      else{OLED_SDA=0;}
      OLED_SCL=1;
      asm("nop");;
      asm("nop");;
      asm("nop");;
      OLED_SCL=0;;
      Data<<=1;
 }
大概是這樣,發現asm("nop");這個延時語句沒什么特別大的作用,刪掉。另外while語句由於我天生C語言缺陷看不懂,我只好改回for循環的格式。稍微改動如下(並不改動邏輯):

void OLED_Write_Data(unsigned char Data)
{

  unsigned char i;
  OLED_DC=1;
  for(i=0;i<8;i++)
  {
    if((Data << i) & 0x80)
    {OLED_SDA = 1;}
    else
    {OLED_SDA = 0;}
  OLED_SCL = 0;
  OLED_SCL = 1;

}

若改動SCL時鍾的語句,則產生花屏或者無法再寫入,改動DC使能語句,同樣花屏,但是略有不同。至於語句就很簡單了,自己看,乖。

  • 然后是命令寫入函數

同樣對該函數進行改寫

void OLED_Write_Command(unsigned char Cmd)
{
  unsigned char i;
  OLED_DC=0;
  for(i=0;i<8;i++)  
  {
    if((Cmd << i) & 0x80)
    {OLED_SDA = 1;}
    else
    {OLED_SDA = 0;}
  OLED_SCL = 0;
  OLED_SCL = 1;
  }
}

看起來除了DC=0以外和數據寫入函數沒有不同。

由此看來兩個最底層的函數都只是寫入一個數,但前者是用來點亮液晶,后者是用來配置寄存器(我猜的)。

  • 再來是初始化函數

void OLED_Init(void)
{
unsigned int Temp_Count;


gpio_init(PTC12,GPO,0); //OLED用IO口初始化為輸出
gpio_init(PTC14,GPO,0);
gpio_init(PTC17,GPO,0);
gpio_init(PTD0,GPO,0);

OLED_SCL=1;
OLED_RST=0;
for(Temp_Count=0;Temp_Count<50000;Temp_Count++);
OLED_RST=1;
//從上電到下面開始初始化要有足夠的時間,即等待RC復位完畢
OLED_Write_Command(0xAE|0x00); // Display Off (0x00/0x01)
OLED_Write_Command(0xD5);OLED_Write_Command(0x80); // Set Clock as 100 Frames/Sec
OLED_Write_Command(0xA8);OLED_Write_Command(0x3F); // 1/64 Duty (0x0F~0x3F)
OLED_Write_Command(0xD3);OLED_Write_Command(0x00); // Shift Mapping RAM Counter (0x00~0x3F)
OLED_Write_Command(0x40|0x00); // Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_Write_Command(0x8D);OLED_Write_Command(0x10|0x04); // Enable Embedded DC/DC Converter (0x00/0x04)
OLED_Write_Command(0x20);OLED_Write_Command(0x02); // Set Page Addressing Mode (0x00/0x01/0x02)
OLED_Write_Command(0xA0|0x01); // Set SEG/Column Mapping 0x00左右反置 0x01正常
OLED_Write_Command(0xC0|0x08); // Set COM/Row Scan Direction 0x00上下反置 0x08正常
OLED_Write_Command(0xDA);OLED_Write_Command(0x02|0x10); // Set Sequential Configuration (0x00/0x10)
OLED_Write_Command(0x81);OLED_Write_Command(0xCF); // Set SEG Output Current
OLED_Write_Command(0xD9);OLED_Write_Command(0xF1); // Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_Write_Command(0xDB);OLED_Write_Command(0x40); // Set VCOM Deselect Level
OLED_Write_Command(0xA4|0x00); // Disable Entire Display On (0x00/0x01)
OLED_Write_Command(0xA6|0x00); // Disable Inverse Display On (0x00/0x01)
OLED_Write_Command(0xAE|0x01); // Display On (0x00/0x01)
OLED_Clear(); // 初始清屏
OLED_Set_Pos(0,0);

然后發現

OLED_Write_Command(0xA6|0x00); // Disable Inverse Display On (0x00/0x01)這一項

修改0x00為0x01后圖像顏色反向。

  • 再看周楚侖大神排出BUG的函數

void OLED_Set_Pos(unsigned char x,unsigned char y)
{
OLED_Write_Command(0xb0+y);
OLED_Write_Command(((x&0xf0)>>4)|0x10);
OLED_Write_Command(x&0x0f);
}

 由於楚侖大神,Set了一個未定義的數,導致函數在運行的過程中隨意輸入命令,導致配置出現異常。

具體細節就不再深挖了,雖然到此還未能真正解決問題,但楚侖大神說他要發一篇文章,所以我的好奇心止於此了。

(本文章由瘋狂的小空出品,轉載請注明出處。  

 文章鏈接:http://www.cnblogs.com/sillykog/p/5827784.html

 作者:陳默含)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM