簡介
OLED:Organic Light-Emitting Diode,即有機發光二極管,又稱爲有機電激光顯示(Organic Electroluminesence Display,OELD)。
OLED 由於同時具備自發光,不需背光源、對比度高、厚度薄、視角廣、反應速度快、可用於撓曲性面板、使用溫度範圍廣、構造及製程較簡單等優異之特性,被認爲是下一代的平面顯示器新興應用技術。
stm32使用的OLED有多種模式可以選擇,包括8080模式(13條信號線),6800模式(13條信號線),SPI模式(四線),IIC模式(兩線)(也被稱爲I2C),四種模式通過模塊的BS1及BS2進行設置。本文主要介紹IIC模式的原理及相關代碼配置。
8080與6800的區別:存取的控制
8080是通過“讀使能(RE)”和“寫使能(WE)”兩條控制線進行讀寫操作
6800是通過“總使能(E)”和“讀寫選擇(W/R)”兩條控制線進行
硬件相關
SSD1306控制
SSD1306,即OLED上的芯片。
0:這個命令包含了兩個字節,第一個 0X81 爲命令(預告即將發出設置對比度的值),隨後發送的一個字節爲要設置的對比度的值。
1:0XAE 爲關閉顯示命令; 0XAF 爲開啓顯示命令 。
2:第一個 0X8D爲命令,第二個字節 表示電荷泵的開關狀態 。(必開,否則看不到顯示)
3:用於設置頁地址,其低三位的值對應頁地址。 (三位可以設置8個地址)
OLED顯存
SSD1306的顯存容量總共爲128*64bit,SSD1306將這些顯存分爲8page,每個page包含8行,每行128bit,即每一page包含128個字節。
顯存:用來存儲要處理的圖形信息的部件(大概就等於內存吧)
初始化過程
操作相關
寫入數據(或命令)
總結一下,每一次寫入數據(或命令)的步驟:
1.使用起始信號 I2C_Start();
2.發送OLED地址:0x78 Send_Byte(0x78);
3.發送應答信號 I2C_WaitAck();
4.發送寄存器地址(命令或數據)
5.發送應答信號
6.發送命令或數據
7.再一次發送應答信號
8.使用結束信號 I2C_Stop();;
//mode:數據/命令標誌 0,表示命令;1,表示數據;
void OLED_WR_Byte(u8 dat,u8 mode)
{
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
if(mode){Send_Byte(0x40);}
else{Send_Byte(0x00);}
I2C_WaitAck();
Send_Byte(dat);
I2C_WaitAck();
I2C_Stop();
}
開始信號:讓SCL時鐘保持高電平,然後讓SDA數據信號由高變低表示一個開始信號。當IIC總線上的設備檢測到開始信號就知道處理器要發送數據。
停止信號:讓SCL時鐘保持高電平,然後讓SDA數據信號由低變高表示一個停止信號。當IIC總線上的設備檢測到停止信號就知道處理器結束數據傳輸。
尋址模式
OLED的顯存分爲8page,每個page都有8行,每行又有128個位,爲了控制總共128* 8* 8個bit,總共有三種尋址模式。(即尋找相應的地址來控制相應位)
頁尋址模式
該模式下,顯示RAM讀/寫後,列地址指針自動加一(每一列8位),當列地址指針到達列結束地址,自動重置爲列開始地址,頁地址指針不變。需要設置新的頁和列地址才能去到下一頁。
水平尋址模式
該模式下,顯示RAM讀/寫後,列地址指針自動加一(每一列8位),當列地址指針到達列結束地址,列地址指針重置爲列開始地址,頁地址指針增加。當頁地址與列地址指針都到達結束地址,指針重置爲列起始地址與頁起始地址。
垂直尋址模式
該模式下,顯示RAM讀/寫後,頁地址指針自動加一,當頁地址指針到達頁結束地址,頁地址指針重置爲頁開始地址,列地址指針增加。當頁地址與列地址指針都到達結束地址,指針重置爲列起始地址與頁起始地址。
代碼相關
1.開啓OLED顯示
void OLED_DisPlay_On(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//電荷泵使能
OLED_WR_Byte(0x14,OLED_CMD);//開啓電荷泵
OLED_WR_Byte(0xAF,OLED_CMD);//點亮屏幕
}
2.關閉OLED顯示
void OLED_DisPlay_Off(void)
{
OLED_WR_Byte(0x8D,OLED_CMD);//電荷泵使能
OLED_WR_Byte(0x10,OLED_CMD);//關閉電荷泵
OLED_WR_Byte(0xAE,OLED_CMD);//關閉屏幕
}
3.畫點
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
u8 i,m,n;
i=y/8;//確定頁
m=y%8;//確定行
n=1<<m;//計算點在頁的位置
if(t){OLED_GRAM[x][i]|=n;}
else
{
OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}
}
4.更新內存
void OLED_Refresh(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD); //設置行起始地址
OLED_WR_Byte(0x00,OLED_CMD); //設置低列起始地址
OLED_WR_Byte(0x10,OLED_CMD); //設置高列起始地址
I2C_Start();
Send_Byte(0x78);
I2C_WaitAck();
Send_Byte(0x40);
I2C_WaitAck();
for(n=0;n<128;n++)
{
Send_Byte(OLED_GRAM[n][i]);
I2C_WaitAck();
}
I2C_Stop();
}
5.顯示16*16的任意符號(通過字模獲取)
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 mode)
{
u8 m,temp;
u8 x0=x,y0=y;
u16 i,size=16*16; //得到字體一個字符對應點陣集所佔的字節數
for(i=0;i<size;i++)
{
for(m=0;m<8;m++)
{
if(temp&0x01)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp>>=1;
y++;
}
x++;
if((x-x0)==16)
{x=x0;y0=y0+8;}
y=y0;
}
}
6.相應引腳時鐘使能及OLED的初始化
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//初始化相應結構體
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOD, ENABLE); //使能A端口時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOG, &GPIO_InitStructure); //初始化GPIOG12
GPIO_SetBits(GPIOG,GPIO_Pin_12);//初始化IO口PG12,後爲SCL
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD5
GPIO_SetBits(GPIOD,GPIO_Pin_5);//初始化IO口PD5,後爲SDA
delay_ms(200);
OLED_WR_Byte(0xAE,OLED_CMD);//顯示關閉 0xAF是開啓 0xAE是關閉
OLED_WR_Byte(0x00,OLED_CMD);//設置低列地址
OLED_WR_Byte(0x10,OLED_CMD);//設置高列地址
OLED_WR_Byte(0x40,OLED_CMD);//設置起始行地址(0x00~0x3F)
OLED_WR_Byte(0x81,OLED_CMD);//對比度設置指令
OLED_WR_Byte(0xCF,OLED_CMD);// 設置輸出電流亮度
OLED_WR_Byte(0xA1,OLED_CMD);//設置分段/列映射,IIC需要設置爲0xA1
OLED_WR_Byte(0xC8,OLED_CMD);//設置COM掃描方向 0xc0上下反置,COM0到COM N-1 左到右 0xc8正常 COM N-1到COM0 右到左
OLED_WR_Byte(0xA6,OLED_CMD);//設置顯示方式爲正常顯示
OLED_WR_Byte(0xA8,OLED_CMD);//設置分辨率(1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);//分辨率爲128*64:0x3f
OLED_WR_Byte(0xD3,OLED_CMD);//設置顯示偏移
OLED_WR_Byte(0x00,OLED_CMD);//默認值00 無偏移
OLED_WR_Byte(0xd5,OLED_CMD);//設置顯示時鐘分頻/振盪器頻率
OLED_WR_Byte(0x80,OLED_CMD);//將時鐘設置爲100幀/秒
OLED_WR_Byte(0xD9,OLED_CMD);//設置預充電時期
OLED_WR_Byte(0xF1,OLED_CMD);//預充電設爲15時鐘,放電設爲1時鐘
OLED_WR_Byte(0xDA,OLED_CMD);//-設置COM硬件引腳配置,適應分辨率
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);//設置VCOMH
OLED_WR_Byte(0x40,OLED_CMD);//設置VCOM取消選擇級別
OLED_WR_Byte(0x20,OLED_CMD);//頁面尋址模式(0x00/0x01/0x02)
OLED_WR_Byte(0x02,OLED_CMD);//頁尋址
OLED_WR_Byte(0x8D,OLED_CMD);//充電泵設置可用或者不可用
OLED_WR_Byte(0x14,OLED_CMD);//可用
OLED_WR_Byte(0xA4,OLED_CMD);//0xa4,輸出遵循RAM內容 0xa5,輸出忽略RAM內容
OLED_WR_Byte(0xA6,OLED_CMD);//設置顯示方式,正常顯示:0xA6,反相顯示:0xA7
OLED_Clear();
OLED_WR_Byte(0xAF,OLED_CMD);//設置完畢,顯示開啓
}
附:取模工具
取模工具
使用工具:PCtoLCD2002