文章目錄
- 前言
- 一、OLED的器件位址
- 二、編寫寫資料和寫指令函數
- 三、編寫初始化OLED螢幕函數
- 四、其他功能函數編寫
- 五、顯示字元和數字函數編寫
- 總結
前言
這篇文章将帶大家學習如何編寫OLED顯示屏的驅動程式。這裡我使用的是HAL庫的硬體IIC,OLED螢幕使用的是SSD1306的。
這裡需要參考SSD1306的資料手冊來編寫驅動程式。
手冊位置:
一、OLED的器件位址
OLED的器件位址由8個位組成,分别是011110SA0 R/W#。

資料手冊有這樣一段話:
D/C# pin acts as SA0 for slave address selection
根據這段話可以得知D/C#這個引腳被作為了SA0。
根據OLED的原理圖我們可以得知D/C接到了GND是以SA0 = 0。
R/W位:當要寫資料時這一位是0,當要讀資料時這一位是1。
是以可以得出OLED的器件位址:
寫位址:0x78
讀位址:0x79
二、編寫寫資料和寫指令函數
寫指令函數
這裡調用了HAL庫自帶的HAL_I2C_Mem_Write函數來寫指令和寫資料。
我們需要參照資料手冊中的I2C-bus Write data這一小節來編寫函數。
根據資料手冊可知:
第一步先發送器件位址(這裡是寫資料也就是0x78)。
第二步發送控制位元組:
控制位元組由Co位和D/C位決定
當發送的是指令的時候D/C和Co都為0。
當發送的是資料的時候D/C為1和Co為0。
是以發送指令時控制位元組為0x00,發送資料時控制位元組為0x40。
第三步發送資料位元組也就是下面函數中的uint8_t data和uint8_t cmd這兩個參數。
void OLED_WR_CMD(uint8_t cmd)
{
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0x100);
}
寫資料函數
void OLED_WR_DATA(uint8_t data)
{
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, &data, 1, 0x100);
}
三、編寫初始化OLED螢幕函數
下面是OLED顯示屏初始化的步驟。
這些要設定的參數都放入了CMD_Data數組中。
uint8_t CMD_Data[] = {
0xAE, 0x00, 0x10, 0x40, 0xB0, 0x81, 0xFF, 0xA1, 0xA6, 0xA8, 0x3F,
0xC8, 0xD3, 0x00, 0xD5, 0x80, 0xD8, 0x05, 0xD9, 0xF1, 0xDA, 0x12,
0xD8, 0x30, 0x8D, 0x14, 0xAF }; //初始化指令
這裡使用for循環将參數寫入。
void WriteCmd(void)
{
uint8_t i = 0;
for (i = 0; i < 27; i++)
{
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, CMD_Data + i, 1, 0x100);
}
}
//初始化oled螢幕
void OLED_Init(void)
{
HAL_Delay(200);
WriteCmd();
}
四、其他功能函數編寫
清屏函數
//清屏
void OLED_Clear(void)
{
uint8_t i, n;
for (i = 0; i < 8; i++)
{
OLED_WR_CMD(0xb0 + i);
OLED_WR_CMD(0x00);
OLED_WR_CMD(0x10);
for (n = 0; n < 128; n++)
OLED_WR_DATA(0);
}
}
開啟OLED顯示和關閉OLED顯示函數
//開啟OLED顯示
void OLED_Display_On(void)
{
OLED_WR_CMD(0X8D); //SET DCDC指令
OLED_WR_CMD(0X14); //DCDC ON
OLED_WR_CMD(0XAF); //DISPLAY ON
}
//關閉OLED顯示
void OLED_Display_Off(void)
{
OLED_WR_CMD(0X8D); //SET DCDC指令
OLED_WR_CMD(0X10); //DCDC OFF
OLED_WR_CMD(0XAE); //DISPLAY OFF
}
設定坐标函數
這裡OLED被設定為了頁位址模式,位址範圍是0xb0-0xb7。也就是y的範圍是0-7。
x的範圍就是0-127
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
OLED_WR_CMD(0xb0 + y);
OLED_WR_CMD(((x & 0xf0) >> 4) | 0x10);
OLED_WR_CMD(x & 0x0f);
}
五、顯示字元和數字函數編寫
//顯示2個數字
//x,y :起點坐标
//len :數字的位數
//size:字型大小
//mode:模式 0,填充模式;1,疊加模式
//num:數值(0~4294967295);
void OLED_ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2)
{
uint8_t t, temp;
uint8_t enshow = 0;
for (t = 0; t < len; t++)
{
temp = (num / oled_pow(10, len - t - 1)) % 10;
if (enshow == 0 && t < (len - 1))
{
if (temp == 0)
{
OLED_ShowChar(x + (size2 / 2)*t, y, ' ', size2);
continue;
}
else enshow = 1;
}
OLED_ShowChar(x + (size2 / 2)*t, y, temp + '0', size2);
}
}
//在指定位置顯示一個字元,包括部分字元
//x:0~127
//y:0~63
//mode:0,反白顯示;1,正常顯示
//size:選擇字型 16/12
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{
unsigned char c = 0, i = 0;
c = chr - ' ';//得到偏移後的值
if (x > 128 - 1) { x = 0; y = y + 2; }
if (Char_Size == 16)
{
OLED_Set_Pos(x, y);
for (i = 0; i < 8; i++)
OLED_WR_DATA(F8X16[c * 16 + i]);
OLED_Set_Pos(x, y + 1);
for (i = 0; i < 8; i++)
OLED_WR_DATA(F8X16[c * 16 + i + 8]);
}
else {
OLED_Set_Pos(x, y);
for (i = 0; i < 6; i++)
OLED_WR_DATA(F6x8[c][i]);
}
}
//顯示一個字元号串
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_t Char_Size)
{
unsigned char j = 0;
while (chr[j] != '\0')
{
OLED_ShowChar(x, y, chr[j], Char_Size);
x += 8;
if (x > 120) { x = 0; y += 2; }
j++;
}
}
//顯示漢字
//hzk 用取模軟體得出的數組
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no)
{
uint8_t t, adder = 0;
OLED_Set_Pos(x, y);
for (t = 0; t < 16; t++)
{
OLED_WR_DATA(Hzk[2 * no][t]);
adder += 1;
}
OLED_Set_Pos(x, y + 1);
for (t = 0; t < 16; t++)
{
OLED_WR_DATA(Hzk[2 * no + 1][t]);
adder += 1;
}
}
總結
這篇文章主要就是講解了如何編寫OLED的驅動程式。