乐鑫技术交流
直播中

陈敏

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

用ESP32通过SPI读取设备数据,GPIO中断漏触发的原因?

用ESP32通过SPI读取设备数据,采用GPIO中断方式触发读取,设备数据准备好后通过GPIO5上升沿触发。GPIO的配置完全按照例程设置,SPI的配置是在eeprom例程的基础上改的。

现象是运行程序可以进入中断读取设备数据,但读取一段时间后,中断不再触发。

中断不触发的原因是设备数据准备好发出上升沿后,如果没有通过SPI读取数据,则设备输出将保持高电平,不会在输出上升沿,直到读取数据后恢复正常。我这样判断的原因是在main_app()函数的循环中加入延时和读取数据的操作后,可以连续产生中断,不会停止。

我的问题是:如何保证每次上升沿中断都被触发并调用中断服务函数?设备正常输出上升沿触发中断的频次是3200次/秒。

IO配置程序如下:

#define GPIO_INPUT_IO_1     5

#define GPIO_INPUT_PIN_SEL  (1ULL<
#define ESP_INTR_FLAG_DEFAULT 0



static xQueueHandle gpio_evt_queue = NULL;

eeprom_handle_t eeprom_handle;

short Accel_RAW[3] = {0,0,0};

void get_acc(void){

    Accel_Device_Read_Accel_Raw(eeprom_handle, Accel_RAW);//读取设备数据

    printf("x = %d, y = %d, z= %d.rn", Accel_RAW[0],Accel_RAW[1],Accel_RAW[2]);//输出

}



static void IRAM_ATTR gpio_isr_handler(void* arg)

{

    uint32_t gpio_num = (uint32_t) arg;

    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);

}



static void gpio_task_example(void* arg)

{

    uint32_t io_num;

    for(;;) {

        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {

            printf("GPIO[%d] intr, val: %dn", io_num, gpio_get_level(io_num));

            get_acc();

        }

        vTaskDelay(10 / portTICK_RATE_MS);

    }

}



void app_main(void)

{

    ESP_ERROR_CHECK(init_services());



    // Set UART log level

    esp_log_level_set(TAG, ESP_LOG_INFO);



    ESP_LOGI(TAG, "Initializing device...");



    //zero-initialize the config structure.

    gpio_config_t io_conf = {};

    //interrupt of rising edge

    io_conf.intr_type = GPIO_INTR_POSEDGE;

    //bit mask of the pins, use GPIO4/5 here

    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;

    //set as input mode

    io_conf.mode = GPIO_MODE_INPUT;

    //enable pull-up mode

    io_conf.pull_down_en = 1;

    gpio_config(&io_conf);

    //create a queue to handle gpio event from isr

    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));

    //start gpio task

    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);



    //install gpio isr service

    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);



    //hook isr handler for specific gpio pin

    gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);



    Accel_Device_Read_Accel_Raw(eeprom_handle, Accel_RAW);// 读取设备数据



    ESP_LOGI(TAG, "Initialization finished.");



     while (1) {



        ESP_LOGI(TAG, "In mainrn");

        vTaskDelay(1000 / portTICK_RATE_MS);

        // Accel_Device_Read_Accel_Raw(eeprom_handle, Accel_RAW);//加入这句后中断可以连续触发,不会停止

    }

更多回帖

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