rk3328点spi-oled屏(单色OLED)

本文档提供了一段用于驱动SH1106单色OLED显示IC的Linux内核代码,该代码基于fbtft框架,并在DTS中配置了SPI接口参数。代码中包含了初始化序列、设置地址窗口、灰度控制等功能,适用于128x64分辨率的显示屏。此外,还展示了如何通过GPIO控制DC和RESET引脚。
摘要由CSDN通过智能技术生成

介绍:spi-单色oled  IC=sh1106 分辨率128x64

1:DTS

&spi0{
	status = "okay";
	//max-freq = <1200000>;
	//dma-name = "tx","rx";  //enable dma
	pinctrl-names = "default";
	pinctrl-0 = <&spi0m2_clk &spi0m2_cs0 &spi0m2_tx &spi0m2_rx>;

       st7789v@0 {
			status = "disabled"; //status = "okay";
            compatible = "sitronix,st7789v";
            reg = <0>;
	
            spi-max-frequency = <32000000>;           
			bgr;
            fps = <30>;
			rotate = <90>;
            buswidth = <8>; 
			dc-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;  /* gpio3 A5 */
            reset-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>; /* gpio3 A6 */
            led-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;  /* gpio3 A4 */ //注意背光io集性          
            debug = <0>; //等级0~7 越高信息越多
       };
       sh1106@0 {
			status = "okay";
            compatible = "sinowealth,sh1106";
            reg = <0>;	
            spi-max-frequency = <12000000>;           
			bgr;
            fps = <30>;
			//rotate = <90>;
            buswidth = <8>; 
			dc-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;  /* gpio3 A5 */
            reset-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>; /* gpio3 A6 */
            led-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;  /* gpio3 A4 */ //注意背光io集性          
            debug = <0>; //等级0~7 越高信息越多
       }; 
 	

};

2:C-code  linux自带 没有动

// SPDX-License-Identifier: GPL-2.0+
/*
 * FB driver for the SH1106 OLED Controller
 * Based on the SSD1306 driver by Noralf Tronnes
 *
 * Copyright (C) 2017 Heiner Kallweit
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio/consumer.h>
#include <linux/delay.h>

#include "fbtft.h"

#define DRVNAME		"fb_sh1106"
#define WIDTH		128
#define HEIGHT		64

/* Init sequence based on the Adafruit SSD1306 Arduino library */
static int init_display(struct fbtft_par *par)
{
	if (!par->info->var.xres || par->info->var.xres > WIDTH ||
	    !par->info->var.yres || par->info->var.yres > HEIGHT ||
	    par->info->var.yres % 8) {
		dev_err(par->info->device, "Invalid screen size\n");
		return -EINVAL;
	}

	if (par->info->var.rotate) {
		dev_err(par->info->device, "Display rotation not supported\n");
		return -EINVAL;
	}

	par->fbtftops.reset(par);

	/* Set Display OFF */
	write_reg(par, 0xAE);

	/* Set Display Clock Divide Ratio/ Oscillator Frequency */
	write_reg(par, 0xD5, 0x80);

	/* Set Multiplex Ratio */
	write_reg(par, 0xA8, par->info->var.yres - 1);

	/* Set Display Offset */
	write_reg(par, 0xD3, 0x00);

	/* Set Display Start Line */
	write_reg(par, 0x40 | 0x0);

	/* Set Segment Re-map */
	/* column address 127 is mapped to SEG0 */
	write_reg(par, 0xA0 | 0x1);

	/* Set COM Output Scan Direction */
	/* remapped mode. Scan from COM[N-1] to COM0 */
	write_reg(par, 0xC8);

	/* Set COM Pins Hardware Configuration */
	if (par->info->var.yres == 64)
		/* A[4]=1b, Alternative COM pin configuration */
		write_reg(par, 0xDA, 0x12);
	else if (par->info->var.yres == 48)
		/* A[4]=1b, Alternative COM pin configuration */
		write_reg(par, 0xDA, 0x12);
	else
		/* A[4]=0b, Sequential COM pin configuration */
		write_reg(par, 0xDA, 0x02);

	/* Set Pre-charge Period */
	write_reg(par, 0xD9, 0xF1);

	/* Set VCOMH Deselect Level */
	write_reg(par, 0xDB, 0x40);

	/* Set Display ON */
	write_reg(par, 0xAF);

	msleep(150);

	return 0;
}

static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
}

static int blank(struct fbtft_par *par, bool on)
{
	fbtft_par_dbg(DEBUG_BLANK, par, "(%s=%s)\n",
		      __func__, on ? "true" : "false");

	write_reg(par, on ? 0xAE : 0xAF);

	return 0;
}

/* Gamma is used to control Contrast */
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
	/* apply mask */
	curves[0] &= 0xFF;

	/* Set Contrast Control for BANK0 */
	write_reg(par, 0x81, curves[0]);

	return 0;
}

static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
	u16 *vmem16 = (u16 *)par->info->screen_buffer;
	u32 xres = par->info->var.xres;
	int page, page_start, page_end, x, i, ret;
	u8 *buf = par->txbuf.buf;

	/* offset refers to vmem with 2 bytes element size */
	page_start = offset / (8 * 2 * xres);
	page_end = DIV_ROUND_UP(offset + len, 8 * 2 * xres);

	for (page = page_start; page < page_end; page++) {
		/* set page and set column to 2 because of vidmem width 132 */
		write_reg(par, 0xb0 | page, 0x00 | 2, 0x10 | 0);

		memset(buf, 0, xres);
		for (x = 0; x < xres; x++)
			for (i = 0; i < 8; i++)
				if (vmem16[(page * 8 + i) * xres + x])
					buf[x] |= BIT(i);

		/* Write data */
		ret = fbtft_write_buf_dc(par, buf, xres, 1);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static void write_register(struct fbtft_par *par, int len, ...)
{
	va_list args;
	int i;

	va_start(args, len);

	for (i = 0; i < len; i++)
		par->buf[i] = va_arg(args, unsigned int);

	/* keep DC low for all command bytes to transfer */
	fbtft_write_buf_dc(par, par->buf, len, 0);

	va_end(args);
}

static struct fbtft_display display = {
	.regwidth = 8,
	.width = WIDTH,
	.height = HEIGHT,
	.txbuflen = WIDTH,
	.gamma_num = 1,
	.gamma_len = 1,
	/* set default contrast to 0xcd = 80% */
	.gamma = "cd",
	.fbtftops = {
		.write_vmem = write_vmem,
		.write_register = write_register,
		.init_display = init_display,
		.set_addr_win = set_addr_win,
		.blank = blank,
		.set_gamma = set_gamma,
	},
};

FBTFT_REGISTER_DRIVER(DRVNAME, "sinowealth,sh1106", &display);

MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:sh1106");
MODULE_ALIAS("platform:sh1106");

MODULE_DESCRIPTION("SH1106 OLED Driver");
MODULE_AUTHOR("Heiner Kallweit");
MODULE_LICENSE("GPL");

sh1106加载OK

 

点亮效果--屏为单色OLED 所有只是白色!

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
7针SPI接口OLED幕工作原理如下: OLED(Organic Light-Emitting Diode),即有机发光二极管,是一种采用有机材料制成的发光显示技术。它与传统的液晶显示技术不同,不需要背光源,在电流的激励下,有机材料能够直接发光。 OLED幕使用7针SPI接口进行通信连接。SPI(Serial Peripheral Interface)是一种串行外设接口,通过时钟、数据输入和输出、片选等引脚实现设备之间的数据传输。其中,7针SPI接口可以具体分为以下几个部分来解释: 1. 电源引脚:通常有VCC和GND两个引脚,分别提供电源和接地。 2. SPI时钟引脚(SCLK):通过这个引脚传输时钟信号,控制数据的传输速度。 3. 数据引脚(SDA):通过这个引脚传输数据,包括指令和像素信息。 4. 片选引脚(CS):通过这个引脚选择与OLED幕进行通信的设备。 5. 复位引脚(RST):通过这个引脚对OLED幕进行复位操作,初始化显示参数。 6. 数据/命令引脚(D/C):通过这个引脚发送数据或者命令给OLED幕,区分是发送数据还是发送控制信息。 7. 开关引脚(BS1/BS0):用于选择OLED幕的工作模式,设置幕的亮度和对比度等参数。 OLED幕首先通过SPI接口与主控设备进行通信,发送初始化命令和显示数据。主控设备通过SCLK引脚提供时钟信号,通过SDA引脚发送给OLED幕并接收从幕返回的数据。同时,D/C引脚和CS引脚用于发送不同的命令或数据OLED幕接收到数据后,根据主控设备发送的指令和数据进行处理,将图像或文本信息通过有机材料发光显示出来。由于OLED幕采用的是有机材料,能够直接发光,在显示效果上具有更高的色彩饱和度和对比度,同时还有更快的响应速度和更广的可视角度。 总结起来,7针SPI接口是用于OLED幕与主控设备进行通信的接口,通过发送时钟信号和数据,实现显示内容的刷新和更新。而OLED幕通过有机材料发光原理,将数据转换为可见光信号,从而实现图像和文字的显示。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值