SF32 快速点屏指南
1. 前言
一直想diy一个手表来着,虽然有很多开源方案,看下来都不尽人意,项目一直搁置,直到思澈在b站发的视频就一直很期待上手终于等到了
SF32LB52x 是一系列用于超低功耗人工智能物联网(AIoT)场景下的高集成度、高性能 MCU 芯片。芯片采用了基于 Arm Cortex-M33 STAR-MC1 处理器的大小核架构,集成高性能2D/2.5D 图形引擎,人工智能神经网络加速器,双模蓝牙 5.3,以及音频 codec,可广泛用于腕带类可穿戴电子设备、智能移动终端、智能家居等各种应用场景
2. 准备工作
参考官方文档链接 安装环境和软件确保能编译并运行(留意一下SDK工程目录)
一块2.01inch 240*296 QSPI 屏幕ic inca3306 屏幕 链接鱼鹰光电
使用这个例程 SiFli-SDK-2.3.0\example\multimedia\lvgl\lvgl_v8_demos
3.修改驱动
用vscode打开 sdk目录
在sdk customer\peripherals中官方已经给我们写好了很多驱动啦,这里屏幕IC是INCA3306并不包含在内,
但是可以看到目录下有个icn3311
3.1 复制一份改名为icn3306,同时将.c文件也改为icn3306
修改SConscript 将LCD_USING_ICN3311改为LCD_USING_ICN3306
打开icn3306.c文件 将 ICN3311 全部替换为 ICN3306
3.2 修改ID
将
#define THE_LCD_ID 0x1133
改为
#define THE_LCD_ID 0x6033
3.3 修改qspi时钟频率(这里是用杜邦线连接开发板与屏幕稳妥起见,将原来的24M改为16M。10M也行毕竟在测试)
static const LCDC_InitTypeDef lcdc_int_cfg_spi =
{
.lcd_itf = QAD_SPI_ITF, //LCDC_INTF_SPI_NODCX_1DATA,
.freq = 16000000,
//.color_mode = LCDC_PIXEL_FORMAT_RGB888,
.color_mode = LCDC_PIXEL_FORMAT_RGB565,
.cfg = {
.spi = {
.dummy_clock = 0, //0: QAD-SPI/SPI3 1:SPI4
.syn_mode = HAL_LCDC_SYNC_DISABLE, //HAL_LCDC_SYNC_VER,
.vsyn_polarity = 0,
//default_vbp=2, frame rate=82, delay=115us,
//TODO: use us to define delay instead of cycle, delay_cycle=115*48
.vsyn_delay_us = 1000,
.hsyn_num = 0,
},
},
};
3.4 修改屏幕初始化命令 (LCD_Init 函数中)
厂家会提供初始化代码
这里直接放出icn3311中的代码供大家参考
/**
******************************************************************************
* @file ICN3306.c
* @author Sifli software development team
* @brief This file includes the LCD driver for ICN3306 LCD.
* @attention
******************************************************************************
*/
/**
* @attention
* Copyright (c) 2019 - 2022, Sifli Technology
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Sifli integrated circuit
* in a product or a software update for such product, must reproduce the above
* copyright notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Sifli nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Sifli integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY SIFLI TECHNOLOGY "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SIFLI TECHNOLOGY OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <rtthread.h>
#include "string.h"
#include "board.h"
#include "drv_io.h"
#include "drv_lcd.h"
#include "log.h"
#include "bf0_hal.h"
#define ROW_OFFSET (0x00)
#define COL_OFFSET (0x00) //ZhouMo modify
/**
* @brief ICN3306 chip IDs
*/
#define THE_LCD_ID 0x0633
/**
* @brief ICN3306 Size
*/
#define THE_LCD_PIXEL_WIDTH (240)
#define THE_LCD_PIXEL_HEIGHT (296)
/**
* @brief ICN3306 Registers
*/
#define REG_SW_RESET 0x01
#define REG_LCD_ID 0x04
#define REG_DSI_ERR 0x05
#define REG_POWER_MODE 0x0A
#define REG_SLEEP_IN 0x10
#define REG_SLEEP_OUT 0x11
#define REG_PARTIAL_DISPLAY 0x12
#define REG_DISPLAY_INVERSION 0x21
#define REG_DISPLAY_OFF 0x28
#define REG_DISPLAY_ON 0x29
#define REG_WRITE_RAM 0x2C
#define REG_READ_RAM 0x2E
#define REG_CASET 0x2A
#define REG_RASET 0x2B
#define REG_TEARING_EFFECT 0x35
#define REG_IDLE_MODE_OFF 0x38
#define REG_IDLE_MODE_ON 0x39
#define REG_COLOR_MODE 0x3A
#define REG_WBRIGHT 0x51 /* Write brightness*/
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINTF(...) LOG_I(__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
/*ICN3306 start colume & row must can be divided by 2, and roi width&height too.*/
#define LCD_ALIGN2(x) //((x) = (x) & (~1))
#define LCD_ALIGN1(x) //((x) = (0 == ((x) & 1)) ? (x - 1) : x)
#define QAD_SPI_ITF LCDC_INTF_SPI_DCX_4DATA
static const LCDC_InitTypeDef lcdc_int_cfg_spi =
{
.lcd_itf = QAD_SPI_ITF, //LCDC_INTF_SPI_NODCX_1DATA,
.freq = 16000000,
//.color_mode = LCDC_PIXEL_FORMAT_RGB888,
.color_mode = LCDC_PIXEL_FORMAT_RGB565,
.cfg = {
.spi = {
.dummy_clock = 0, //0: QAD-SPI/SPI3 1:SPI4
.syn_mode = HAL_LCDC_SYNC_DISABLE, //HAL_LCDC_SYNC_VER,
.vsyn_polarity = 0,
//default_vbp=2, frame rate=82, delay=115us,
//TODO: use us to define delay instead of cycle, delay_cycle=115*48
.vsyn_delay_us = 1000,
.hsyn_num = 0,
},
},
};
static LCDC_InitTypeDef lcdc_int_cfg;
static void LCD_WriteReg(LCDC_HandleTypeDef *hlcdc, uint16_t LCD_Reg, uint8_t *Parameters, uint32_t NbParameters);
static uint32_t LCD_ReadData(LCDC_HandleTypeDef *hlcdc, uint16_t RegValue, uint8_t ReadSize);
static void LCD_ReadMode(LCDC_HandleTypeDef *hlcdc, bool enable);
/**
* @brief spi read/write mode
* @param enable: false - write spi mode | true - read spi mode
* @retval None
*/
static void LCD_ReadMode(LCDC_HandleTypeDef *hlcdc, bool enable)
{
if (HAL_LCDC_IS_SPI_IF(lcdc_int_cfg.lcd_itf))
{
if (enable)
{
HAL_LCDC_SetFreq(hlcdc, 2000000); //read mode min cycle 300ns
}
else
{
HAL_LCDC_SetFreq(hlcdc, lcdc_int_cfg.freq); //Restore normal frequency
}
}
}
/**
* @brief Power on the LCD.
* @param None
* @retval None
*/
static void LCD_Init(LCDC_HandleTypeDef *hlcdc)
{
uint8_t parameter[14];
memcpy(&lcdc_int_cfg, &lcdc_int_cfg_spi, sizeof(lcdc_int_cfg));
rt_kprintf("\n ICN3306_Init lcdc_int_cfg_spi\n");
rt_kprintf("\n ICN3306_Init lcdc_int_cfg_spi----zhoumo\n");
/* Initialize ICN3306 low level bus layer ----------------------------------*/
memcpy(&hlcdc->Init, &lcdc_int_cfg, sizeof(LCDC_InitTypeDef));
LCD_DRIVER_DELAY_MS(100); //delay 10 ms
HAL_LCDC_Init(hlcdc);
// BSP_LCD_Reset(1);//Reset LCD
// LCD_DRIVER_DELAY_MS(10); //delay 20 ms
// BSP_LCD_Reset(0);
// LCD_DRIVER_DELAY_MS(200); //delay 20 ms
// BSP_LCD_Reset(1);
// LCD_DRIVER_DELAY_MS(200); //delay 100 ms
//software reset
LCD_WriteReg(hlcdc, 0x01, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
rt_kprintf("\n ICN3306_Init \n");
LCD_WriteReg(hlcdc, 0x11, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
parameter[0] = 0x00;
LCD_WriteReg(hlcdc, 0xFE, parameter, 1);
parameter[0] = 0x80;
LCD_WriteReg(hlcdc, 0xC4, parameter, 1);
parameter[0] = 0x00;
LCD_WriteReg(hlcdc, 0x35, parameter, 1);
// set RGB
parameter[0] = 0x55;
LCD_WriteReg(hlcdc, 0x3A, parameter, 1);
parameter[0] = 0x20;
LCD_WriteReg(hlcdc, 0x53, parameter, 1);
parameter[0] = 0x00;
LCD_WriteReg(hlcdc, 0x51, parameter, 1);
parameter[0] = 0xff;
LCD_WriteReg(hlcdc, 0x63, parameter, 1);
parameter[0] = 0x00;
parameter[1] = 0x00;
parameter[3] = 0x00;
parameter[4] = 0xEF;
LCD_WriteReg(hlcdc, 0x2A, parameter, 4);
parameter[0] = 0x00;
parameter[1] = 0x00;
parameter[3] = 0x01;
parameter[4] = 0x27;
LCD_WriteReg(hlcdc, 0x2B, parameter, 4);
LCD_WriteReg(hlcdc, 0x11, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(80);
LCD_WriteReg(hlcdc, 0x29, (uint8_t *)NULL, 0);
}
/**
* @brief Disables the Display.
* @param None
* @retval LCD Register Value.
*/
static uint32_t LCD_ReadID(LCDC_HandleTypeDef *hlcdc)
{
uint32_t data;
/*
data = LCD_ReadData(hlcdc,REG_CASET, 4);
DEBUG_PRINTF("\REG_CASET 0x%x \n", data);
data = LCD_ReadData(hlcdc,REG_RASET, 4);
DEBUG_PRINTF("\REG_RASET 0x%x \n", data);
*/
data = LCD_ReadData(hlcdc, REG_LCD_ID, 3);
rt_kprintf("\nICN3306_ReadID 0x%x \n", data);
data = LCD_ReadData(hlcdc, REG_RASET, 4);
rt_kprintf("\nICN3306_Read REG_RASET 0x%x \n", data);
#if 0
data = LCD_ReadData(hlcdc, 0x0a, 4);
DEBUG_PRINTF("\nICN3306_Read 0a 0x%x \n", data);
#endif
if (data)
{
DEBUG_PRINTF("LCD module use ICN3306 IC \n");
data = THE_LCD_ID;
}
data = THE_LCD_ID;
return data;
}
/**
* @brief Enables the Display.
* @param None
* @retval None
*/
static void LCD_DisplayOn(LCDC_HandleTypeDef *hlcdc)
{
/* Display On */
rt_kprintf("\n ICN3306_DisplayOn\n");
LCD_WriteReg(hlcdc, REG_DISPLAY_ON, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
LCD_WriteReg(hlcdc, REG_SLEEP_OUT, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
}
/**
* @brief Disables the Display.
* @param None
* @retval None
*/
static void LCD_DisplayOff(LCDC_HandleTypeDef *hlcdc)
{
/* Display Off */
LCD_WriteReg(hlcdc, REG_DISPLAY_OFF, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
LCD_WriteReg(hlcdc, REG_SLEEP_IN, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
}
static void LCD_SetRegion(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint8_t parameter[4];
LCD_ALIGN2(Xpos0);
LCD_ALIGN2(Ypos0);
LCD_ALIGN1(Xpos1);
LCD_ALIGN1(Ypos1);
HAL_LCDC_SetROIArea(hlcdc, Xpos0, Ypos0, Xpos1, Ypos1);
Xpos0 += COL_OFFSET;
Xpos1 += COL_OFFSET;
Ypos0 += ROW_OFFSET;
Ypos1 += ROW_OFFSET;
parameter[0] = (Xpos0) >> 8;
parameter[1] = (Xpos0) & 0xFF;
parameter[2] = (Xpos1) >> 8;
parameter[3] = (Xpos1) & 0xFF;
LCD_WriteReg(hlcdc, REG_CASET, parameter, 4);
parameter[0] = (Ypos0) >> 8;
parameter[1] = (Ypos0) & 0xFF;
parameter[2] = (Ypos1) >> 8;
parameter[3] = (Ypos1) & 0xFF;
LCD_WriteReg(hlcdc, REG_RASET, parameter, 4);
}
/**
* @brief Writes pixel.
* @param Xpos: specifies the X position.
* @param Ypos: specifies the Y position.
* @param RGBCode: the RGB pixel color
* @retval None
*/
static void LCD_WritePixel(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos, uint16_t Ypos, const uint8_t *RGBCode)
{
uint8_t data = 0;
uint8_t parameter[4];
LCD_ALIGN2(Xpos);
LCD_ALIGN2(Ypos);
rt_kprintf("\n ICN3306_WritePixel xpos=%d, ypos=%d\n", Xpos, Ypos);
if ((Xpos >= THE_LCD_PIXEL_WIDTH) || (Ypos >= THE_LCD_PIXEL_HEIGHT))
{
return;
}
/* Set Cursor */
LCD_SetRegion(hlcdc, Xpos, Ypos, Xpos, Ypos);
LCD_WriteReg(hlcdc, REG_WRITE_RAM, (uint8_t *)RGBCode, 2);
}
static void LCD_WriteMultiplePixels(LCDC_HandleTypeDef *hlcdc, const uint8_t *RGBCode, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint32_t size;
LCD_ALIGN2(Xpos0);
LCD_ALIGN2(Ypos0);
LCD_ALIGN1(Xpos1);
LCD_ALIGN1(Ypos1);
uint32_t data;
//data = LCD_ReadData(hlcdc, 0x05, 3);
//DEBUG_PRINTF("DSI ERROR= 0x%x \n", data);
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, ((0x32 << 24) | (REG_WRITE_RAM << 8)), 4);
}
else
{
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, REG_WRITE_RAM, 1);
}
}
/**
* @brief Writes to the selected LCD register.
* @param LCD_Reg: address of the selected register.
* @retval None
*/
static void LCD_WriteReg(LCDC_HandleTypeDef *hlcdc, uint16_t LCD_Reg, uint8_t *Parameters, uint32_t NbParameters)
{
if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
uint32_t cmd;
cmd = (0x02 << 24) | (LCD_Reg << 8);
if (0 != NbParameters)
{
/* Send command's parameters if any */
HAL_LCDC_WriteU32Reg(hlcdc, cmd, Parameters, NbParameters);
}
else
{
uint32_t v = 0;
HAL_LCDC_WriteU32Reg(hlcdc, cmd, (uint8_t *)&v, 1);
}
}
else
{
HAL_LCDC_WriteU8Reg(hlcdc, LCD_Reg, Parameters, NbParameters);
}
}
/**
* @brief Reads the selected LCD Register.
* @param RegValue: Address of the register to read
* @param ReadSize: Number of bytes to read
* @retval LCD Register Value.
*/
static uint32_t LCD_ReadData(LCDC_HandleTypeDef *hlcdc, uint16_t RegValue, uint8_t ReadSize)
{
uint32_t rd_data = 0;
LCD_ReadMode(hlcdc, true);
if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
HAL_LCDC_ReadU32Reg(hlcdc, ((0x03 << 24) | (RegValue << 8)), (uint8_t *)&rd_data, ReadSize);
}
else
{
HAL_LCDC_ReadU8Reg(hlcdc, RegValue, (uint8_t *)&rd_data, ReadSize);
}
LCD_ReadMode(hlcdc, false);
return rd_data;
}
static uint32_t LCD_ReadPixel(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos, uint16_t Ypos)
{
uint8_t r, g, b;
uint32_t ret_v, read_value;
DEBUG_PRINTF("ICN3306_ReadPixel[%d,%d]\n", Xpos, Ypos);
LCD_ALIGN2(Xpos);
LCD_ALIGN2(Ypos);
LCD_SetRegion(hlcdc, Xpos, Ypos, Xpos, Ypos);
read_value = LCD_ReadData(hlcdc, REG_READ_RAM, 4);
DEBUG_PRINTF("result: [%x]\n", read_value);
b = (read_value >> 0) & 0xFF;
g = (read_value >> 8) & 0xFF;
r = (read_value >> 16) & 0xFF;
DEBUG_PRINTF("r=%d, g=%d, b=%d \n", r, g, b);
switch (lcdc_int_cfg.color_mode)
{
case LCDC_PIXEL_FORMAT_RGB565:
ret_v = (uint32_t)(((r << 11) & 0xF800) | ((g << 5) & 0x7E0) | ((b >> 3) & 0X1F));
break;
/*
(8bit R + 3bit dummy + 8bit G + 3bit dummy + 8bit B)
*/
case LCDC_PIXEL_FORMAT_RGB888:
ret_v = (uint32_t)(((r << 16) & 0xFF0000) | ((g << 8) & 0xFF00) | ((b) & 0XFF));
break;
default:
RT_ASSERT(0);
break;
}
//LCD_WriteReg(hlcdc,REG_COLOR_MODE, parameter, 1);
return ret_v;
}
static void LCD_SetColorMode(LCDC_HandleTypeDef *hlcdc, uint16_t color_mode)
{
uint8_t parameter[2];
switch (color_mode)
{
case RTGRAPHIC_PIXEL_FORMAT_RGB565:
/* Color mode 16bits/pixel */
parameter[0] = 0x75;
lcdc_int_cfg.color_mode = LCDC_PIXEL_FORMAT_RGB565;
break;
case RTGRAPHIC_PIXEL_FORMAT_RGB888:
parameter[0] = 0x77;
lcdc_int_cfg.color_mode = LCDC_PIXEL_FORMAT_RGB888;
break;
default:
return; //unsupport
break;
}
LCD_WriteReg(hlcdc, REG_COLOR_MODE, parameter, 1);
HAL_LCDC_SetOutFormat(hlcdc, lcdc_int_cfg.color_mode);
}
#define ICN3306_BRIGHTNESS_MAX 0xFF
static void LCD_SetBrightness(LCDC_HandleTypeDef *hlcdc, uint8_t br)
{
uint8_t bright = (uint8_t)((int)ICN3306_BRIGHTNESS_MAX * br / 100);
LCD_WriteReg(hlcdc, REG_WBRIGHT, &bright, 1);
}
static const LCD_DrvOpsDef ICN3306_drv =
{
LCD_Init,
LCD_ReadID,
LCD_DisplayOn,
LCD_DisplayOff,
LCD_SetRegion,
LCD_WritePixel,
LCD_WriteMultiplePixels,
LCD_ReadPixel,
LCD_SetColorMode,
LCD_SetBrightness
};
LCD_DRIVER_EXPORT2(ICN3306, THE_LCD_ID, &lcdc_int_cfg,
&ICN3306_drv, 2);
/************************ (C) COPYRIGHT Sifli Technology *******END OF FILE****/
3.5 修改customer\peripherals\Kconfig
这里没添加会导致驱动不编译(别问我为什么)
打开Kconfig 搜索 3311
复制一份加到下面 (注意修改为3306)
3.6 修改customer\boards\Kconfig_lcd
这里新增一块屏幕,在menuconfig中会用到
- 添加新的屏幕模组
# add by ZhouMo 2025-02-17
config LCD_USING_AMOLED_ICNA3306
bool "2.01 inch QSPI AMOLED Module(240*296 IC-ICNA3306)"
select TSC_USING_CST816 if BSP_USING_TOUCHD
select LCD_USING_ICN3306
select BSP_LCDC_USING_QADSPI
# select LCD_USING_PWM_AS_BACKLIGHT
if LCD_USING_AMOLED_ICNA3306
config LCD_ICN3306_VSYNC_ENABLE
bool "Enable AMOLED VSYNC (TE signal)"
def_bool n
endif
- 添加的屏幕定义分辨率
在config LCD_HOR_RES_MAX
# add by ZhouMo 2025-02-17
default 240 if LCD_USING_AMOLED_ICNA3306
在config LCD_VER_RES_MAX
# add by ZhouMo 2025-02-17
default 296 if LCD_USING_AMOLED_ICNA3306
- 添加新的屏幕DPI
在 config LCD_DPI
# add by ZhouMo 2025-02-17
default 315 if LCD_USING_AMOLED_ICNA3306
3.7 menuconfig 配置
在你的lvgl_v8_demos/project/ 中右键打开
输入
menuconfig --board=em-lb525
回车
选择
按q 再按y 保存退出
执行编译命令
scons --board=em-lb525 -j8
然后烧录到开发板中
恭喜你 离屏幕点亮只差一步
4. 接线
qspi引脚在customer\boards\sf32lb52-devkit-lcd\bsp_pinmux.c 中有定义
目前我点的qspi屏都有reset引脚,这里并没定义,在LCD_Init 函数中直接使用的software reset (嘿嘿又省下一个pin)
到这里屏幕应该就能点亮了
5.避坑
- 屏幕出现画面扭曲,可能是需要像素对齐,在 icn3306.c 中
将
LCD_DRIVER_EXPORT2(ICN3306, THE_LCD_ID, &lcdc_int_cfg,
&ICN3306_drv, 1);
改为
LCD_DRIVER_EXPORT2(ICN3306, THE_LCD_ID, &lcdc_int_cfg,
&ICN3306_drv, 2);
- 出现花边请设置偏移量
在icn3306.c 中
#define ROW_OFFSET (0x00)
#define COL_OFFSET (0x00) //ZhouMo modify
- 屏幕上的 VDD GND 尽量都接上,不然可能会出现抖屏,横线闪烁,偏色等问题!!!
6.参考链接
7.写在末尾
这里关于为什么直接用3311 的驱动改是因为同一品牌寄存器都大差不差所以能改改直接用
点屏步骤大致都相同,其他ic也可以参考此教程
有任何问题欢迎大家到下方留言,祝大家早日点亮自己的屏幕
本文以CC-BY-NC许可发布,当您转载该文章时,需要署名,且不能用于商业用途。特别申明,不能转载到C**N平台。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升