Передать typedef в функцию

Я работаю с ESP32S3, который будет управлять двумя портами I2S, поэтому для чистоты моего кода, а также потому, что я буду работать с несколькими установками и деинсталляциями I2S, я хочу переместить все функции в ".cpp .ч»; файл.

что-то вроде этого

  1. I2S_functions.h

    #ifndef I2S_FUNCTIONS_H
    #define I2S_FUNCTIONS_H
    #include <Arduino.h>
    #include <driver/i2s.h>
    
    void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,
    i2s_bits_per_sample_t I2S_SAMPLE_BITS,i2s_channel_fmt_t I2S_CHANNEL,i2s_comm_format_t I2S_COMM_FORMAT_STAND_I2S,int buf_count, int buf_len, bool apll);
    
    #endif
    
    
  2. I2S_functions.cpp

#include "I2S_functions.h"

void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,
i2s_bits_per_sample_t I2S_SAMPLE_BITS,i2s_channel_fmt_t I2S_CHANNEL,i2s_comm_format_t I2S_COMM_FORMAT_STAND_I2S,
int buf_count, int buf_len, bool apll)
{
  const i2s_config_t i2s_config = 
  {
    
    .mode = I2S_MODE,
    //.mode = (i2s_mode_t)(I2S_MODE),
    .sample_rate = I2S_SAMPLE_RATE,
    
    .bits_per_sample = I2S_SAMPLE_BITS,
    .channel_format = I2S_CHANNEL,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
    
    .intr_alloc_flags = 0, // default interrupt priority
    .dma_buf_count = buf_count,//cambiado de 8 a 64
    .dma_buf_len = buf_len,
    .use_apll = apll
  };

  i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
}
  1. main.ino
#include "I2S_functions.h"

// I2S config //////
#include <driver/i2s.h>

#define I2S_PORT I2S_NUM_0
//#define I2S_SAMPLE_RATE  (44100) 
float I2S_SAMPLE_RATE=44100;
int I2S_SAMPLE_BITS=32;
//#define I2S_SAMPLE_BITS  (32)
#define bufferLen 1024
#define I2S_READ_LEN (16*1024)


void setup ()
{
  i2s_install(I2S_PORT,I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE, 
I2S_BITS_PER_SAMPLE_32BIT,I2S_CHANNEL_FMT_ONLY_LEFT,I2S_COMM_FORMAT_STAND_I2S,8,bufferLen,false);

}

Но когда я скомпилировал это, я получил ошибки при передаче второго аргумента: «I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE»

копия ошибки:

C:\Users\.ino: In function 'void setup()':
test_10seg_V2:52:39: error: invalid conversion from 'int' to 'i2s_mode_t' [-fpermissive]
   i2s_install(I2S_PORT,I2S_MODE_MASTER|I2S_MODE_RX,I2S_SAMPLE_RATE,
                        ~~~~~~~~~~~~~~~^~~~~~~~~~~~
In file included from C:\Users\.ino:2:
C:\Users\I2S_functions.h:6:50: note:   initializing argument 2 of 'void i2s_install(i2s_port_t, i2s_mode_t, float, i2s_bits_per_sample_t, i2s_channel_fmt_t, i2s_comm_format_t, int, int, bool)'
 void i2s_install(i2s_port_t I2S_PORT, i2s_mode_t I2S_MODE, float I2S_SAMPLE_RATE,

exit status 1
invalid conversion from 'int' to 'i2s_mode_t' [-fpermissive]

По сути у меня 2 вопроса. Пока я просматривал github из esp32, я обнаружил, что в конфигурации I2S есть некоторый typedef (https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/esp32/include/hal/include/hal/i2s_types.h). Я никогда раньше не работал со структурами такого типа, поэтому думаю, как мне его использовать и, в частности, как передать переменные этого типа в функцию.

typedef enum {
    I2S_BITS_PER_SAMPLE_8BIT    = 8,            /*!< data bit-width: 8 */
    I2S_BITS_PER_SAMPLE_16BIT   = 16,           /*!< data bit-width: 16 */
    I2S_BITS_PER_SAMPLE_24BIT   = 24,           /*!< data bit-width: 24 */
    I2S_BITS_PER_SAMPLE_32BIT   = 32,           /*!< data bit-width: 32 */
} i2s_bits_per_sample_t;

/**
 * @brief I2S bit width per chan.
 *
 */
typedef enum {
    I2S_BITS_PER_CHAN_DEFAULT        = (0),      /*!< channel bit-width equals to data bit-width */
    I2S_BITS_PER_CHAN_8BIT           = (8),      /*!< channel bit-width: 8 */
    I2S_BITS_PER_CHAN_16BIT          = (16),     /*!< channel bit-width: 16 */
    I2S_BITS_PER_CHAN_24BIT          = (24),     /*!< channel bit-width: 24 */
    I2S_BITS_PER_CHAN_32BIT          = (32),     /*!< channel bit-width: 32 */
} i2s_bits_per_chan_t;

мои вопросы

1.- Мне хотелось бы понять, как работают эти структуры. Я хочу максимально очистить свой код, а это означает передачу множества функций из основного файла. Поэтому я приветствую любой ресурс, позволяющий улучшить мои навыки программирования.

2.- Почему код не может передать эти две переменные "I2S_MODE_MASTER|I2S_MODE_RX" ?. Есть ли какой-то особый способ передачи этих переменных, когда одновременно задано 2 параметра?

Спасибо за ваши ответы!

, 👍1

Обсуждение

это скорее общий вопрос по программированию на C++, чем вопрос по Arduino, @jsotola

https://en.wikipedia.org/wiki/Enumerated_type, @Juraj


1 ответ


2

Ответ на вопрос 1: опубликованный вами код typedef — это enum, а не struct. Посмотрите Перечисление C++, и вы найдете множество хороших руководств. Вот одно видео.

Ответ на вопрос 2: вам необходимо привести аргумент вашей функции к типу, чтобы он мог принять его как i2s_mode_t.

i2s_install(I2S_PORT, (i2s_mode_t)(I2S_MODE_MASTER|I2S_MODE_RX), ... ... ...);
,

i2s_mode_t — это пример очень плохого дизайна API. это никогда не должно быть перечислением., @Juraj