OLED显示屏

1 芯片介绍

1.1 硬件连接图

该芯片的型号为SH1106,通讯方式有几种类型,这里选用的是I2C通信,其连接如下图所示:
在这里插入图片描述
参考洋桃电子家的电路图:
在这里插入图片描述
左下角的LM75a是温度传感器,不用看。这里我也没看懂这里的电路图,感觉和数据手册的电路图不太匹配。

1.2 OLED0561屏行列地址

该屏有13264(列行)的像素点,实际边上只有128列,估计是为显示不要太靠边了,不然不好看吧。
英文显示的像素点为88,但为了和汉字对齐,为了美观,通常用816的像素点,汉字用1616,所以12864的像素点只能显示164个英文字母,或者84个汉字,即4行16个英文字母或4行8个汉字。
关于行列地址的划分,该芯片还有另外的讲究,参考数据手册中的行列地址的说明。
在这里插入图片描述
在ADC这个位为0时,SEG0-SEG131的地址是从0x0-0x83,若ADC=1时,地址是从0x83-0x0,此外这个还能设置滚动的效果。
在这里插入图片描述
它这里说其实显示的地址是从1D(H)开始的,参照下面的图可以发现,好像确实是这样。
在这里插入图片描述
根据箭头的方向可以看到滚动的方向,放大局部可以看滚动的起始位置确实是从1D(H)开始的,它这里标的是1CH,但这里想表达的意思应该是已经滚动一行之后的地址,具体的情况可以在写代码的时候调试一下。从这里也可以看到滚动的方向是向上滚动的。这里1D(H)对应的行数是PAGE3,之后试一下效果。
在这里插入图片描述
从局部可以发现数据D0-D7共8位组成一个PAGE,也就是说64行对应64位数据,可以组成8个PAGE,这里对应着PAGE0-PAGE7,地址是由D0-D3组成的从0000-0007。列是被分为了128列,地址从00(H)-83(H),对应着SEG0-SEG131。
111
具体的列地址看数据手册
在这里插入图片描述
列地址的选择是由两个字节来决定的,Higher bits和Lower bits,Highter bits决定着A4-A7,Lower bits决定着A0-A3,Higher bits的高4位为0001,Lower bits的高4位为0000。所以在发送列地址时,应该发送Higher bits:0x10-0x1F,和Lower bits:0x00-0x0F。
行地址的选取:
在这里插入图片描述

1.3 指令控制集

除了上述的行列地址的选取,此外还有很多另外的指令集。

  1. 设置电压值(0x30-0x33)
    这个是用来设置内部电荷的,不知道有啥用。
    在这里插入图片描述

  2. 设置显示的初始行(0x40-0x3f)
    当改变这个值时,将发生平滑滚动或页面更改。刚开始以为这个是行地址选取,有点懵,后来发现这个不是。
    在这里插入图片描述

  3. 设置对比度寄存器(双字节)
    这个是通过调节电流的大小来调节显示屏幕的亮度的,发送时得发送两个字节。电流大小的计算公式为:
    ISEG = a/256 X IREF X scale factor
    其中a为往寄存器设置的值,范围为00-FF(H),IREF是参考电流为12.5uA,scale factor=16。
    设置对比度命令为0x81(10000001)。
    在这里插入图片描述
    对比度设置:0x00-0xFF
    在这里插入图片描述

  4. 设置段区重映射(0xa0/0xa1)
    这里根据描述应该是显示内容旋转。
    在这里插入图片描述

  5. 设置开关(0xa4/0xa5)
    A4为关,A5为开。
    在这里插入图片描述

  6. 正常/反转显示(A6/A7)
    在这里插入图片描述
    即当D=0时,写入ram的数据为1,则OLED的灯亮,当D=1时,写入ram的数据为0,则OLED的灯亮。正常显示时,是ram里的数据为1时,灯亮。

  7. 设置多路复用(双字节)(A8,00-3F)
    这个是用来设置行数使用的多少,比如设置的是31,则表示使用的是前32行(0-31)。代码设置的是0x3F,对应的Multiplex Ratio为64。
    在这里插入图片描述

  8. 设置DC-DC控制(双字节)
    在设置这个命令时,需要把显示面板关闭。
    在这里插入图片描述

  9. 显示打开和关闭(AF/AE)
    这个还有一个睡眠模式。
    在这里插入图片描述

  10. 设置显示方向(C0/C8)
    这个是设置行的方向。
    在这里插入图片描述

  11. 设置显示偏移(双字节0xd3, 0x00-0x3f)
    偏移了对显示好像没啥用,也不知道干啥
    在这里插入图片描述

  12. 设置显示时钟的分频/晶振频率(双字节)
    A0-A3是设置时钟的分频,A4-A7是用来设置晶振的频率。
    在这里插入图片描述
    在这里插入图片描述

  13. 设置放电/预充电周期(双字节)
    在这里插入图片描述
    在这里插入图片描述

  14. 设置COM的排列顺序
    在这里插入图片描述
    这个应该和硬件的COM的布局有关。设置为0x02时,COM应该是按31,30—1,0,32,33—62,63布局。设置为0x12时,COM应该是62,60—2,0,1,3—61,63。

  15. Set VCOM Deselect Level(双字节)
    在这里插入图片描述
    在这里插入图片描述
    这个感觉是设置输出电压的。

  16. Read-Modify-Write: (E0H)
    在这里插入图片描述
    在这里插入图片描述

  17. End(EE(H))
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
从16-19不知道为啥没有用到。估计是跟IIC的通信方式有关吧。

1.4 实际应用

u8 buf[22]={
			0xae,//0xae:关显示,0xaf:开显示
		//设置内部电荷值,这里设置8.0
			0x32,
		//设置初始行(0x40-0x3f)
				//感觉这里不用设置
		//设置对比度(双字节),这里设置为FF吧,对比度最高
			0x81, 0xff,
		//设置列从那边开始显示(0xa0/0xa1)
			0xa1,
		//DC-DC控制
			//感觉这里不用设置
		//设置开/关A5/A4,这里A5是整体点亮,A4是正常显示
			0xa4, 
		//设置数据显示的方式,正常为数据为1,灯亮(0xa6/0xa7)
			0xa6,
		//设置使用那几行,正常来说整屏要使用(双字节,0xa8, 00-0x3f)
			0xa8, 0x3f,
		//设置行从上/下开始显示(C0/C8)
			0xc8,
		//设置显示偏移(双字节,0xd3,0x00-0x3f)
			0xd3, 0x00,
		//设置时频的分频和晶振频率(双字节0xd5, 0x00-0xff)
			0xd5, 0x50,
		//设置放电/预充电周期(双字节,0xd9, 0x00-0xff)
			0xd9, 0x22,
		//设置COM排列顺序(双字节,0xda, 0x02/0x12)
			0xda, 0x12,
		//Set VCOM Deselect Level(双字节,0xdb,0x00-0xff),不知道啥意思,乱设置一个
			0xdb, 0x01,
			0xaf//0xae:关显示,0xaf:开显示
	}; //

初始化成功。

void OLED_DISPLAY_OFF (void){
	//OLED屏初始值设置并开显示
		u8 buf[3]={
			0xae,//0xae:关显示,0xaf:开显示
			0x8d,0x10//VCC电源
		}; //
		
		I2C_SAND_BUFFER(0x78,0x00,buf,3);
	
}

void OLED_DISPLAY_CLEAR(void)
{
	u8 row,col;
	for(row = 0xB0; row < 0xB8; row++)
	{
		//行地址
		I2C_SAND_BYTE(0x78, 0x00, row);
		//列地址,这里只用给起始地址
		I2C_SAND_BYTE(0x78, 0x00, 0x10);
		I2C_SAND_BYTE(0x78, 0x00, 0x00);
		//写入数据
		for(col = 0; col < 132; col++)
		{
			I2C_SAND_BYTE(0x78, 0x40, 0x00);
		}
	}
}


void OLED0561_Init (void){//OLED屏开显示初始化
	OLED_DISPLAY_OFF(); //OLED关显示
	OLED_DISPLAY_CLEAR(); //清空屏幕内容
	OLED_DISPLAY_ON(); //OLED屏初始值设置并开显示
	//I2C_SAND_BYTE(0x78, 0x00, 0xa5);
}

void OLDE0561_DISPLAY(u8 oled_row, u8 oled_col, u16 len)//oled_row1-4行,oled_col为1-8列
{
		u8 row, col;
		/遍历两次,第一次遍历完之后数据的位数是8*16(高*宽),即显示屏的第一行,第二次遍历是16*16,即显示屏的第二行
		for(row = 0; row < 2; row++)
		{
			//行地址
			I2C_SAND_BYTE(0x78, 0x00, 2*(oled_row-1)+row+0xB0);
			//列地址,这里只用给起始地址
			I2C_SAND_BYTE(0x78, 0x00, 0x10+oled_col);//高位,高位加1,相当于列数加16列
			I2C_SAND_BYTE(0x78, 0x00, 0x00);//低位,低位加1,相当于列数加1列
			//写入数据,第一次遍历前16个数据,第二次遍历后16个数据
			for(col = 0; col < 16; col++)
			{
				if(row == 1)
				{
					I2C_SAND_BYTE(0x78,0x40,picture[(len-1)*32+16+col]);
				}
				if(row == 0)
				{
					I2C_SAND_BYTE(0x78,0x40,picture[(len-1)*32+col]);
				}
				
				
			}
		}
	
		I2C_SAND_BYTE(0x78, 0x00, 0xaf);
	
}
这个问题可以分为两个部分:读取电位器或光敏电阻的值和将值显示到OLED屏上。 读取电位器或光敏电阻的值可以使用模拟输入引脚来完成。假设使用的是Arduino,可以使用analogRead()函数来读取模拟输入引脚的值,得到一个0到1023之间的数字。这个数字代表了电位器或光敏电阻的电阻值,可以通过简单的电路计算得到对应的电位器或光敏电阻的电阻值。 将值显示到OLED屏上,需要使用OLED屏的相关库函数。具体的操作步骤如下: 1. 引入OLED库,并初始化OLED屏幕。 2. 读取电位器或光敏电阻的值,并计算出对应的电阻值。 3. 将电阻值转换为字符串。 4. 使用库函数将字符串显示到OLED屏幕上。 下面是一个简单的示例代码: ```C++ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET -1 Adafruit_SSD1306 display(OLED_RESET); int potPin = A0; // 电位器连接的模拟输入引脚 void setup() { display.begin(SSD1306_SWITCHCAPVCC, 128, 32); // 初始化OLED屏幕 display.clearDisplay(); // 清空屏幕 } void loop() { int potValue = analogRead(potPin); // 读取电位器的值 float resistance = 10000.0 * (1023.0 / potValue - 1.0); // 计算电阻值 String resistanceStr = String(resistance, 2); // 将电阻值转换为字符串 display.clearDisplay(); // 清空屏幕 display.setCursor(0, 0); // 设置光标位置 display.print("Resistance:"); // 显示文本 display.setCursor(0, 10); // 设置光标位置 display.print(resistanceStr); // 显示电阻值 display.print(" ohm"); // 显示单位 display.display(); // 刷新屏幕 } ``` 这个代码示例假设电位器连接到了A0引脚,并且电位器的最大阻值是10Kohm。如果使用光敏电阻,只需要将电阻计算公式进行修改即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值