ESP32C3 使用TFT_eSPI驱动TFT屏幕ST7796时的问题 无限重启,报Guru Meditation Error: (Store access fault)

  • 硬件

        使用的是淘宝上购买的ESP32C3经典版,带串口,板子如图

使用的TFT显示屏是3.5的,480*320,spi转接板

接线方式(供参考)

ESP32C3      <->      转接板

GPIO2                      SCK

GPIO3                      SD(MOSI)

GPIO7                      CS

GPIO6                      DC

GPIO11                    RESET

GPIO18                   LED(BL)

代码如下

#include "SPI.h"
#include "TFT_eSPI.h"

TFT_eSPI myGLCD = TFT_eSPI();

void setup() {
  Serial.begin(115200);
  Serial.println("display init...");

  myGLCD.init();

  pinMode(18, GPIO_MODE_OUTPUT);
  digitalWrite(TFT_BL,HIGH);

  myGLCD.fillScreen(TFT_WHITE);
  myGLCD.setRotation(1);  //切换成横屏

  myGLCD.setTextSize(2);  //字体放大
  myGLCD.setTextColor(TFT_BLACK,TFT_WHITE);
  myGLCD.drawCentreString("* TFT_eSPI *", 240, 4, 1);
}
  

然而,固件上传后,程序就不断的重启动,

参考   https://www.bilibili.com/opus/1032540189873930242,根据它的配置,正常运行

platformio.ini内

[env:wifiduino32c3]
platform = espressif32 @ 6.5.0
board = airm2m_core_esp32c3
framework = arduino
lib_deps = 
	;bodmer/TFT_eSPI@^2.5.0
board_build.flash_mode = dio
monitor_speed = 115200
build_flags = 
	-DUSER_SETUP_LOADED=1
	-DST7796_DRIVER=1
	-DTFT_RGB_ORDER=TFT_BGR
	-DTFT_WIDTH=320
	-DTFT_HEIGHT=480
	-DTFT_SCLK=2
	-DTFT_MOSI=3
	-DTFT_CS=7
	-DTFT_DC=6
	-DTFT_RST=11
	-DTFT_BL=18
	-DSPI_FREQUENCY=20000000
	-DTFT_MISO=-1   ; 禁用MISO
	-DLOAD_GLCD=1

但是这样就限制了一些依赖版本,不是根源,所以我们修改platformio.ini内的

platform = espressif32

这样就使用最新版本

然后参考下面链接,打开错误回溯,

platformIO开发ESP32程序时,出现崩溃重启时如何根据堆栈定位到源代码位置-CSDN博客文章浏览阅读2次。本文介绍如何配置ESP-IDF查看错误回溯信息 https://blog.csdn.net/belllab/article/details/148658087

查到错误代码在

void TFT_eSPI::init(uint8_t tc)  内,

  if (TFT_RST >= 0) {
    writecommand(0x00); // 错误在这一行

按住ctrl键,左键点击writecommand,跳到对应的函数

void TFT_eSPI::writecommand(uint8_t c)里面,

一步一步加日志跟踪,是在

begin_tft_write

内,再向下到   

SET_BUS_WRITE_MODE;  // Some processors (e.g. ESP32) allow recycling the tx buffer when rx is not used

向下到

  #define SET_BUS_WRITE_MODE *_spi_user = SPI_USR_MOSI

这一行的*spi_user

  volatile uint32_t* _spi_user      = (volatile uint32_t*)(SPI_USER_REG(SPI_PORT));

这里的SPI_PORT

#define SPI_PORT SPI2_HOST

查得

typedef enum {
//SPI1 can be used as GPSPI only on ESP32
    SPI1_HOST=0,    ///< SPI1
    SPI2_HOST=1,    ///< SPI2
#if SOC_SPI_PERIPH_NUM > 2
    SPI3_HOST=2,    ///< SPI3
#endif
} spi_host_device_t;

然后

#define SPI_USER_REG(i)          (REG_SPI_BASE(i) + 0x10)

继续

#define REG_SPI_BASE(i)   (((i)==2) ? (DR_REG_SPI2_BASE) : (0))   // only one GPSPI

问题出来了,传入的SPI_PORT也就是SPI2_HOST是1,然后就直接返回0了,理论上应该是返回

#define DR_REG_SPI2_BASE                        0x60024000

所以我们修改SPI_PORT一宏定义(TFT_eSPI_esp32_c3.h)

// ESP32 specific SPI port selection - only SPI2_HOST available on C3
#ifdef CONFIG_IDF_TARGET_ESP32C3
  #define SPI_PORT 2
#else  
  #define SPI_PORT SPI2_HOST
#endif  

OK,固件上传后,不报错了!

如果要调整屏幕亮度,可以使用PWM

// 屏幕亮度PWM 配置
const int pwmPin = TFT_BL;       // 使用 GPIO 18
const int pwmChannel = 0;    // 使用 PWM 通道 0 (0-5)
const int pwmFrequency = 5000; // 5kHz 频率
const int pwmResolution = 8;  // 8 位分辨率 (0-255)
  // 配置 PWM 通道
  ledcSetup(pwmChannel, pwmFrequency, pwmResolution);
  
  // 将 PWM 通道附加到 GPIO 引脚
  ledcAttachPin(pwmPin, pwmChannel);

  // 示例:从 0 到最大亮度渐变
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(pwmChannel, dutyCycle);
    delay(10);
  }
  
  // 示例:从最大亮度到 0 渐变
  for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
    ledcWrite(pwmChannel, dutyCycle);
    delay(10);
  }

成功驱动

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值