我无法从 SPI 总线读取数据,特别是 ILI9341 显示适配器(不过,我在其他设备上也遇到了同样的问题)。当我尝试阅读时,我得到的只是零。我可以写得很好。
我正在使用带有集成 ILI9341 显示器的 ESP-WROVER-KIT v4.1,所以我知道接线是正确的。根据文档,我配置的 MISO 行是正确的。再说一次,我写数据很好,所以 MOSI 也很好。
基本上,我设置地址窗口,启动内存读取 (0x2E) 并读取一个虚拟参数(对我来说始终为零),然后读取数据。这是作为单独的交易完成的。当我以这种方式编写时,我没有任何问题(除了写入时没有虚拟参数)。不幸的是,当我阅读时,我再次得到零。
重现此问题的完整代码尽可能短,但对于这个论坛来说太长了,所以我在此处发布了一个指向相关 .c 文件的链接,它将重现该问题。
https://github.com/codewitch-honey-crisis/ili9341_read_rep/blob/master/src/main.c
如果您需要运行它,该 repo 还包含一个完整的 platformio 项目。只需备份到主回购链接。
这是代码的摘录。
spi_device_handle_t handle;
ESP_ERROR_CHECK(spi_bus_add_device(HOST,&devcfg,&handle));
init_display(handle);
uint16_t fill[320];
memset(fill,0xFF,320*2);
set_window(handle,0,0,319,239);
uint8_t cmd = 0x2C; // memory write
send(handle,&cmd,1,true);
for(int y=0;y<240;++y) {
send(handle,(uint8_t*)fill,320*2,false);
}
set_window(handle,0,0,319,239);
cmd = 0x2E; // memory read
send(handle,&cmd,1,true);
// dummy read (see datasheet)
retr(handle,&cmd,1,false);
printf("dummy value: 0x");
print_hex(&cmd,1);
printf("\r\n");
// getting zeroes here, but expect FFFFFF...
for(int y=0;y<240;++y) {
size_t sz = retr(handle,(uint8_t*)fill,320*2,false);
print_hex((uint8_t*)fill,sz);
printf("\r\n");
vTaskDelay(1);
}
这是我设置读取的方式(retr() 函数)
// retrieves data from the SPI bus MISO line
// this doesn't seem to return meaningful data currently
size_t retr(spi_device_handle_t handle, uint8_t* data,size_t size,bool cmd) {
if(0<size) {
spi_transaction_t t;
memset(&t,0,sizeof(t));
// always use rx_buffer
t.rx_buffer = data;
t.length = t.rxlength = 8*size;
t.user = (void*)!cmd;
ESP_ERROR_CHECK(spi_device_polling_transmit(handle,&t));
return (t.rxlength+7)/8;
}
return 0;
}
这是数据表的链接以供参考 https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf 相关页面是 116 和 117。我认为数据表不会揭示核心问题,但我提供无论如何。我认为问题在于我调用 API 的方式,但我不能确定。ESP-IDF SDK 中没有很好的读取示例,除了使用完全不同的 SPI 配置(10 个命令位、地址位、HALF_DUPLEX 标志等)的 NVS 事物,因此它对我来说不是很有用。
我也尝试过查看 Arduino 代码来执行此操作,但 SPI API 太不同了,我无法将其正面或反面足以将其转换为 ESP-IDF
也许我上面的代码需要一些小的更正?我希望是这样。任何帮助将不胜感激。