ESP32 S3+3线SPI+HX8347

 HX8347 240*320 TFT屏 3线SPI(CS,SCL,SDI)用ESP32 S3驱动

一、源码

/* SPI Master exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"#include "pretty_effect.h"/*This code displays some fancy graphics on the 320x240 LCD on an ESP-WROVER_KIT board.This example demonstrates the use of both spi_device_transmit as well asspi_device_queue_trans/spi_device_get_trans_result and pre-transmit callbacks.Some info about the ILI9341/ST7789V: It has an C/D line, which is connected to a GPIO here. It expects thisline to be low for a command and high for data. We use a pre-transmit callback here to control thatline: every transaction has as the user-definable argument the needed state of the D/C line and justbefore the transaction is sent, the callback will set this line to the correct state.
*/#define LCD_HOST    SPI2_HOST#define PIN_NUM_MISO 4
#define PIN_NUM_MOSI 5
#define PIN_NUM_CLK  3
#define PIN_NUM_CS   6#define PIN_NUM_DC   -1
#define PIN_NUM_RST  2
#define PIN_NUM_BCKL -1#define PIN_NUM_LED  45static spi_device_handle_t g_screen_spi;static int lcd_cs_port(int status)
{if (status) {gpio_set_level(PIN_NUM_CS, 1);} else {gpio_set_level(PIN_NUM_CS, 0);}return 0;
}static void spi_writeData(spi_device_handle_t spi,uint8_t data)
{esp_err_t ret;spi_transaction_t t;memset(&t, 0, sizeof(t));t.length = 8;t.tx_buffer = &data;ret = spi_device_polling_transmit(spi, &t);  //Transmit!assert(ret==ESP_OK);
}static void lcd_cmd(spi_device_handle_t spi, const uint8_t data) {lcd_cs_port(0);spi_writeData(spi,0x70);spi_writeData(spi,data);lcd_cs_port(1);
}static void lcd_data(spi_device_handle_t spi, const uint8_t data) {lcd_cs_port(0);spi_writeData(spi,0x72);spi_writeData(spi,data);lcd_cs_port(1);
}static void LCD_WriteComm(uint8_t cmd) {lcd_cmd(g_screen_spi, cmd);
}static void LCD_WriteData(uint8_t data) {lcd_data(g_screen_spi, data);
}void LCD_WriteData_16Bit(uint16_t Data)
{lcd_cs_port(0);spi_writeData(g_screen_spi,0x72);spi_writeData(g_screen_spi,Data>>8);spi_writeData(g_screen_spi,Data);lcd_cs_port(1);
}
void Lcd_Write_REG(uint8_t Index,uint8_t Data)
{LCD_WriteComm(Index);LCD_WriteData(Data);
}void LCD_SetWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{//SCLcd_Write_REG(0x02,x1>>8);       // Column address start2Lcd_Write_REG(0x03,(unsigned char)x1);          // Column address start1//ECLcd_Write_REG(0x04,x2>>8);       // Column address end2Lcd_Write_REG(0x05,(unsigned char)x2);          // Column address end1//SPLcd_Write_REG(0x06,y1>>8);       // Row address start2Lcd_Write_REG(0x07,(unsigned char)y1);          // Row address start1//EPLcd_Write_REG(0x08,y2>>8);       // Row address end2Lcd_Write_REG(0x09,(unsigned char)y2);          // Row address end1//写0x22到index register,那么下次send data就会直接被写到graphic ramLCD_WriteComm(0x22);
}void FillRect(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned short color)
{LCD_SetWindow(x1, y1,x2,y2);x2 = x2 - x1 + 1;y2 = y2 - y1 + 1;for(x1 = x2; x1 != 0 ; x1--){for (y1 = y2;y1 != 0 ;y1--){LCD_WriteData_16Bit(color);}}}void LCD_Init(void)
{gpio_set_level(PIN_NUM_RST, 0);vTaskDelay(100/portTICK_PERIOD_MS);gpio_set_level(PIN_NUM_RST, 1);vTaskDelay(100/portTICK_PERIOD_MS);Lcd_Write_REG(0x18,0x88);        //UADJ 75HzLcd_Write_REG(0x19,0x01);        //OSC_EN='1', start Osc//Power Voltage SettingLcd_Write_REG(0x1B,0x1E); //VRH=4.60VLcd_Write_REG(0x1C,0x07); //AP Crosstalk    04Lcd_Write_REG(0x1A,0x01); //BT (VGH~15V,VGL~-10V,DDVDH~5V)Lcd_Write_REG(0x24,0x38); //VMH 27Lcd_Write_REG(0x25,0x5F); //VML//VCOM offsetLcd_Write_REG(0x23,0x8C); //for Flicker adjustLcd_Write_REG(0x1F,0x88);// GAS=1, VOMG=00, PON=0, DK=1, XDK=0, DVDH_TRI=0, STB=0vTaskDelay(5/portTICK_PERIOD_MS);Lcd_Write_REG(0x1F,0x80);// GAS=1, VOMG=00, PON=0, DK=0, XDK=0, DVDH_TRI=0, STB=0vTaskDelay(5/portTICK_PERIOD_MS);Lcd_Write_REG(0x1F,0x90);// GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0vTaskDelay(5/portTICK_PERIOD_MS);Lcd_Write_REG(0x1F,0xD0);// GAS=1, VOMG=10, PON=1, DK=0, XDK=0, DDVDH_TRI=0, STB=0vTaskDelay(5/portTICK_PERIOD_MS);//Display ON SettingLcd_Write_REG(0x28,0x38);   //GON=1, DTE=1, D=1000vTaskDelay(40/portTICK_PERIOD_MS);Lcd_Write_REG(0x28,0x3C);   //GON=1, DTE=1, D=1100Lcd_Write_REG(0x36,0x09);   //REV, BGRLcd_Write_REG(0x17,0x05);  //16BIT/PIXEL//Gamma 2.2 SettingLcd_Write_REG(0x40,0x00); //Lcd_Write_REG(0x41,0x00); //Lcd_Write_REG(0x42,0x00); //Lcd_Write_REG(0x43,0x11); //Lcd_Write_REG(0x44,0x0e); //Lcd_Write_REG(0x45,0x23); //Lcd_Write_REG(0x46,0x08); //Lcd_Write_REG(0x47,0x53); //Lcd_Write_REG(0x48,0x03); //Lcd_Write_REG(0x49,0x11); //Lcd_Write_REG(0x4A,0x18); //Lcd_Write_REG(0x4B,0x1a); //Lcd_Write_REG(0x4C,0x16); //Lcd_Write_REG(0x50,0x1c); //Lcd_Write_REG(0x51,0x31); //Lcd_Write_REG(0x52,0x2e); //Lcd_Write_REG(0x53,0x3f); //Lcd_Write_REG(0x54,0x3f); //Lcd_Write_REG(0x55,0x3f); //Lcd_Write_REG(0x56,0x2c); //Lcd_Write_REG(0x57,0x77); //Lcd_Write_REG(0x58,0x09); //Lcd_Write_REG(0x59,0x05); //Lcd_Write_REG(0x5A,0x07); //Lcd_Write_REG(0x5B,0x0e); //Lcd_Write_REG(0x5C,0x1c); //Lcd_Write_REG(0x5D,0x88); //vTaskDelay(100/portTICK_PERIOD_MS);FillRect(0, 0, 239, 319, 0xf800 );
}void app_main(void)
{esp_err_t ret;gpio_config_t io_conf = {};spi_bus_config_t buscfg={.miso_io_num=PIN_NUM_MISO,.mosi_io_num=PIN_NUM_MOSI,.sclk_io_num=PIN_NUM_CLK,.quadwp_io_num=-1,.quadhd_io_num=-1,.max_transfer_sz=16*320};spi_device_interface_config_t devcfg={.clock_speed_hz=40*1000*1000,           //Clock out at 10 MHz.mode=0,                                //SPI mode 0//.spics_io_num=PIN_NUM_CS,               //CS pin.queue_size=1,                          //We want to be able to queue 7 transactions at a time};//Initialize the lcd gpioio_conf.pin_bit_mask = ( (1ULL<<PIN_NUM_RST) |(1ULL<<PIN_NUM_CS));io_conf.mode = GPIO_MODE_OUTPUT;io_conf.pull_up_en = true;gpio_config(&io_conf);//Initialize the SPI busret=spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO);ESP_ERROR_CHECK(ret);// //Attach the LCD to the SPI busret=spi_bus_add_device(LCD_HOST, &devcfg, &g_screen_spi);ESP_ERROR_CHECK(ret);//Initialize the LCDLCD_Init();FillRect(0, 0, 239, 319, 0xf800 );vTaskDelay(500/portTICK_PERIOD_MS);FillRect(0, 0, 239, 319, 0x07e0 );vTaskDelay(500/portTICK_PERIOD_MS);FillRect(0, 0, 239, 319, 0x001f );vTaskDelay(500/portTICK_PERIOD_MS);FillRect(0, 0, 239, 319, 0xFFE0 );vTaskDelay(500/portTICK_PERIOD_MS);FillRect(0, 0, 239, 319, 0xEF7D );vTaskDelay(500/portTICK_PERIOD_MS);}

二、总结

1、驱动成功了,但刷新很慢,感觉比模拟SPI都慢。SPI频率设到40M了,也没什么改进。

2、开始让SPI自己控制CS,不知道什么原因,无论用中断方式还是轮询方式,屏幕都无显示。CS只有通过GPIO控制才有效。

SPI轮询方式

ret = spi_device_polling_transmit(spi, &t);  //Transmit!

 SPI中断方式

ret = spi_device_transmit(spi,(spi_transaction_t *)&trans); 

自己控制CS

static int lcd_cs_port(int status)

{

   if (status) {

       gpio_set_level(PIN_NUM_CS, 1);

   } else {

       gpio_set_level(PIN_NUM_CS, 0);

   }

    return 0;

}

 

所以.spics_io_num=PIN_NUM_CS被注释掉了。

   spi_device_interface_config_t devcfg={

        .clock_speed_hz=40*1000*1000,           //Clock out at 10 MHz

        .mode=0,                                //SPI mode 0

        //.spics_io_num=PIN_NUM_CS,               //CS pin

        .queue_size=1,                          //We want to be able to queue 7 transactions at a time

    };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/205147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于下游竞争的在线评论引入策略研究

基于下游竞争的在线评论引入策略研究 分析一下这篇文章吧 中国管理科学的2023年10月的文章&#xff0c;非常新 文章的结论 引入在线评论会使得线下零售商在持续销售阶段降价&#xff0c;线上零售商在持续销售阶段提价&#xff0c;从而使得线上线下零售商的价格差异增大&…

Python 作业解答

1. 在给定的一些数字中找出2个数&#xff0c;使得它们的和为N 题目要求 如给定5个数字 [3&#xff0c;4&#xff0c;9&#xff0c;7&#xff0c;10] 从中选择两个数使用它们的和为11。必须保证这些数据中有答案&#xff0c;并且只有一个答案。 1.1 解题思路一&#xff1a;双…

第2讲、布署Hyper-V软硬件需求:

硬件&#xff1a; 1、处理器&#xff08;CPU&#xff09;&#xff1a; a.处理器必须是64位&#xff0c;1.4GHz b.处理器必须支持硬件虚拟化技术 CPU(主板BIOS启用): Intel VT AMD-V 2、需要启用硬件数据保…

Android平板还能编程?Ubuntu本地安装code-server远程编程写代码

文章目录 1.ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以&#xff0c;这里以VMwhere ubuntu系统为例 下载code server服务,浏览器…

Spark - 输出parqute文件

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

[RK-Linux] 移植Linux-5.10到RK3399(四)| 检查HDMI配置与打开内核LOGO显示

文章目录 一、HDMI二、VOP三、显示内核LOGO一、HDMI RK3399 的 HDMI 接口如图: datasheet 介绍: HDMI 接口各个引脚的作用如下: 接口标签作用HDMI_TX0P HDMI_TX0PA差分信号线,用于传输 HDMI 通道 0 的正向数据HDMI_TX0N HDMI_TX0NA

JavaWeb-Tomcat

1. Web服务器 web服务器由硬件和软件组成&#xff1a; 硬件&#xff1a;计算机系统软件&#xff1a;计算机上安装的服务器软件&#xff0c;安装后可以为web应用提供网络服务。 常见的JavaWeb服务器&#xff1a; Tomcat&#xff08;Apache&#xff09;&#xff1a;应用最广泛的…

数据结构 | 查漏补缺之求叶子结点,分离链接法、最小生成树、DFS、BFS

求叶子结点的个数 参考博文&#xff1a; 树中的叶子结点的个数 计算方法_求树的叶子节点个数-CSDN博客 分离链接法 参考博文 数据结构和算法——哈希查找冲突处理方法&#xff08;开放地址法-线性探测、平方探测、双散列探测、再散列&#xff0c;分离链接法&#xff09;_线性…

如何选择性能测试工具?ab和其它工具的对比分析!

性能测试是保证应用程序高效可靠的重要手段之一&#xff0c;在进行性能测试时&#xff0c;选择合适的性能测试工具非常重要。应当根据测试需求来选择适合的测试工具&#xff0c;本文将会详细介绍ApacheBench&#xff08;简称ab&#xff09;和其他性能测试工具的区别以及如何选择…

Peter算法小课堂—贪心算法

课前思考&#xff1a;贪心是什么&#xff1f;贪心如何“贪”&#xff1f; 课前小视频&#xff1a;什么是贪心算法 - 知乎 (zhihu.com) 贪心 贪心是一种寻找最优解问题的常用方法。 贪心一般将求解过程分拆成若干个步骤&#xff0c;自顶向下&#xff0c;解决问题 太戈编程第…

排序:快速排序(hoare版本)

目录 快速排序&#xff1a; 概念&#xff1a; 动画分析&#xff1a; 代码实现&#xff1a; 代码分析&#xff1a; 代码特性&#xff1a; 常见问题&#xff1a; 快速排序&#xff1a; 概念&#xff1a; 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&a…

【项目日记(一)】高并发内存池项目介绍

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 项目日记 1. 前言2. 什么是高并发内存池…

SCI常用的连接词

1、描述相似性连词 Similarly 类似地&#xff0c;相似地 Likewise 同样地 Correspondingly 相应地 Equally 同样地 Not only ….but also 不仅…….而且 In the same way 以同样的方式 2、表示因果关系 Therefore 所以 Thus 因此, 从而&#xff0c;这样 H…

《opencv实用探索·十三》opencv之canny边缘检测

1、canny边缘检测应用场景 目标检测&#xff1a; Canny边缘检测可以用于检测图像中的目标边缘&#xff0c;从而帮助识别和定位物体。在目标检测的流程中&#xff0c;边缘通常是检测的第一步。 图像分割&#xff1a; Canny边缘检测可用于图像分割&#xff0c;即将图像划分为具有…

微服务--08--Seata XA模式 AT模式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 分布式事务Seata 1.XA模式1.1.两阶段提交1.2.Seata的XA模型1.3.优缺点 AT模式2.1.Seata的AT模型2.2.流程梳理2.3.AT与XA的区别 分布式事务 > 事务–01—CAP理论…

class050 双指针技巧与相关题目【算法】

class050 双指针技巧与相关题目【算法】 算法讲解050【必备】双指针技巧与相关题目 code1 922. 按奇偶排序数组 II // 按奇偶排序数组II // 给定一个非负整数数组 nums。nums 中一半整数是奇数 &#xff0c;一半整数是偶数 // 对数组进行排序&#xff0c;以便当 nums[i] 为…

HarmonyOS开发(十):通知和提醒

1、通知概述 1.1、简介 应用可以通过通知接口发送通知消息&#xff0c;终端用户可以通过通知栏查看通知内容&#xff0c;也可以点击通知来打开应用。 通知使用的的常见场景&#xff1a; 显示接收到的短消息、即使消息...显示应用推送消息显示当前正在进行的事件&#xff0c…

dbug_hub 错误 使用多个ILA导致

记录一下vivado调整dbg_hub时钟调整的方法 (dengkanwen.com) 解决方法参考以上链接。 或&#xff0c;使用高速下载器&#xff1f;

MySQL数据库与其管理工具Navicat

这里介绍MySQL数据库和Navicat的使用 1.下载MySQL数据库及MySQL客户端管理工具Navicat 登录www.mysql.com下载MySQL 登录www.navicat.com.cn/download下载客户端管理工具 2.启动MySQL数据库服务器 以管理员身份打开命令提示窗口 找到mysql的bin目录 输入初始化命令mysqld…

Java毕业设计源码—vue+SpringBoot图书借阅管理图书馆管理系统

主要技术 SpringBoot、Mybatis-Plus、MySQL、Vue3、ElementPlus等 主要功能 管理员模块&#xff1a;注册、登录、书籍管理、读者管理、借阅管理、借阅状态、修改个人信息、修改密码 读者模块&#xff1a;注册、登录、查询图书信息、借阅和归还图书、查看个人借阅记录、修改…