相对于数码管来说OLED屏具有小巧、显示信息多的特点。这里选用的是一款0.96寸的双色OLED屏,其显示分辨率为128*64像素点,并以I2C的方式来工作。
本打算以开发板的2个I2C接口来驱动OLED屏,无奈的是却没找到I2C的使用方法和相关的例程,也就只能以GPIO口来模拟I2C啦。
该OLED屏与开发板的连接关系为:
SDA----GPIO9
SCL---- GPIO10
以GPIO口模拟I2C方式字节数据的函数为:
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
digitalWrite(10, LOW);
for(i=0;i<8;i++)
{
m=da;
m=m&0x80;
if(m==0x80)
{
digitalWrite(9, HIGH);
}
else
{
digitalWrite(9, LOW);
}
da=da<<1;
digitalWrite(10, HIGH);
digitalWrite(10, LOW);
}
}
该显示屏的初始化函数为:
void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x81,OLED_CMD);
OLED_WR_Byte(0xff,OLED_CMD);
OLED_WR_Byte(0xA1,OLED_CMD);
OLED_WR_Byte(0xC8,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xA8,OLED_CMD);
OLED_WR_Byte(0x3f,OLED_CMD);
OLED_WR_Byte(0xD3,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xd5,OLED_CMD);
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD);
OLED_WR_Byte(0xF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD);
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x20,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xA4,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_Clear();
OLED_Set_Pos(0,0);
}
为测试对该显示屏的驱动性,先以清屏函数改造了一个水平线绘制函数,其内容如下:
void OLED_Clear(void)
{
unsignedchar i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD);
OLED_WR_Byte (0x00,OLED_CMD);
OLED_WR_Byte (0x10,OLED_CMD);
for(n=0;n<128;n++) OLED_WR_Byte(0xf0,OLED_DATA);
}
}
经程序下载,其显示效果如图1所示,这说明对显示屏的驱动是成功的。
图1 测试效果
然后在此基础上再添加字符显示函数和字库就可显示字符了,其字库的结构如下:
unsigned char F8X16[]=
{
...
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1
17
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2
18
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3
19
...
};
相应的字符显示函数为:
void OLED_ShowChar(unsigned char x,unsigned char
y,unsigned char chr,unsigned char Char_Size)
{ unsignedchar c=0,i=0;
c=chr-'';
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
}
对应的数值显示函数为:
void OLED_ShowNum(unsigned char x,unsigned char y,uint32_t num,unsigned char len,unsigned char size2)
{
unsigned char t,temp;
unsigned char 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);
}
}
实现图2所示效果的初始设置程序为:
void setup() {
unsignedchar STR[10]={'B','P','I','_','R','P','2','0','4','0'};
unsignedchar i;
pinMode(9,OUTPUT);
pinMode(10, OUTPUT);
OLED_Init();
OLED_Clear();
OLED_ShowChar(20,4,'O',16);
OLED_ShowChar(28,4,'K',16);
for(i=0;i<10;i++) OLED_ShowChar(16+i*8,0,STR[i],16);
OLED_ShowNum(20,2,985,3,16);
}
图2 显示效果
由于在Arduino IDE的环境下只支持数值而没有指针变量类型,为此要显示一个字符串就只好将其放入数组中来实现。
BH1750是一款用于光照强度检测的传感器,该传感器以I2C方式工作,它与开发板的连接关系为:
SCL---- GPIO11
SDA----GPIO12
实现数据引脚输入、输出模式设置的函数为:
void IIC_INPUT_MODE_SET()
{
pinMode(12, INPUT_PULLUP);
}
void IIC_OUTPUT_MODE_SET()
{
pinMode(12, OUTPUT);
}
读取光照强度的函数为:
void Get_Sunlight_Value()
{
int dis_data=0;
float temp;
char i=0;
unsigned int sd;
Single_Write_BH1750(0x01); //power on
Single_Write_BH1750(0x10); // H-resolution mode
delay(180);
Multiple_Read_BH1750();
for(i=0;i<3;i++) dis_data=BUF[0];
dis_data=(dis_data<<8)+BUF[1];
temp=(float)dis_data/1.2;
sd=temp;
if(sd<54612) OLED_ShowNum(88,5,sd,4,16);
}
实现光照强度检测与显示的程序为:
void setup() {
unsigned char STR[10]={'B','P','I','_','R','P','2','0','4','0'}; unsigned char STR1[6]={'B','H','1','7','5','0'};
unsigned char STR2[9]={'S','u','n','l','i','g','h','t','='};
unsigned char i;
OLED_Init();
OLED_Clear();
for(i=0;i<10;i++)
OLED_ShowChar(16+i*8,0,STR[i],16);
for(i=0;i<6;i++)
OLED_ShowChar(16+i*8,2,STR1[i],16);
for(i=0;i<9;i++)
OLED_ShowChar(16+i*8,5,STR2[i],16);
BH1750_Init();
}
void loop() {
Get_Sunlight_Value();
delay(1000);
}
经程序的下载,其运行效果如图3所示,说明程序设计有效。
图3 传感器检测效果