STM32学习100步之第五十二-五十五步——OLED显示模块

我们学习的OLED的主控芯片是SH1106,并且的我们的OLED是64×128点阵。在这里插入图片描述

其中的行划分是按照每8个纵列划分,即每行有8列,方便以字节为单位整体操作。

硬件连接电路如下:

在这里插入图片描述
在这里插入图片描述

具体的操作函数分别如下:
初始化函数:
void OLED_DISPLAY_ON (void){//OLED屏初始值设置并开显示
	u8 buf[28]={
	0xae,//0xae:关显示,0xaf:开显示
    0x00,0x10,//开始地址(双字节)       
	0xd5,0x80,//显示时钟频率?
	0xa8,0x3f,//复用率?
	0xd3,0x00,//显示偏移?
	0XB0,//写入页位置(0xB0~7)
	0x40,//显示开始线
	0x8d,0x14,//VCC电源
	0xa1,//设置段重新映射?
	0xc8,//COM输出方式?
	0xda,0x12,//COM输出方式?
	0x81,0xff,//对比度,指令:0x81,数据:0~255(255最高)
	0xd9,0xf1,//充电周期?
	0xdb,0x30,//VCC电压输出
	0x20,0x00,//水平寻址设置
	0xa4,//0xa4:正常显示,0xa5:整体点亮
	0xa6,//0xa6:正常显示,0xa7:反色显示
	0xaf//0xae:关显示,0xaf:开显示
	}; //
	I2C_SAND_BUFFER(OLED0561_ADD,COM,buf,28);
}

利用I2C总线写入OLED控制芯片即可,需要注意的是,有些功能的设定,需要先写入该功能的控制号,告诉芯片要设置哪个功能,再写入具体的参数值,以用来设置特定功能。

OLED清屏显示:
void OLED_DISPLAY_CLEAR(void){//清屏操作
	u8 j,t;
	for(t=0xB0;t<0xB8;t++){	//设置起始页地址为0xB0
		I2C_SAND_BYTE(OLED0561_ADD,COM,t); 	//页地址(从0xB0到0xB7)
		I2C_SAND_BYTE(OLED0561_ADD,COM,0x10); //起始列地址的高4位
		I2C_SAND_BYTE(OLED0561_ADD,COM,0x00);	//起始列地址的低4位
		for(j=0;j<132;j++){	//整页内容填充
 			I2C_SAND_BYTE(OLED0561_ADD,DAT,0x00);
 		}
	}
}
}

意思是:先从第一行清除,即先写入第一行的行标号,再写入列的起始地址,其中0x10,0x00中的两个高四位1、0是特殊标志位,用来表示列,两个数的低四位组合起来便是0x0000 0000正好代表列的起始地址,而0x00000000-0x11111111正好代表了128列,后面利用for循环逐渐从第1列至第128列清零。

字符和数字、汉字占用的OLED原理图如下:

在这里插入图片描述

经过计算可知显示字母的数字、字母和汉字,每个汉字占16列,每行最多可有8个汉字,16个字符,该OLED有8行。

字符显示函数:
void OLED_DISPLAY_8x16(u8 x, //显示字母的页坐标(从0到7)(此处不可修改)
						u8 y, //显示字母的列坐标(从0到128)
						u16 w){ //要显示字母的编号
	u8 j,t,c=0;
	y=y+2; //因OLED屏的内置驱动芯片是从0x02列作为屏上最左一列,所以要加上偏移量
	for(t=0;t<2;t++){
		I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+x); //页地址(从0xB0到0xB7)
		I2C_SAND_BYTE(OLED0561_ADD,COM,y/16+0x10); //起始列地址的高4位
		I2C_SAND_BYTE(OLED0561_ADD,COM,y%16);	//起始列地址的低4位
		for(j=0;j<8;j++){ //整页内容填充
 			I2C_SAND_BYTE(OLED0561_ADD,DAT,ASCII_8x16[(w*16)+c-512]);//为了和ASII表对应要减512
			c++;}x++; //页地址加1
	}
}

其实字符显示函数和清屏函数的原理基本相同,直接调用即可,注意书写的时候每个字母、汉字是占两个大行的,若在第0行书写了汉字或字母,则下次写到下一行的时候,必须传输大行标号2,因为第1大行已经被占用。

字符串显示函数:
void OLED_DISPLAY_8x16_BUFFER(u8 row,u8 *str){
	u8 r=0;
	while(*str != '\0'){
		OLED_DISPLAY_8x16(row,r*8,*str++);
		r++;
    }	
}

函数中定义了变量r=0,然后最多是r=16,每次要写入下一个的时候,r×8,因为无论是汉字还是字母都占用了8列,为了不产生冲突

使用示例:
	OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk "); //显示字符串
	OLED_DISPLAY_8x16_BUFFER(6,"  Temp:"); //显示字符串

该函数需要注意无论如何传输,传输的字符串的长度不能超过16,可以加空格居中等等。

汉字显示函数:
void OLED_DISPLAY_16x16(u8 x, //显示汉字的页坐标(从0xB0到0xB7)
			u8 y, //显示汉字的列坐标(从0到63)
			u16 w){ //要显示汉字的编号
	u8 j,t,c=0;
	for(t=0;t<2;t++){
		I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+x); //页地址(从0xB0到0xB7)
		I2C_SAND_BYTE(OLED0561_ADD,COM,y/16+0x10); //起始列地址的高4位
		I2C_SAND_BYTE(OLED0561_ADD,COM,y%16);	//起始列地址的低4位
		for(j=0;j<16;j++){ //整页内容填充
 			I2C_SAND_BYTE(OLED0561_ADD,DAT,GB_16[(w*32)+c]);
			c++;}x++; //页地址加1
	}
	I2C_SAND_BYTE(OLED0561_ADD,COM,0xAF); //开显示 
}

汉字显示函数和字母、数字显示函数使用方法基本相同,其需要注意的地方和前面相同,需要注意的是第二个形参是以16位单位乘的,目的和前面相同,为了汉字不发生重叠,最后一个参数是汉字标号,定义在了.h文件中。

使用示例:
OLED_DISPLAY_16x16(2,2*16,0);//汉字显示	 洋桃电子
OLED_DISPLAY_16x16(2,3*16,1);
OLED_DISPLAY_16x16(2,4*16,2);
OLED_DISPLAY_16x16(2,5*16,3);
图像显示函数:
void OLED_DISPLAY_PIC1(void){ //显示全屏图片
	u8 m,i;
	for(m=0;m<8;m++){//
		I2C_SAND_BYTE(OLED0561_ADD,COM,0xb0+m);
		I2C_SAND_BYTE(OLED0561_ADD,COM,0x10); //起始列地址的高4位
		I2C_SAND_BYTE(OLED0561_ADD,COM,0x02);	//起始列地址的低4位
		for(i=0;i<128;i++){//送入128次图片显示内容
			I2C_SAND_BYTE(OLED0561_ADD,DAT,PIC1[i+m*128]);}
	}
}

下面是几个.h头文件:

1、ASCILL表(只有结构,目的是为了符合上述的算法,使表达起来更加清晰)
// ------------------  ASCII字模的数据表 ------------------------ //
// 码表从0x20~0x7e                                                //
// 字库:  纵向取模下高位// (调用时要减512)
// -------------------------------------------------------------- //
uc8 ASCII_8x16[] =  {            // ASCII
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  // - -
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

	0x00,0x00,0x38,0xFC,0xFC,0x38,0x00,0x00,  // -!-
	0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00,

	0x00,0x0E,0x1E,0x00,0x00,0x1E,0x0E,0x00,  // -"-
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

	0x20,0xF8,0xF8,0x20,0xF8,0xF8,0x20,0x00,  // -#-
	0x02,0x0F,0x0F,0x02,0x0F,0x0F,0x02,0x00,
    ....
};
2、汉字表:
uc8 GB_16[] = {         // 数据表
	//"洋", 
	0x10,0x22,0x64,0x0C,0x80,0x08,0x49,0x4A,
	0x4C,0xF8,0x4C,0x4A,0x49,0x08,0x00,0x00,
	0x04,0x04,0xFE,0x01,0x04,0x04,0x04,0x04,
	0x04,0xFF,0x04,0x04,0x04,0x06,0x04,0x00,
	//"桃", 
	0x10,0x10,0xD0,0xFF,0x50,0x90,0x20,0x40,
	0xFF,0x00,0xFF,0x40,0x20,0x30,0x00,0x00,
	0x04,0x03,0x00,0xFF,0x80,0x44,0x22,0x19,
	0x07,0x00,0x3F,0x41,0x46,0x40,0x70,0x00,
	//"电", 
	0x00,0xF8,0x48,0x48,0x48,0x48,0xFF,0x48,
	0x48,0x48,0x48,0xFC,0x08,0x00,0x00,0x00,
	0x00,0x07,0x02,0x02,0x02,0x02,0x3F,0x42,
	0x42,0x42,0x42,0x47,0x40,0x70,0x00,0x00,
	//"子", 
	0x80,0x80,0x82,0x82,0x82,0x82,0x82,0xE2,
	0xA2,0x92,0x8A,0x86,0x80,0xC0,0x80,0x00,
	0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
3、图片表(不全面)
uc8 PIC1[] =                  // 数据表
{
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
      ......
};
至于这些汉字如何显示是通过取模软件来产生相应的段码,根据我们的算法,我们应该选择纵向8点向下高位,选择合适的格式,将产生的段码直接排列到汉字头文件中后面,排列整齐,根据顺序写出相应的汉字标号即可,至于图片段码的产生,直接上传合适的图片格式(格式正确bmp格式,无灰度等)

取模软件如下图:在这里插入图片描述

选择好正确的格式之后,点击参数确认即可,即(ASCILL的格式是8×16),注意,设置图片格式的时候需要注意修改下面X,Y的值,即X取128,Y取64。

同时还可以使用该软件产生自己想要的字符、汉字,如下图所示:

在这里插入图片描述

将修改之后的段码直接复制在.h文件中更新之后便可以使用

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值