友善之臂NanoPi NEO利用fbtft驱动点亮1.69寸ST7789V2屏幕

news/2025/1/1 9:44:11/

屏幕介绍

本文以中景园1.69LCD,驱动芯片ST7789V2该款屏幕示例,屏幕的分辨率为240*280

1.69寸屏幕

屏幕引脚说明

屏幕接线说明

NanoPi NEO IO介绍

NanoPi io介绍

屏幕与板子的IO连接关系

屏幕NanoPi NEO
GNDGND
VCC3.3V
SCLPC2
SDAPC0
RESPG11
DCPA1
CSPC3
BLKPA0

下载交叉编译器和linux内核源码并按教程配置好开发环境

参考友善官方链接:Building U-boot and Linux for H5/H3/H2+/zh


修改设备树

需要修改的设备树文件路径:

linux/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi

找到其中spi0节点,修改为如下:

&spi0 {/* needed to avoid dtc warning */#address-cells = <1>;#size-cells = <0>;status = "okay";pinctrl-names = "default";pinctrl-0 = <&spi0_pins &spi0_cs_pins>;cs-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>;spidev0: spi@0 {compatible = "nanopi,spidev";reg = <0>;status = "disabled";spi-max-frequency = <10000000>;};spiflash: spiflash@0 {#address-cells = <1>;#size-cells = <1>;compatible = "mxicy,mx25l12805d";reg = <0>;status = "disabled";spi-max-frequency = <50000000>;mode = <0>;partition@0 {reg = <0x0 0x1000000>;label = "spi-flash";};};pitft: pitft@0{compatible = "sitronix,st7789v";reg = <0>;status = "okay"; /* 使能 */spi-max-frequency = <96000000>; /* 修改了默认速度 */rotate = <90>;/* 初始默认旋转了90度 横屏 */fps = <33>;buswidth = <8>;dc-gpios = <&pio 0 1 GPIO_ACTIVE_HIGH>;  /* PA1 */reset-gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */led-gpios = <&pio 0 0 GPIO_ACTIVE_LOW>;  /* PA0 */debug = <0x0>;};pitft_ts: pitft-ts@1 {compatible = "ti,ads7846";reg = <1>;status = "disabled";spi-max-frequency = <2000000>;interrupt-parent = <&pio>;interrupts = <6 9 IRQ_TYPE_EDGE_FALLING>;   /* PG9 / EINT9 */pendown-gpio = <&pio 6 9 GPIO_ACTIVE_LOW>;ti,swap-xy;ti,vref-delay-usecs = <1000>;ti,x-min = /bits/ 16 <100>;ti,x-max = /bits/ 16 <0xfff>;ti,y-min = /bits/ 16 <100>;ti,y-max = /bits/ 16 <0xfff>;ti,vref-mv = <3300>;ti,x-plate-ohms = /bits/ 16 <256>;ti,penirq-recheck-delay-usecs = <10>;ti,settle-delay-usec = /bits/ 16 <100>;ti,keep-vref-on = <1>;ti,pressure-max = /bits/ 16 <0xfff>;ti,debounce-max = <10>;ti,debounce-tol = <30>;ti,debounce-rep = <1>;};
};

找到pio节点,添加屏幕其它控制引脚的io

&pio {leds_npi: led_pins {pins = "PA10";function = "gpio_out";};lcd_reset_pins: lcd_reset_pins {pins = "PG11";function = "gpio_out";};lcd_dc_pins: lcd_dc_pins {pins = "PA1";function = "gpio_out";};lcd_led_pins: lcd_led_pins {pins = "PA0";function = "gpio_out";};spi0_cs_pins: spi0_cs_pins {pins = "PC3", "PA6";function = "gpio_out";};
};

禁用hdmi音频视频输出,否则屏幕不显示

&hdmi {#status = "okay";status = "disabled";
};&hdmi_out {hdmi_out_con: endpoint {remote-endpoint = <&hdmi_con_in>;};
};&sound_hdmi {#status = "okay";status = "disabled";
};

修改驱动文件

linux/drivers/staging/fbtft/路径下,找到fb_st7789v.c,根据自己屏幕情况修改相关参数本人移植时,出现屏幕颜色不对,坐标偏移等情况,根据中景园提供的驱动程序对该文件进行了一定修改,本人用途屏幕旋转90度横屏使用,只做了横屏坐标校准,其它旋转角度下坐标不准只需要修改set_addr_win函数内的坐标偏移即可,至此代码修改内容全部完成

/** FB driver for the ST7789V LCD Controller** Copyright (C) 2015 Dennis Menschel** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU General Public License for more details.*/#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <video/mipi_display.h>
#include <linux/gpio.h>#include "fbtft.h"#define DRVNAME "fb_st7789v"#define DEFAULT_GAMMA \"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"/*** enum st7789v_command - ST7789V display controller commands** @PORCTRL: porch setting* @GCTRL: gate control* @VCOMS: VCOM setting* @VDVVRHEN: VDV and VRH command enable* @VRHS: VRH set* @VDVS: VDV set* @VCMOFSET: VCOM offset set* @PWCTRL1: power control 1* @PVGAMCTRL: positive voltage gamma control* @NVGAMCTRL: negative voltage gamma control** The command names are the same as those found in the datasheet to ease* looking up their semantics and usage.** Note that the ST7789V display controller offers quite a few more commands* which have been omitted from this list as they are not used at the moment.* Furthermore, commands that are compliant with the MIPI DCS have been left* out as well to avoid duplicate entries.*/
enum st7789v_command {PORCTRL = 0xB2,GCTRL = 0xB7,VCOMS = 0xBB,VDVVRHEN = 0xC2,VRHS = 0xC3,VDVS = 0xC4,VCMOFSET = 0xC5,PWCTRL1 = 0xD0,PVGAMCTRL = 0xE0,NVGAMCTRL = 0xE1,
};#define MADCTL_BGR BIT(3) /* bitmask for RGB/BGR order */
#define MADCTL_MV BIT(5) /* bitmask for page/column order */
#define MADCTL_MX BIT(6) /* bitmask for column address order */
#define MADCTL_MY BIT(7) /* bitmask for page address order *//*** init_display() - initialize the display controller** @par: FBTFT parameter object** Most of the commands in this init function set their parameters to the* same default values which are already in place after the display has been* powered up. (The main exception to this rule is the pixel format which* would default to 18 instead of 16 bit per pixel.)* Nonetheless, this sequence can be used as a template for concrete* displays which usually need some adjustments.** Return: 0 on success, < 0 if error occurred.*/
static int init_display(struct fbtft_par *par)
{/* turn off sleep mode */write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);mdelay(120);
#if 0/* set pixel format to RGB-565 */write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);write_reg(par, PORCTRL, 0x08, 0x08, 0x00, 0x22, 0x22);/** VGH = 13.26V* VGL = -10.43V*/write_reg(par, GCTRL, 0x35);/** VDV and VRH register values come from command write* (instead of NVM)*/write_reg(par, VDVVRHEN, 0x01, 0xFF);/** VAP =  4.1V + (VCOM + VCOM offset + 0.5 * VDV)* VAN = -4.1V + (VCOM + VCOM offset + 0.5 * VDV)*/write_reg(par, VRHS, 0x0B);/* VDV = 0V */write_reg(par, VDVS, 0x20);/* VCOM = 0.9V */write_reg(par, VCOMS, 0x20);/* VCOM offset = 0V */write_reg(par, VCMOFSET, 0x20);/** AVDD = 6.8V* AVCL = -4.8V* VDS = 2.3V*/write_reg(par, PWCTRL1, 0xA4, 0xA1);write_reg(par, MIPI_DCS_SET_DISPLAY_ON);#endifwrite_reg(par, 0x3A,0x05);write_reg(par, 0xB2,0x0C,0x0C,0x00,0x33,0x33);write_reg(par, 0xB7,0x35);write_reg(par, 0xBB,0x32);    write_reg(par, 0xC2,0x01);  write_reg(par, 0xC3,0x15);    write_reg(par, 0xC4,0x20);write_reg(par, 0xC6,0x0F);write_reg(par, 0xD0,0xA4,0xA1);write_reg(par,PVGAMCTRL,0xD0,0x08,0x0E,0x09,0x09,0x05,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34);write_reg(par,NVGAMCTRL, 0xD0,0x08,0x0E,0x09,0x09,0x15,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34);write_reg(par,0x21); write_reg(par,0x29);return 0;
}/*** set_var() - apply LCD properties like rotation and BGR mode** @par: FBTFT parameter object** Return: 0 on success, < 0 if error occurred.*/
static int set_var(struct fbtft_par *par)
{u8 madctl_par = 0;if (par->bgr)madctl_par |= MADCTL_BGR;switch (par->info->var.rotate) {case 0:break;case 90: madctl_par |= (MADCTL_MV | MADCTL_MY);break;case 180:madctl_par |= (MADCTL_MX | MADCTL_MY);break;case 270:madctl_par |= (MADCTL_MV | MADCTL_MX);break;default:return -EINVAL;}write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);return 0;
}/*** set_gamma() - set gamma curves** @par: FBTFT parameter object* @curves: gamma curves** Before the gamma curves are applied, they are preprocessed with a bitmask* to ensure syntactically correct input for the display controller.* This implies that the curves input parameter might be changed by this* function and that illegal gamma values are auto-corrected and not* reported as errors.** Return: 0 on success, < 0 if error occurred.*/
static int set_gamma(struct fbtft_par *par, u32 *curves)
{int i;int j;int c; /* curve index offset *//** Bitmasks for gamma curve command parameters.* The masks are the same for both positive and negative voltage* gamma curves.*/static const u8 gamma_par_mask[] = {0xFF, /* V63[3:0], V0[3:0]*/0x3F, /* V1[5:0] */0x3F, /* V2[5:0] */0x1F, /* V4[4:0] */0x1F, /* V6[4:0] */0x3F, /* J0[1:0], V13[3:0] */0x7F, /* V20[6:0] */0x77, /* V36[2:0], V27[2:0] */0x7F, /* V43[6:0] */0x3F, /* J1[1:0], V50[3:0] */0x1F, /* V57[4:0] */0x1F, /* V59[4:0] */0x3F, /* V61[5:0] */0x3F, /* V62[5:0] */};for (i = 0; i < par->gamma.num_curves; i++) {c = i * par->gamma.num_values;for (j = 0; j < par->gamma.num_values; j++)curves[c + j] &= gamma_par_mask[j];write_reg(par, PVGAMCTRL + i,curves[c + 0], curves[c + 1], curves[c + 2],curves[c + 3], curves[c + 4], curves[c + 5],curves[c + 6], curves[c + 7], curves[c + 8],curves[c + 9], curves[c + 10], curves[c + 11],curves[c + 12], curves[c + 13]);}return 0;
}
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{switch(par->info->var.rotate){case   0: xs+=0;xe+=0;ys+=0;ye+=0;break;case  90: xs+=20;xe+=20;ys+=0;ye+=0;break;case 180: xs+=0;xe+=0;ys+=80;ye+=80;break;case 270: xs+=0;xe+=0;ys+=53;ye+=53;break;default :break;}write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}/*** blank() - blank the display** @par: FBTFT parameter object* @on: whether to enable or disable blanking the display** Return: 0 on success, < 0 if error occurred.*/
static int blank(struct fbtft_par *par, bool on)
{if (on)write_reg(par, MIPI_DCS_SET_DISPLAY_OFF);elsewrite_reg(par, MIPI_DCS_SET_DISPLAY_ON);return 0;
}static struct fbtft_display display = {.regwidth = 8,.width = 240,.height = 280,.gamma_num = 2,.gamma_len = 14,.gamma = DEFAULT_GAMMA,.fbtftops = {.init_display = init_display,.set_var = set_var,.set_addr_win = set_addr_win,.set_gamma = set_gamma,.blank = blank,},
};FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display);MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v");
MODULE_ALIAS("platform:st7789v");MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");

使用menuconfig使能该驱动

linux源码根目录下执行

make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-
Device Drivers  --->  [*] Staging drivers  --->  <*>   Support for small TFT LCD display modules  ---><*> FB driver for the ST7789V LCD Controller

编译内核设备树

# 编译内核、设备树、模块
make zImage dtbs modules ARCH=arm CROSS_COMPILE=arm-linux- 

更新板子内核和设备树文件

arch/arm/boot/zImage内核镜像文件和arch/arm/boot/dts/sun8i-h3-nanopi-neo.dtb 设备树文件拷贝到板子的/boot目录下,使用内存卡拷贝或者网络传输都可以,这里以网络更新为例

scp arch/arm/boot/zImage root@192.168.31.88:/boot
scp arch/arm/boot/dts/sun8i-h3-nanopi-neo.dtb root@192.168.31.88:/boot

重启板子后屏幕可以出现内核启动和linux终端画面

这里开机logo已经修改,原系统是三只linux企鹅图标

开机图片
开机logo显示

终端画面

后期玩法

画一张带屏幕的接口板与板子组合成一体,可以移植lvgl或者QT,真正变成一个小电脑

参考链接:NanoPi NEO Air使用十二:使用自带的fbtft驱动点亮SPI接口TFT屏幕,ST7789V


http://www.ppmy.cn/news/1026139.html

相关文章

第48节:cesium 面交集计算(含源码+视频)

结果示例: 完整源码: <template><div class="viewer"><vc-viewer @ready="ready" :logo="false"><vc-navigation

【数据结构与算法】二分查找算法(非递归)

二分查找算法&#xff08;非递归&#xff09; 介绍 二分查找只适用于从有序的数列中进行查找&#xff08;比如数字和字母等&#xff09;&#xff0c;将数列排序后再进行查找。二分查找法的运行时间为对数时间O(log2n)&#xff0c;即查找到所需要的目标位置最多只需要log2n步&…

逆向破解学习-割绳子

试玩 支付失败&#xff0c;请检查网络设置 Hook成功 Hook代码 import android.app.Application; import android.content.Context;import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_…

实验二十六、RC桥式正弦波振荡电路参数选择

一、题目 电路如图1所示。利用 Multisim 分析下列问题&#xff1a; &#xff08;1&#xff09;选择合适的 R f R_f Rf​ 和稳压管&#xff0c;使电路产生正弦波振荡&#xff0c;并观察起振过程&#xff1b; &#xff08;2&#xff09;调整电路参数&#xff0c;使输出电压峰值…

cookie是什么?

cookie是什么&#xff1f; Cookie实际上是一小段的文本信息。 http协议本身是无状态的。无状态是指Web浏览器与Web服务器之间不需要建立持久的连接&#xff0c;这意味着当一个客户端向服务器端发出请求&#xff0c;然后Web服务器返回响应&#xff08;Response&#xff09;&…

光致发光二极管光源——荧光效率检测系统

发光二极管&#xff08;LED&#xff09;光源已经逐步地取代传统光源&#xff0c;并在生产和生活中得以广泛应用。荧光粉在LED照明设备中起到了至关重要的作用&#xff0c;其功能为将转换芯片所产生的紫外或者蓝光&#xff0c;发射出目标颜色的光。近年来&#xff0c;人们为了提…

【Matlab智能算法】RBF神经网络-遗传算法(RBF-GA)函数极值寻优——非线性函数求极值

上一篇博客介绍了GRNN-GA&#xff1a;GRNN神经网络遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值&#xff0c;神经网络用的是GRNN神经网络&#xff0c;RBF神经网络&#xff08;径向基函数神经网络&#xff09;和GRNN神经网络有相似之处。本篇博客将GRNN神经网络替换成RBF…

【C++】多态(多态的构成条件,虚函数重写,override,final,覆盖隐藏对比)

文章目录 前言一、多态的定义及实现1.多态的构成条件&#xff1a; 二、虚函数1.虚函数的重写2.虚函数重写的例外&#xff08;协变&#xff09;3.析构函数的虚函数&#xff08;基类与派生类析构函数名字不同&#xff09;1.不加virtual的一般情况&#xff1a;2.不加virtual会出现…