oled显示屏spi协议驱动代码
时间: 2023-08-05 16:02:03 浏览: 116
以下是一份基于SPI协议驱动OLED显示屏的示例代码,供参考:
```c
#include <reg51.h>
// 定义OLED的引脚
sbit OLED_RST = P1^0;
sbit OLED_DC = P1^1;
sbit OLED_CS = P1^4;
sbit OLED_SCL = P1^6;
sbit OLED_SDA = P1^7;
// 定义SPI通信命令
#define CMD_SET_COL_ADDR 0x15
#define CMD_SET_PAGE_ADDR 0x75
#define CMD_WRITE_RAM 0x5C
// 定义屏幕分辨率
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// 定义字体
const unsigned char F6x8[][6] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // '!'
{0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // '"'
// ...
};
// 定义函数
void spi_write_byte(unsigned char dat);
void spi_write_cmd(unsigned char cmd);
void spi_write_data(unsigned char dat);
void oled_init();
void oled_set_pos(unsigned char x, unsigned char y);
void oled_clear();
void oled_show_string(unsigned char x, unsigned char y, const char *str);
// 主函数
void main() {
// 初始化OLED显示屏
oled_init();
// 在屏幕上显示字符串
oled_show_string(0, 0, "Hello, world!");
}
// SPI写入一个字节
void spi_write_byte(unsigned char dat) {
unsigned char i;
for (i = 0; i < 8; i++) {
OLED_SDA = (dat & 0x80) >> 7;
dat <<= 1;
OLED_SCL = 1;
OLED_SCL = 0;
}
}
// SPI写入一个命令
void spi_write_cmd(unsigned char cmd) {
OLED_DC = 0;
OLED_CS = 0;
spi_write_byte(cmd);
OLED_CS = 1;
}
// SPI写入一个数据
void spi_write_data(unsigned char dat) {
OLED_DC = 1;
OLED_CS = 0;
spi_write_byte(dat);
OLED_CS = 1;
}
// 初始化OLED显示屏
void oled_init() {
OLED_RST = 0;
delay(200);
OLED_RST = 1;
spi_write_cmd(0xAE); // 关闭显示
spi_write_cmd(0xD5); // 设置时钟分频因子
spi_write_cmd(0x80); // 时钟分频因子,越小越快
spi_write_cmd(0xA8); // 设置驱动路数
spi_write_cmd(0x3F); // 默认值(1/64)
spi_write_cmd(0xD3); // 设置显示偏移
spi_write_cmd(0x00); // 默认值
spi_write_cmd(0x40); // 设置显示起始行
spi_write_cmd(0x8D); // 电荷泵设置
spi_write_cmd(0x14); // bit2,开启/关闭
spi_write_cmd(0x20); // 设置内存地址模式
spi_write_cmd(0x02); // 按列地址,从左到右,从上到下
spi_write_cmd(0xA1); // 设置列映射
spi_write_cmd(0xC8); // 设置行映射
spi_write_cmd(0xDA); // 设置COM硬件引脚配置
spi_write_cmd(0x12); // 默认值
spi_write_cmd(0x81); // 对比度设置
spi_write_cmd(0xCF); // 默认值
spi_write_cmd(0xD9); // 设置预充电周期
spi_write_cmd(0xF1); // 默认值
spi_write_cmd(0xDB); // 设置VCOMH电压倍率
spi_write_cmd(0x40); // 默认值
spi_write_cmd(0xA4); // 全局显示开启
spi_write_cmd(0xA6); // 设置显示方式,白色显示
spi_write_cmd(0xAF); // 开启显示
oled_clear(); // 清屏
}
// 设置显示位置
void oled_set_pos(unsigned char x, unsigned char y) {
spi_write_cmd(CMD_SET_COL_ADDR);
spi_write_cmd(x);
spi_write_cmd(OLED_WIDTH - 1);
spi_write_cmd(CMD_SET_PAGE_ADDR);
spi_write_cmd(y / 8);
spi_write_cmd(OLED_HEIGHT / 8 - 1);
}
// 清屏
void oled_clear() {
unsigned char i, j;
for (i = 0; i < 8; i++) {
oled_set_pos(0, i);
for (j = 0; j < OLED_WIDTH; j++) {
spi_write_data(0x00);
}
}
}
// 在指定位置显示字符串
void oled_show_string(unsigned char x, unsigned char y, const char *str) {
unsigned char i = 0;
while (str[i] != '\0') {
oled_show_char(x + i * 6, y, str[i]);
i++;
}
}
// 在指定位置显示一个字符
void oled_show_char(unsigned char x, unsigned char y, unsigned char ch) {
unsigned char i, j;
for (i = 0; i < 6; i++) {
unsigned char byte = F6x8[ch - ' '][i];
for (j = 0; j < 8; j++) {
if (byte & 0x01) {
spi_write_data(0xff << (j % 8));
} else {
spi_write_data(0x00);
}
byte >>= 1;
}
oled_set_pos(x + i, y);
}
}
```
在上述代码中,我们使用了51单片机的SPI接口来驱动OLED显示屏。在初始化函数中,我们通过向OLED发送一系列的命令来配置OLED的参数,以及打开显示。在显示函数中,我们通过内置的字体表来逐个显示字符,并使用`spi_write_data()`函数向OLED发送相应的数据。需要注意的是,OLED的显示是按页来进行的,每页8个像素。因此,在设置显示位置时,需要将纵坐标除以8。
阅读全文