这是我所有代码,怎么播放不了视频,还报错/******************** ESP32-C3 NV3007 TFT视频播放器 ********************/
#include <WiFi.h>
#include <WebServer.h>
// 请先使用转换脚本生成video_data.h,然后取消注释下面这行
#include "142x428.h"
// 如果没有video_data.h,使用这些默认值(用于测试)
//#define VIDEO_FRAMES 10
//#define VIDEO_WIDTH 142
//#define VIDEO_HEIGHT 428
// ESP32-C3引脚定义
#define TFT_SCK_PIN 2
#define TFT_SDA_PIN 3
#define TFT_RST_PIN 10
#define TFT_DC_PIN 6
#define TFT_CS_PIN 7
#define TFT_BL_PIN 11
// 引脚控制宏
#define TFT_SCK_0 digitalWrite(TFT_SCK_PIN, LOW)
#define TFT_SCK_1 digitalWrite(TFT_SCK_PIN, HIGH)
#define TFT_SDA_0 digitalWrite(TFT_SDA_PIN, LOW)
#define TFT_SDA_1 digitalWrite(TFT_SDA_PIN, HIGH)
#define TFT_RST_0 digitalWrite(TFT_RST_PIN, LOW)
#define TFT_RST_1 digitalWrite(TFT_RST_PIN, HIGH)
#define TFT_DC_0 digitalWrite(TFT_DC_PIN, LOW)
#define TFT_DC_1 digitalWrite(TFT_DC_PIN, HIGH)
#define TFT_CS_0 digitalWrite(TFT_CS_PIN, LOW)
#define TFT_CS_1 digitalWrite(TFT_CS_PIN, HIGH)
#define TFT_BL_0 digitalWrite(TFT_BL_PIN, LOW)
#define TFT_BL_1 digitalWrite(TFT_BL_PIN, HIGH)
// WiFi配置
const char* ssid = "ESP32-TFT-Video";
const char* password = "12345678";
WebServer server(80);
// 颜色定义
#define RED 0XF800
#define GREEN 0X07E0
#define BLUE 0X001F
#define WHITE 0XFFFF
#define BLACK 0X0000
#define YELLOW 0xFFE0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
// 视频播放状态
bool isPlayingVideo = false;
int currentVideoFrame = 0;
unsigned long lastFrameTime = 0;
int frameDelay = 100; // 毫秒
bool loopPlayback = true;
// 简化版视频帧数据(用于测试)
const uint16_t testFrames[VIDEO_FRAMES][VIDEO_WIDTH * VIDEO_HEIGHT] = {0}; // 空数据,仅用于编译测试
void IO_init(void) {
pinMode(TFT_SCK_PIN, OUTPUT);
pinMode(TFT_SDA_PIN, OUTPUT);
pinMode(TFT_RST_PIN, OUTPUT);
pinMode(TFT_DC_PIN, OUTPUT);
pinMode(TFT_CS_PIN, OUTPUT);
pinMode(TFT_BL_PIN, OUTPUT);
}
void SPI_SendByte(unsigned char byte) {
unsigned char counter;
for(counter = 0; counter < 8; counter++) {
TFT_SCK_0;
if((byte & 0x80) == 0) {
TFT_SDA_0;
} else {
TFT_SDA_1;
}
byte = byte << 1;
TFT_SCK_1;
}
TFT_SCK_0;
}
void TFT_SEND_CMD(unsigned char o_command) {
TFT_CS_0;
TFT_DC_0;
SPI_SendByte(o_command);
TFT_CS_1;
}
void TFT_SEND_DATA(unsigned char o_data) {
TFT_CS_0;
TFT_DC_1;
SPI_SendByte(o_data);
TFT_CS_1;
}
void TFT_SET_ADD(unsigned short int X, unsigned short int Y,
unsigned short int X_END, unsigned short int Y_END) {
X += 12; // 偏移量
X_END += 12;
TFT_SEND_CMD(0x2A); // 列地址设置
TFT_SEND_DATA(X >> 8);
TFT_SEND_DATA(X);
TFT_SEND_DATA(X_END >> 8);
TFT_SEND_DATA(X_END);
TFT_SEND_CMD(0x2B); // 行地址设置
TFT_SEND_DATA(Y >> 8);
TFT_SEND_DATA(Y);
TFT_SEND_DATA(Y_END >> 8);
TFT_SEND_DATA(Y_END);
TFT_SEND_CMD(0x2C); // 开始写入数据
}
// 清屏函数
void TFT_Clear(unsigned short int color) {
TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1);
for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) {
TFT_SEND_DATA(color >> 8);
TFT_SEND_DATA(color & 0xFF);
}
}
// 绘制矩形函数
void TFT_DrawRect(unsigned short x, unsigned short y, unsigned short w, unsigned short h, unsigned short color) {
TFT_SET_ADD(x, y, x + w - 1, y + h - 1);
for(int i = 0; i < w * h; i++) {
TFT_SEND_DATA(color >> 8);
TFT_SEND_DATA(color & 0xFF);
}
}
// 显示一帧视频
void displayVideoFrame(int frameIndex) {
if (frameIndex < 0 || frameIndex >= VIDEO_FRAMES) return;
TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1);
// 这里使用测试数据,实际使用时应该从video_data.h读取
for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) {
uint16_t pixel = testFrames[frameIndex][i]; // 测试数据,实际应该用真实数据
TFT_SEND_DATA(pixel >> 8);
TFT_SEND_DATA(pixel & 0xFF);
}
}
void displayVideoFrame(int frameIndex) {
if (frameIndex < 0 || frameIndex >= VIDEO_FRAMES) return;
TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1);
// 使用真实视频数据(取消注释下面这行)
// const uint16_t* frameData = video_frames[frameIndex];
for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) {
uint16_t pixel = frameData[i]; // 使用真实数据
TFT_SEND_DATA(pixel >> 8);
TFT_SEND_DATA(pixel & 0xFF);
}
}
// 视频播放函数
void playVideo() {
if (!isPlayingVideo) return;
unsigned long currentTime = millis();
if (currentTime - lastFrameTime >= frameDelay) {
displayVideoFrame(currentVideoFrame);
currentVideoFrame++;
if (currentVideoFrame >= VIDEO_FRAMES) {
if (loopPlayback) {
currentVideoFrame = 0;
} else {
isPlayingVideo = false;
currentVideoFrame = 0;
}
}
lastFrameTime = currentTime;
}
}
// 完整的TFT初始化序列
void TFT_Init(void) {
Serial.println("开始TFT初始化...");
TFT_RST_0;
delay(100);
TFT_RST_1;
delay(120);
Serial.println("发送完整初始化序列...");
TFT_SEND_CMD(0xff);
TFT_SEND_DATA(0xa5);
TFT_SEND_CMD(0x9a);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x9b);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x9c);
TFT_SEND_DATA(0xb0);
TFT_SEND_CMD(0x9d);
TFT_SEND_DATA(0x16);
TFT_SEND_CMD(0x9e);
TFT_SEND_DATA(0xc4);
TFT_SEND_CMD(0x8f);
TFT_SEND_DATA(0x55);
TFT_SEND_DATA(0x04);
TFT_SEND_CMD(0x84);
TFT_SEND_DATA(0x90);
TFT_SEND_CMD(0x83);
TFT_SEND_DATA(0x7b);
TFT_SEND_CMD(0x85);
TFT_SEND_DATA(0x33);
TFT_SEND_CMD(0x60);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x70);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x61);
TFT_SEND_DATA(0x02);
TFT_SEND_CMD(0x71);
TFT_SEND_DATA(0x02);
TFT_SEND_CMD(0x62);
TFT_SEND_DATA(0x04);
TFT_SEND_CMD(0x72);
TFT_SEND_DATA(0x04);
TFT_SEND_CMD(0x6c);
TFT_SEND_DATA(0x29);
TFT_SEND_CMD(0x7c);
TFT_SEND_DATA(0x29);
TFT_SEND_CMD(0x6d);
TFT_SEND_DATA(0x31);
TFT_SEND_CMD(0x7d);
TFT_SEND_DATA(0x31);
TFT_SEND_CMD(0x6e);
TFT_SEND_DATA(0x0f);
TFT_SEND_CMD(0x7e);
TFT_SEND_DATA(0x0f);
TFT_SEND_CMD(0x66);
TFT_SEND_DATA(0x21);
TFT_SEND_CMD(0x76);
TFT_SEND_DATA(0x21);
TFT_SEND_CMD(0x68);
TFT_SEND_DATA(0x3A);
TFT_SEND_CMD(0x78);
TFT_SEND_DATA(0x3A);
TFT_SEND_CMD(0x63);
TFT_SEND_DATA(0x07);
TFT_SEND_CMD(0x73);
TFT_SEND_DATA(0x07);
TFT_SEND_CMD(0x64);
TFT_SEND_DATA(0x05);
TFT_SEND_CMD(0x74);
TFT_SEND_DATA(0x05);
TFT_SEND_CMD(0x65);
TFT_SEND_DATA(0x02);
TFT_SEND_CMD(0x75);
TFT_SEND_DATA(0x02);
TFT_SEND_CMD(0x67);
TFT_SEND_DATA(0x23);
TFT_SEND_CMD(0x77);
TFT_SEND_DATA(0x23);
TFT_SEND_CMD(0x69);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x79);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x6a);
TFT_SEND_DATA(0x13);
TFT_SEND_CMD(0x7a);
TFT_SEND_DATA(0x13);
TFT_SEND_CMD(0x6b);
TFT_SEND_DATA(0x13);
TFT_SEND_CMD(0x7b);
TFT_SEND_DATA(0x13);
TFT_SEND_CMD(0x6f);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x7f);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x50);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x52);
TFT_SEND_DATA(0xd6);
TFT_SEND_CMD(0x53);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x54);
TFT_SEND_DATA(0x08);
TFT_SEND_CMD(0x55);
TFT_SEND_DATA(0x1e);
TFT_SEND_CMD(0x56);
TFT_SEND_DATA(0x1c);
//goa map_sel
TFT_SEND_CMD(0xa0);
TFT_SEND_DATA(0x2b);
TFT_SEND_DATA(0x24);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xa1);
TFT_SEND_DATA(0x87);
TFT_SEND_CMD(0xa2);
TFT_SEND_DATA(0x86);
TFT_SEND_CMD(0xa5);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xa6);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xa7);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xa8);
TFT_SEND_DATA(0x36);
TFT_SEND_CMD(0xa9);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xaa);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xB9);
TFT_SEND_DATA(0x85);
TFT_SEND_CMD(0xBA);
TFT_SEND_DATA(0x84);
TFT_SEND_CMD(0xBB);
TFT_SEND_DATA(0x83);
TFT_SEND_CMD(0xBC);
TFT_SEND_DATA(0x82);
TFT_SEND_CMD(0xBD);
TFT_SEND_DATA(0x81);
TFT_SEND_CMD(0xBE);
TFT_SEND_DATA(0x80);
TFT_SEND_CMD(0xBF);
TFT_SEND_DATA(0x01);
TFT_SEND_CMD(0xC0);
TFT_SEND_DATA(0x02);
TFT_SEND_CMD(0xc1);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xc2);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xc3);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xc4);
TFT_SEND_DATA(0x33);
TFT_SEND_CMD(0xc5);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xc6);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xC8);
TFT_SEND_DATA(0x33);
TFT_SEND_DATA(0x33);
TFT_SEND_CMD(0xC9);
TFT_SEND_DATA(0x68);
TFT_SEND_CMD(0xCA);
TFT_SEND_DATA(0x69);
TFT_SEND_CMD(0xCB);
TFT_SEND_DATA(0x6a);
TFT_SEND_CMD(0xCC);
TFT_SEND_DATA(0x6b);
TFT_SEND_CMD(0xCD);
TFT_SEND_DATA(0x33);
TFT_SEND_DATA(0x33);
TFT_SEND_CMD(0xCE);
TFT_SEND_DATA(0x6c);
TFT_SEND_CMD(0xCF);
TFT_SEND_DATA(0x6d);
TFT_SEND_CMD(0xD0);
TFT_SEND_DATA(0x6e);
TFT_SEND_CMD(0xD1);
TFT_SEND_DATA(0x6f);
TFT_SEND_CMD(0xAB);
TFT_SEND_DATA(0x03);
TFT_SEND_DATA(0x67);
TFT_SEND_CMD(0xAC);
TFT_SEND_DATA(0x03);
TFT_SEND_DATA(0x6b);
TFT_SEND_CMD(0xAD);
TFT_SEND_DATA(0x03);
TFT_SEND_DATA(0x68);
TFT_SEND_CMD(0xAE);
TFT_SEND_DATA(0x03);
TFT_SEND_DATA(0x6c);
TFT_SEND_CMD(0xb3);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xb4);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xb5);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xB6);
TFT_SEND_DATA(0x32);
TFT_SEND_CMD(0xB7);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xB8);
TFT_SEND_DATA(0x7e);
TFT_SEND_CMD(0xe0);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0xe1);
TFT_SEND_DATA(0x03);
TFT_SEND_DATA(0x0f);
TFT_SEND_CMD(0xe2);
TFT_SEND_DATA(0x04);
TFT_SEND_CMD(0xe3);
TFT_SEND_DATA(0x01);
TFT_SEND_CMD(0xe4);
TFT_SEND_DATA(0x0e);
TFT_SEND_CMD(0xe5);
TFT_SEND_DATA(0x01);
TFT_SEND_CMD(0xe6);
TFT_SEND_DATA(0x19);
TFT_SEND_CMD(0xe7);
TFT_SEND_DATA(0x10);
TFT_SEND_CMD(0xe8);
TFT_SEND_DATA(0x10);
TFT_SEND_CMD(0xea);
TFT_SEND_DATA(0x12);
TFT_SEND_CMD(0xeb);
TFT_SEND_DATA(0xd0);
TFT_SEND_CMD(0xec);
TFT_SEND_DATA(0x04);
TFT_SEND_CMD(0xed);
TFT_SEND_DATA(0x07);
TFT_SEND_CMD(0xee);
TFT_SEND_DATA(0x07);
TFT_SEND_CMD(0xef);
TFT_SEND_DATA(0x09);
TFT_SEND_CMD(0xf0);
TFT_SEND_DATA(0xd0);
TFT_SEND_CMD(0xf1);
TFT_SEND_DATA(0x0e);
TFT_SEND_DATA(0x17);
TFT_SEND_CMD(0xf2);
TFT_SEND_DATA(0x2c);
TFT_SEND_DATA(0x1b);
TFT_SEND_DATA(0x0b);
TFT_SEND_DATA(0x20);
//1 dot
TFT_SEND_CMD(0xe9);
TFT_SEND_DATA(0x29);
TFT_SEND_CMD(0xec);
TFT_SEND_DATA(0x04);
//TE
TFT_SEND_CMD(0x35);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x44);
TFT_SEND_DATA(0x00);
TFT_SEND_DATA(0x10);
TFT_SEND_CMD(0x46);
TFT_SEND_DATA(0x10);
TFT_SEND_CMD(0xff);
TFT_SEND_DATA(0x00);
TFT_SEND_CMD(0x3a);
TFT_SEND_DATA(0x05);
TFT_SEND_CMD(0x11);
delay(220);
TFT_SEND_CMD(0x29);
Serial.println("TFT初始化完成");
}
// 网页界面
const char* MAIN_page = R"=====(
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TFT视频播放器</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin: 20px; background: #f5f5f5; }
.container { background: white; padding: 20px; border-radius: 15px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); max-width: 500px; margin: 0 auto; }
h1 { color: #333; margin-bottom: 20px; }
.btn {
padding: 12px 24px;
margin: 8px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: all 0.3s;
min-width: 120px;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 6px 8px rgba(0,0,0,0.2); }
.btn:active { transform: translateY(0); }
.red { background: #ff4444; color: white; }
.green { background: #44ff44; color: black; }
.blue { background: #4444ff; color: white; }
.black { background: #333333; color: white; }
.control { background: #666666; color: white; }
.status { margin: 20px 0; padding: 15px; background: #e8f4fd; border-radius: 8px; }
</style>
</head>
<body>
<div class="container">
<h1>🎬 TFT视频播放器</h1>
<div class="status">
<p>当前模式: <span id="currentMode">停止</span></p>
<p>帧数: <span id="frameInfo">0/0</span></p>
<p>速度: <span id="speedInfo">100ms/帧</span></p>
</div>
<div>
<h3>颜色测试</h3>
<button class="btn red" onclick="setColor('red')">红色</button>
<button class="btn green" onclick="setColor('green')">绿色</button>
<button class="btn blue" onclick="setColor('blue')">蓝色</button>
<button class="btn black" onclick="setColor('black')">黑色</button>
</div>
<div style="margin-top: 20px;">
<h3>视频控制</h3>
<button class="btn control" onclick="controlVideo('play')">播放视频</button>
<button class="btn control" onclick="controlVideo('stop')">停止</button>
<button class="btn control" onclick="controlVideo('restart')">重新开始</button>
</div>
<div style="margin-top: 20px;">
<label>帧延迟:
<input type="range" id="frameDelay" min="50" max="500" value="100" onchange="updateSpeed()">
<span id="delayValue">100ms</span>
</label>
</div>
</div>
<script>
function setColor(color) {
fetch('/color?c=' + color)
.then(response => response.text())
.then(data => {
document.getElementById('currentMode').textContent = '颜色: ' + color;
alert('设置为: ' + color);
});
}
function controlVideo(action) {
fetch('/control?action=' + action)
.then(response => response.text())
.then(data => {
if (action === 'play') {
document.getElementById('currentMode').textContent = '视频播放中';
} else {
document.getElementById('currentMode').textContent = '停止';
}
alert('操作: ' + action);
});
}
function updateSpeed() {
const delay = document.getElementById('frameDelay').value;
document.getElementById('delayValue').textContent = delay + 'ms';
document.getElementById('speedInfo').textContent = delay + 'ms/帧';
fetch('/control?action=speed&value=' + delay);
}
// 初始化
fetch('/videoinfo')
.then(response => response.json())
.then(data => {
document.getElementById('frameInfo').textContent = '0/' + data.frames;
});
</script>
</body>
</html>
)=====";
void setup() {
Serial.begin(115200);
delay(2000);
Serial.println("=== ESP32-C3 TFT视频播放器 ===");
Serial.printf("视频设置: %d帧, %dx%d分辨率\n", VIDEO_FRAMES, VIDEO_WIDTH, VIDEO_HEIGHT);
// 初始化硬件
IO_init();
TFT_BL_1;
TFT_Init();
// 清屏
TFT_Clear(BLACK);
// 设置WiFi
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP地址: ");
Serial.println(myIP);
// 设置网页路由
server.on("/", HTTP_GET, []() {
server.send(200, "text/html", MAIN_page);
});
server.on("/color", HTTP_GET, []() {
if (server.hasArg("c")) {
String color = server.arg("c");
uint16_t colorValue = BLACK;
if (color == "red") colorValue = RED;
else if (color == "green") colorValue = GREEN;
else if (color == "blue") colorValue = BLUE;
else if (color == "black") colorValue = BLACK;
TFT_Clear(colorValue);
server.send(200, "text/plain", "颜色设置为: " + color);
Serial.println("颜色设置为: " + color);
}
});
server.on("/control", HTTP_GET, []() {
if (server.hasArg("action")) {
String action = server.arg("action");
if (action == "play") {
isPlayingVideo = true;
server.send(200, "text/plain", "开始播放视频");
} else if (action == "stop") {
isPlayingVideo = false;
server.send(200, "text/plain", "停止播放");
} else if (action == "restart") {
currentVideoFrame = 0;
isPlayingVideo = true;
server.send(200, "text/plain", "重新开始");
} else if (action == "speed" && server.hasArg("value")) {
frameDelay = server.arg("value").toInt();
server.send(200, "text/plain", "速度设置: " + String(frameDelay));
}
}
});
server.on("/videoinfo", HTTP_GET, []() {
String json = "{\"frames\": " + String(VIDEO_FRAMES) +
", \"width\": " + String(VIDEO_WIDTH) +
", \"height\": " + String(VIDEO_HEIGHT) + "}";
server.send(200, "application/json", json);
});
server.begin();
Serial.println("HTTP服务器启动完成");
// 显示初始信息
TFT_Clear(BLACK);
Serial.println("系统就绪");
}
void loop() {
server.handleClient();
// 播放视频
if (isPlayingVideo) {
playVideo();
}
delay(10);
}
最新发布