天天看點

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結

文章目錄

  • 前言
  • 一、OLED的器件位址
  • 二、編寫寫資料和寫指令函數
  • 三、編寫初始化OLED螢幕函數
  • 四、其他功能函數編寫
  • 五、顯示字元和數字函數編寫
  • 總結

前言

這篇文章将帶大家學習如何編寫OLED顯示屏的驅動程式。這裡我使用的是HAL庫的硬體IIC,OLED螢幕使用的是SSD1306的。

這裡需要參考SSD1306的資料手冊來編寫驅動程式。

手冊位置:

一、OLED的器件位址

OLED的器件位址由8個位組成,分别是011110SA0 R/W#。

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結

資料手冊有這樣一段話:

D/C# pin acts as SA0 for slave address selection

根據這段話可以得知D/C#這個引腳被作為了SA0。

根據OLED的原理圖我們可以得知D/C接到了GND是以SA0 = 0。

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結

R/W位:當要寫資料時這一位是0,當要讀資料時這一位是1。

是以可以得出OLED的器件位址:

寫位址:0x78

讀位址:0x79

二、編寫寫資料和寫指令函數

寫指令函數

這裡調用了HAL庫自帶的HAL_I2C_Mem_Write函數來寫指令和寫資料。

我們需要參照資料手冊中的I2C-bus Write data這一小節來編寫函數。

根據資料手冊可知:

第一步先發送器件位址(這裡是寫資料也就是0x78)。

第二步發送控制位元組:

控制位元組由Co位和D/C位決定

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結

當發送的是指令的時候D/C和Co都為0。

當發送的是資料的時候D/C為1和Co為0。

是以發送指令時控制位元組為0x00,發送資料時控制位元組為0x40。

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結

第三步發送資料位元組也就是下面函數中的uint8_t data和uint8_t cmd這兩個參數。

STM32編寫OLED顯示屏驅動前言一、OLED的器件位址二、編寫寫資料和寫指令函數三、編寫初始化OLED螢幕函數四、其他功能函數編寫五、顯示字元和數字函數編寫總結
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顯示屏初始化的步驟。

STM32編寫OLED顯示屏驅動前言一、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顯示函數

STM32編寫OLED顯示屏驅動前言一、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的驅動程式。

繼續閱讀