乐鑫技术交流
直播中

李斌

7年用户 1335经验值
私信 关注
[问答]

ESP32-C3作为SPI主机与从机通讯,从SPI切换为GPIO功能后无法再切换至SPI功能了怎么解决?

我的需求是ESP32-C3作为SPI主机与从机通讯,通讯完成后SPI管脚切换为普通GPIO用于其他功能,待下次需要与从机通讯时再切换为主机SPI。
现在的问题是从SPI切换为GPIO功能后无法再切换至SPI功能。
大概的功能代码为:
void SetGpio()
{
   //CLK信号管脚配置为OD
    gpio_config_t IO_Config;
    IO_Config.pin_bit_mask = PIN_NUM_CLK_PIN_SEL;
    IO_Config.mode = GPIO_MODE_DEF_OD;
    IO_Config.pull_up_en = 0; /*上拉*/
    IO_Config.pull_down_en = 0;
    IO_Config.intr_type = GPIO_INTR_DISABLE; /*不使能中断*/
    gpio_config(&IO_Config);
    //MOSI信号管脚配置为OD
    IO_Config.pin_bit_mask = PIN_NUM_MOSI_PIN_SEL;
    IO_Config.mode = GPIO_MODE_DEF_OD;
    IO_Config.pull_up_en = 0; /*上拉*/
    IO_Config.pull_down_en = 0;
    IO_Config.intr_type = GPIO_INTR_DISABLE; /*不使能中断*/
    gpio_config(&IO_Config);
}
//SPI外设初始化
void vspi_init(void)
{
    spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
    spi_bus_add_device(SPI2_HOST, &devcfg, &spi);
}
void  ResetSPI()
{
    gpio_config_t IO_Config;
    IO_Config.pin_bit_mask = PIN_NUM_CLK_PIN_SEL;
    IO_Config.mode = GPIO_MODE_DEF_OUTPUT;
    IO_Config.pull_up_en = 0; /*上拉*/
    IO_Config.pull_down_en = 0;
    IO_Config.intr_type = GPIO_INTR_DISABLE; /*不使能中断*/
    gpio_config(&IO_Config);
    IO_Config.pin_bit_mask = PIN_NUM_MOSI_PIN_SEL;
    IO_Config.mode = GPIO_MODE_DEF_OUTPUT;
    IO_Config.pull_up_en = 0; /*上拉*/
    IO_Config.pull_down_en = 0;
    IO_Config.intr_type = GPIO_INTR_DISABLE; /*不使能中断*/
    gpio_config(&IO_Config);
    spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
}
void main()
{
   vspi_init();//初始化SPI外设
   SPI_communication();//作为主机与从机通讯
   SetGpio();//设置 为普通IO
   Gpio_Control();//进行IO控制
   ResetSPI();//重新配置为SPI外设
   SPI_communication();//进行SPI通讯
}
如上操作无法再次开启SPI功能 log将反馈SPI bus already initialized
我也参试过重新配置SPI前运行   
spi_bus_remove_device(&spi);
spi_bus_free(SPI2_HOST);
卸载SPI再重装,但是ESP32将出现异常直接重启
                                                                                                                                                                                                                        
               
               

回帖(1)

陈静

2024-6-6 18:16:34
根据您的需求,您希望ESP32-C3在与SPI从机通讯后,将SPI管脚切换为普通GPIO用于其他功能,然后在需要与从机通讯时再切换回SPI功能。现在的问题是在切换为GPIO功能后无法再切换回SPI功能。

为了解决这个问题,您可以尝试以下步骤:

1. 在切换管脚功能之前,确保已经正确地关闭了SPI接口。这可以通过调用`spi_bus_remove`函数来实现。

```c
spi_bus_remove(HSPI_HOST);
```

2. 在切换管脚为GPIO功能后,确保已经正确地配置了GPIO管脚。您已经提供了GPIO配置的代码,这里不再赘述。

3. 当需要再次使用SPI功能时,首先需要重新初始化SPI接口。这可以通过调用`spi_bus_initialize`函数来实现。

```c
spi_bus_config_t bus_config = {
    .mosi_io_num = PIN_NUM_MOSI,
    .miso_io_num = PIN_NUM_MISO,
    .sclk_io_num = PIN_NUM_CLK_PIN_SEL,
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
    .max_transfer_sz = 4096,
    .flags = SPICOMMON_BUSFLAG_MASTER,
};
spi_bus_initialize(HSPI_HOST, &bus_config, 1);
```

4. 然后,重新配置SPI管脚。这可以通过调用`gpio_matrix_out`函数来实现。

```c
gpio_matrix_out(PIN_NUM_MOSI, HSPI_IO_MUX, 0, 0);
gpio_matrix_in(PIN_NUM_MISO, HSPI_IO_MUX, 0);
gpio_matrix_out(PIN_NUM_CLK_PIN_SEL, HSPI_IO_MUX, 0, 0);
```

5. 最后,重新初始化SPI设备。这可以通过调用`spi_device_interface_config_t`结构体进行配置,然后调用`spi_device_initialize`函数。

```c
spi_device_interface_config_t dev_config = {
    .command_bits = 0,
    .address_bits = 0,
    .dummy_bits = 0,
    .clock_speed_hz = 10 * 1000 * 1000, // 10MHz
    .duty_cycle_pos = 128, // 50% duty cycle
    .cs_ena_posttrans = 3, // 3 cycles after transaction
    .input_delay_ns = 6 * 1000, // 6us input delay
    .mode = 0,
    .spics_io_num = PIN_NUM_CS,
    .flags = SPI_DEVICE_NO_DUMMY,
};
spi_device_initialize(HSPI_DEVICE, &dev_config, 1, HSPI_HOST);
```

通过以上步骤,您应该可以在需要时切换SPI管脚为GPIO功能,并在需要时再次切换回SPI功能。希望这能解决您的问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分