STM32的HAL库的IIC OLED驱动

        目前IICOLED屏幕是初学者常用的外设,本文将介绍STM32F407(所有STM32都大同小异)方面的oled驱动,下一篇文章将会介绍linux的IIC驱动。       

OLED启动主要分为以下几步:

①屏幕初始化
②开启屏幕显示
③清屏(不清屏的话屏幕将会出现一片雪花)
④发送要显示的字符串、数字、汉字等

一、工程建立

首先利用Stm32CubeMX软件建立工程,因屏幕是i2c通信因此此工程只配置i2c和时钟即可。

时钟配置:

        STM32的HAL库的IIC OLED驱动_第1张图片

 STM32的HAL库的IIC OLED驱动_第2张图片

i2c配置,本次选用的为i2c1:

        STM32的HAL库的IIC OLED驱动_第3张图片

然后生成工程即可。

二、代码编写

oled有写命令和写数据两种操作,写命令为配置某项功能时使用,写数据为向oled写显示内容时使用。具体实现代码如下:oled屏地址一般为0x78(可以根据屏幕后面有一电阻,看电阻连接0x78还是0x7A)。

//写命令
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屏幕的配置,如果驱动不成功,可以试一下其他的初始化代码。

void WriteCmd()
{
    OLED_WR_CMD(0xAE);//--turn off oled panel
	OLED_WR_CMD(0x00);//---set low column address
	OLED_WR_CMD(0x10);//---set high column address
	OLED_WR_CMD(0x40);//--set start line address  Set Mapping RAM Display Start Line 
	OLED_WR_CMD(0x81);//--set contrast control register
	OLED_WR_CMD(0xCF);// Set SEG Output Current Brightness
	OLED_WR_CMD(0xA1);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WR_CMD(0xC8);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WR_CMD(0xA6);//--set normal display
	OLED_WR_CMD(0xA8);//--set multiplex ratio(1 to 64)
	OLED_WR_CMD(0x3f);//--1/64 duty
	OLED_WR_CMD(0xD3);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_CMD(0x00);//-not offset
	OLED_WR_CMD(0xd5);//--set display clock divide ratio/oscillator frequency
	OLED_WR_CMD(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_CMD(0xD9);//--set pre-charge period
	OLED_WR_CMD(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_CMD(0xDA);//--set com pins hardware configuration
	OLED_WR_CMD(0x12);
	OLED_WR_CMD(0xDB);//--set vcomh
	OLED_WR_CMD(0x40);//Set VCOM Deselect Level
	OLED_WR_CMD(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_CMD(0x02);//
	OLED_WR_CMD(0x8D);//--set Charge Pump enable/disable
	OLED_WR_CMD(0x14);//--set(0x10) disable
	OLED_WR_CMD(0xA4);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_CMD(0xA6);// Disable Inverse Display On (0xa6/a7) 
	OLED_Clear();
	OLED_WR_CMD(0xAF);
}

 ②开启屏幕显示

//开启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
}		

③清屏操作:

void OLED_Clear()
{
	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(0x00);
	} 
}

④配置显示内容:

其中F8x16和F6x8是自己添加的字符库。

/*
输入内容为oled屏幕的显示坐标,要显示的字符、字符大小
*/
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++;
	}
}


unsigned char Hzk[][16]=
{

 {0x00,0x80,0xC0,0xBC,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0xC0,0x80,0x00},
 {0x00,0x40,0x20,0x10,0x0C,0x40,0x80,0x7F,0x00,0x00,0x04,0x08,0x30,0x60,0x00,0x00},

 {0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x06,0x55,0x84,0x7E,0x04,0x00},
 {0x40,0x3F,0x02,0x3F,0x40,0x3F,0x42,0x7F,0x10,0x13,0x12,0x12,0x5A,0x92,0x7E,0x00},
};

//显示汉字
//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;
      }					
}

//水平滚动
void OLED_ver_scroll()
{
  OLED_WR_CMD(0x2e);//关滚动
  OLED_WR_CMD(0x27);//29向右,2a向左
  OLED_WR_CMD(0x00);//A:空字节
  OLED_WR_CMD(0x02);//B:水平起始页
  OLED_WR_CMD(0x07);//C:水平滚动速度
  OLED_WR_CMD(0x03);//D:水平结束页
  OLED_WR_CMD(0x00);//E:每次垂直滚动位移
  OLED_WR_CMD(0xFF);//E:每次垂直滚动位移
  OLED_WR_CMD(0x2f);//开滚动
  
}

主函数为:

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  HAL_Delay(500);
  OLED_Display_On();
  uint8_t A[]="hellow world !!!!";
  uint8_t B[]="hellow world !!";
  OLED_Init();
  HAL_Delay(500);
  OLED_Display_On();pei
  OLED_Clear();

  /*OLED_ShowString(0,0,A,sizeof(A));
	OLED_ShowString(0,4,A,sizeof(B));*/
  OLED_ShowCHinese(0,2,0);
  OLED_ShowCHinese(16,2,1);
  OLED_ver_scroll();

  while (1)
  {
   
  }
}

至此就可以实现OLED的简单驱动了,下一期将会更新此olde屏幕在linux系统上的驱动配置。

本人并称开源思想以下我将附上我的代码希望大家多读点赞收藏支持。如失效,请及时与我联系

链接:https://pan.baidu.com/s/1_CTN0VSClB4VggR8OyRIcA 
提取码:lpfx

创作不易,未经许可禁止转载

你可能感兴趣的:(电子,计算机,编程,stm32,arm,嵌入式硬件,c++,c语言)