StoreProjected Ошибка на ESP32 при вызове функции i2s_read - PullRequest
0 голосов
/ 06 января 2019

Я пытаюсь использовать датчик микрофона на моем микроконтроллере esp32. В настоящее время работает ESP-IDF. Микрофон sph0645lm4h-b. Я использую протокол I2S для подключения к датчику.

Конфигурация I2S показана ниже:

    void i2s_init()
{
    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_RX, // I2S_MODE_TX Only TX
        .sample_rate = 17000,
        .bits_per_sample = 32,
        // .channel_format = I2S_CHANNEL_FMT_ALL_LEFT, //2-channels
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 8,
        .dma_buf_len = 64,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1
    };
    i2s_pin_config_t pin_config = {
        .bck_io_num = 26,
        .ws_io_num = 25,
        .data_out_num = -1, //Not used
        .data_in_num = 27
        };
    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM, &pin_config);
}

Код, который собирает данные:

i2s_init(); //initializes mics 
int samples_value, samples_data;
samples_value = i2s_pop_sample(I2S_NUM, &samples_data, 2);
printf("%d,", samples_data);

Когда я загружаю код в микроконтроллер, я получаю запутанные данные. Выходы чередуются от действительно отрицательного значения и 1.

Данные:

-191725568,1,-191823872,1,-191889408,1,-192020480,1,-192118784,1,-190152704,1,-190054400,1,-190021632,1

Я не уверен, что это данные, которые я должен получать от датчика микрофона, и я прочитал в документации I2S , что i2s_pop_sample устарел, поэтому я попытался использовать i2s_read, но я получение StorePro Error.

Код для i2s_read:

int *samples;
int s;
samples = &s;       //pointer initialization

i2s_read(I2S_NUM,&samples,4,4,2); 

Ошибка:

Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
        Core 0 register dump:
    PC      : 0x400d7552  PS      : 0x00060b30  A0      : 0x800d1c9f  A1      : 0x3ffcc950
    A2      : 0x00000000  A3      : 0x3ffccaa8  A4      : 0x00000004  A5      : 0x00000004
    A6      : 0x00000002  A7      : 0x00000005  A8      : 0x800d1e72  A9      : 0x3ffcc900
    A10     : 0x3d87e746  A11     : 0x00000000  A12     : 0x00000001  A13     : 0x00000002
    A14     : 0x7f800000  A15     : 0x00000000  SAR     : 0x00000015  EXCCAUSE: 0x0000001d
    EXCVADDR: 0x00000004  LBEG    : 0x40002390  LEND    : 0x4000239f  LCOUNT  : 0x00000000

    Backtrace: 0x400d7552:0x3ffcc950 0x400d1c9c:0x3ffcc990 0x400e9994:0x3ffccae0

1 Ответ

0 голосов
/ 07 января 2019

Я просто собираюсь решить проблему i2s_read(), поскольку i2s_pop_sample() устарела.

При вызове i2s_read() вы используете указатель в качестве буфера данных и передаете целое число в качестве указателя.

Вот прототип i2c_read(), взятый из руководства ESP-IDF .

esp_err_t i2s_read(i2s_port_ti2s_num, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait)
  • i2s_num - это номер порта i2s
  • dest - адрес буфера для чтения данных в
  • size - размер буфера
  • bytes_read - указатель на size_t, в котором будет записано количество прочитанных байтов
  • ticks_to_wait - это тайм-аут

Есть две проблемы с аргументами, которые вы передали i2s_read(). Вы называете это так:

int *samples;
int s;
samples = &s;

i2s_read(I2S_NUM,&samples,4,4,2); 

Вы передаете &samples в качестве адреса буфера. Итак, что вы говорите i2s_read() - это прочитать 4 байта данных и сохранить их в samples, что не имеет большого смысла, так как это указатель. Вы должны просто передать &s в качестве буфера и пропустить перебор с samples.

Вторая проблема - вы передаете 4 в качестве аргумента bytes_read. Я на самом деле удивлен, что это даже скомпилировано. Это i2s_read() пытается сохранить size_t с количеством байтов, прочитанных по адресу 4, что, безусловно, вызовет какое-то исключение.

Попробуйте это:

int32_t sample;
size_t bytes_read;

i2s_read(I2S_NUM, &sample, 4, &bytes_read, 2); 

Это:

  1. не делает никаких предположений о размере хранилища int и гарантирует 4-байтовое (32-битное) целое число для sample
  2. правильно передает указатель на 4-байтовое целое число, созданное для хранения данных, считанных i2s_read()
  3. правильно передает указатель на size_t, так что i2s_read() может сохранить число из прочитанных байтов.

А если вы хотите узнать, сколько фактически было прочитано байтов, это в bytes_read.

...