树莓派使用WiringPi库和硬件IIC驱动OLED屏幕
文章目录
一、0.96寸OLED屏幕介绍
OLED,即有机发光二极管( Organic Light Emitting Diode )。OLED由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。
本文采用的是4针的0.96寸OLED显示进行讲解,采用的是IIC协议,速度会比采用SPI协议的慢一点,但这两者的显示驱动都一样,本质上没有太大差别。屏幕整体分辨率为128*64,有黄蓝、白、蓝三种颜色可选,驱动芯片为SSD1306,下面是引脚功能介绍。
名称 | 注释 |
---|---|
GND | 接地 |
VCC | 3.3-5v |
SCL | 时钟线 |
SDA | 数据线 |
二、树莓派的IIC接口
2.1 树莓派的两组IIC接口:
树莓派3B有两组IIC接口,我们用的是第一组IIC接口,也就是树莓派3脚的SDA接到OLED屏幕的SDA,树莓派5脚的SCL接到OLED屏幕的SCL。
2.2 开启树莓派的IIC接口:
sudo raspi-config
执行完指令之后会进入下面界面,键盘方向键选择:Interfacing Options,然后按下回车
然后还是选择第5个:I2C,按下回车继续
这里出现:你希望启用IIC接口吗?选择Yes
然后这里会提示:ARM I2C接口已开启,选择OK
配置完成之后,我们重启树莓派,重启完成之后进入到我们的/dev目录下,查看是否有I2C的驱动文件:
我们用的是I2C-1,Linux一切皆文件,每个硬件设备“对应”一个文件,由驱动程序提供映射
2.3 检查挂载在I2C的设备:
- 开始测试I2C,首先安装i2c-tools:
sudo apt-get install i2c-tools
- 列出连接到I2C总线的设备的地址:
gpio i2cdetect
三、树莓派与OLED屏幕硬件接线
四、WiringPi库的I2C函数
#include <wiringPi.h>
#include <wiringPiI2C.h>
int wiringPiI2CSetup (int devId);//初始化wiringPi库i2c,devId是i2c设备地址,返回值是linux的文件描述符
int wiringPiI2CRead (int fd);//直接读取数据,fd是wiringPiI2CSetup函数的返回值,返回值是读到的数据
int wiringPiI2CWrite (int fd, int data);//直接写数据,fd同上,data是写入的数据
int wiringPiI2CWriteReg8 (int fd, int reg, int data);//写数据到8位寄存器,fd同上,reg寄存器地址,data要写入的数据
int wiringPiI2CWriteReg16 (int fd, int reg, int data);//写数据到16位寄存器,fd同上,reg寄存器地址,data要写入的数据
int wiringPiI2CReadReg8 (int fd, int reg);//从寄存器读取8位数据,fd同上,reg寄存器地址,返回值读取到的数据
int wiringPiI2CReadReg16 (int fd, int reg);//从寄存器读取16位数据,fd同上,reg寄存器地址,返回值读取到的数据
五、树莓派使用WiringPi库驱动OLED显示
#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#define IIC_ADRR 0x3c
#define OLED_CMD 0x00 //写命令
#define OLED_DATA 0x40 //写数据
void OLED_Clear(int fd) //清屏函数
{
unsigned char i,n;
for(i=0;i<8;i++)
{
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xb0+i); //设置页地址(0~7)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x00); //设置显示位置—列低地址
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x10); //设置显示位置—列高地址
for(n=0;n<128;n++)wiringPiI2CWriteReg8(fd, OLED_DATA, 0);
} //更新显示
}
void OLED_Init(int fd)
{
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x00);//---set low column address
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x10);//---set high column address
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x81);//--set contrast control register
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xCF); // Set SEG Output Current Brightness
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xA1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xC8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xA6);//--set normal display
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xA8);//--set multiplex ratio(1 to 64)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x3f);//--1/64 duty
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x00);//-not offset
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xd5);//--set display clock divide ratio/oscillator frequency
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xD9);//--set pre-charge period
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xDA);//--set com pins hardware configuration
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x12);
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xDB);//--set vcomh
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x40);//Set VCOM Deselect Level
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x02);//
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x8D);//--set Charge Pump enable/disable
wiringPiI2CWriteReg8(fd, OLED_CMD, 0x14);//--set(0x10) disable
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xA4);// Disable Entire Display On (0xa4/0xa5)
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xA6);// Disable Inverse Display On (0xa6/a7)
OLED_Clear(fd);
wiringPiI2CWriteReg8(fd, OLED_CMD, 0xAF); /*display ON*/
}
int main(int argc, char const *argv[])
{
int i2c_fd; //IIC设备文件描述符
if(wiringPiSetup() != 0) //初始化wiringPi库
{
printf("wiringPi error!\n");
return -1;
}
i2c_fd = wiringPiI2CSetup(IIC_ADRR); //初始化IIC总线
OLED_Init(i2c_fd); //初始化OLED
wiringPiI2CWriteReg8(i2c_fd, OLED_CMD, 0xB0); //设置页地址(0~7)
//画一条直线
for (int i = 0; i < 100; i++)
{
wiringPiI2CWriteReg8(i2c_fd, OLED_DATA, 0x80); //设置列地址(0~127)
}
while (1);
return 0;
}