我已将AS5048A磁编码器连接到ESP32开发板(VSPI/SPI3 3总线: CS=5、CLK=18、MISO=19、MOSI=23)。使用ESP以色列国防军版本4.0.1。Arduino库:https://github.com/espressif/arduino-esp32/tree/idf-release/v4.0
我测试了两个版本的SPI传输:a)和和b),没有 Arduino ESP-库。
Arduino版本通常在不同的速度下工作得很好。纯粹的以色列国防军很难正确地接收数据。奇怪的是,纯国防军版本能够在SPI模式3 (Arduino与模式1一起工作)中发送0x0000和0xFFFF (带有奇偶校验和r/w的读取角命令),但其他命令失败。同样,0x0000 (null命令)返回一些垃圾(0x6000或类似的东西,而不是0x00000)。所以纯版本可以正确地读取角度 (?!)对于SPI模式3,但是任何事情都会失败(我想这是个意外,因为读角命令是0xFFFF)。
我尝试了每一种模式和很多定时配置。试图在Arduino库中查看SPI,它对SPI使用的方法不同于以色列国防军本身。
有什么帮助/想法吗?下面是密码。
Arduino实现非常简单:
this->settings = SPISettings(3000000, MSBFIRST, SPI_MODE1);
pinMode(this->_cs, OUTPUT);
SPI.begin();
SPI.beginTransaction(this->settings);
digitalWrite(this->_cs, LOW);
uint16_t response = SPI.transfer16(command);
digitalWrite(this->_cs, HIGH);纯以色列国防军如下:
spi_host_device_t spi_host = SPI3_HOST;
spi_device_handle_t spi;
esp_err_t ret;
spi_bus_config_t buscfg;
memset(&buscfg, 0, sizeof(buscfg));
buscfg.mosi_io_num = pinMOSI;
buscfg.miso_io_num = pinMISO;
buscfg.sclk_io_num = pinCLK;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = 1;
buscfg.flags = SPICOMMON_BUSFLAG_MASTER ; /*| SPICOMMON_BUSFLAG_IOMUX_PINS ;*/
buscfg.intr_flags = 0;
spi_device_interface_config_t devcfg;
memset(&devcfg, 0, sizeof(devcfg));
devcfg.command_bits = 0;
devcfg.address_bits = 0;
devcfg.dummy_bits = 0;
devcfg.mode = (uint8_t) 1; //SPI_MODE;
devcfg.duty_cycle_pos = 0;
devcfg.cs_ena_pretrans = 0;
devcfg.cs_ena_posttrans = (uint8_t) 0; //CS_ENA_POSTTRANS;
devcfg.clock_speed_hz = 300 * 1000; //SPI_HZ;
devcfg.input_delay_ns = 50; // INPUT_DELAY_NS;
devcfg.spics_io_num = pinCS;
devcfg.flags = SPI_DEVICE_NO_DUMMY ;
devcfg.queue_size = 1;
devcfg.pre_cb = 0;
devcfg.post_cb = 0;
ret = spi_bus_initialize(spi_host, &buscfg, 0); // No DMA
ESP_ERROR_CHECK(ret);
ret = spi_bus_add_device(spi_host, &devcfg, &spi);
ESP_ERROR_CHECK(ret);
ESP_LOGI(TAG, "AS5048 device initialized on SPI with MISO=%d, MOSI=%d, CLK=%d, CS=%d, HZ=%d", pinMISO, pinMOSI, pinCLK, pinCS, SPI_HZ);传输(cmd是具有奇偶校验和r/w位的uint16_t ):
esp_err_t ret;
spi_transaction_t t;
spi_device_acquire_bus(spi, portMAX_DELAY);
memset(&t, 0, sizeof(t));
t.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA ;
*((uint16_t*)t.tx_data) = SPI_SWAP_DATA_TX(cmd, 16);
t.length = 16;
//ret = spi_device_transmit(spi, &t);
ret = spi_device_polling_transmit(spi, &t);
if(ret != ESP_OK)
ESP_LOGE(TAG, "spi_device_transmit() failed");
spi_device_release_bus(spi);
uint16_t response = SPI_SWAP_DATA_RX(*((uint16_t*)t.rx_data), 16); 发布于 2020-09-20 16:17:35
我刚刚在组件上提取了数据表,并注意到它声明SPI WireMode为1。
还有一个表,其中提到了我在这里包含的一些其他项目。Time between CSn falling edge and CLK rising edge被指定为350 as,最小串行时钟周期为100 as,因此如果您在10 The运行,则需要等待最多4个时钟。我不认为这是一个问题的速度,你正在运行,但想注意它。
您的Arduino配置显示您在3 3MHz和CS线在传输之前由软件驱动,这可能处理您的设置时间,而您的ESP-以色列国防军代码让您运行模式3,但以300 3MHz,这将使您大大超过所需的350 is的设置时间(docs显示1 spi时钟延迟后,CS被驱动,更多这一点稍后)。模式3上的时钟与模式1相反,这意味着SPI将试图在数据线转换的同时读取数据。我的猜测是,您正在遇到一些逻辑竞赛,它在某些情况下是“工作的”,因为input_delay_ns参数可能会对数据状态在示例之前更改的位置造成足够的延迟。
使用错误的SPI计时模式可能会使您发疯,因为事情几乎可以正常工作,而且有时您会得到正确的结果(此外,对于设备或总线布局来说,以过高的速度运行会给您带来同样的痛苦)。为了快速重新散列,模式是时钟极性和相位的矩阵。模式1和模式3彼此之间有相反的极性,在上升或下降的边缘取样,当你使用错误的时间时,你可以在时钟改变状态的同时设置这个值。
我赞扬你使用ESP-以色列国防军,摆脱了Arduino,嵌入式世界的"Visual Basic“。如果您想尝试并接近10 the设备的最大速度,您还需要使用SPI ctrl2寄存器(0x14)。根据文档,位0-3 (默认值为1)指定被驱动的CS线路与数据传输开始之间的延迟。
https://stackoverflow.com/questions/62384327
复制相似问题