Usa Hongmeng OS para reproducir una canción "Two Tigers" en el timbre

Este artículo describe cómo utilizar la interfaz PWM del subsistema de hardware Harmony OS IoT para activar el timbre y reproducir música en el kit HiSpark Wi-Fi IoT.

API para generar onda cuadrada con PWM

El subsistema de hardware de IoT del sistema Hongmeng proporciona interfaces relacionadas con PWM, el archivo de encabezado de la interfaz es wifiiot_pwm.h, y la interfaz para comenzar a generar ondas cuadradas es:

/**
 * @brief Outputs PWM signals based on the input parameters.
 *
 * This function outputs PWM signals from a specified port based on
 * the configured frequency division multiple and duty cycle.
 *
 * @param port Indicates the PWM port number.
 * @param duty Indicates the PWM duty cycle.
 * @param freq Indicates the frequency-division multiple.
 * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful;
 * returns an error code defined in {@link wifiiot_errno.h} otherwise.
 * @since 1.0
 * @version 1.0
 */
unsigned int PwmStart(WifiIotPwmPort port, unsigned short duty, unsigned short freq);

Frecuencia de onda cuadrada de salida PWM

A través de la anotación de la interfaz PwmStart, puede saber que el parámetro de frecuencia es el múltiplo de división de frecuencia, y la frecuencia de onda cuadrada realmente emitida por el PWM es igual a la frecuencia de la fuente de reloj PWM dividida por el múltiplo de división de frecuencia, es decir

f = Fcs / frecuencia

Entre ellos, Fcs es la frecuencia de la fuente de reloj PWM;

Ciclo de trabajo de onda cuadrada de salida PWM

A través del parámetro de trabajo de la interfaz PwmStart, se puede controlar el ciclo de trabajo de la onda cuadrada de salida. El ciclo de trabajo se refiere a la relación entre el tiempo de alto nivel de la forma de onda de onda cuadrada emitida por el PWM y el ciclo de onda cuadrada completo. El valor del ciclo de trabajo específico es la relación de trabajo y frecuencia , Por ejemplo, si desea generar una señal de onda cuadrada con un ciclo de trabajo del 50%, el valor del trabajo debe ser freq / 2;

Correspondencia nota-frecuencia
Inserte la descripción de la imagen aquí

Hay una regla en esta tabla: el tono aumenta en una octava y la frecuencia se duplica.

El formulario proviene de: https://liam.page/2018/04/09/pitch-interval-and-harmonic/

La frecuencia más baja que puede generar la placa de desarrollo a
partir de la fórmula anterior, la conocemos:

  1. La frecuencia de la salida de onda cuadrada por el PWM es inversamente proporcional a la frecuencia, cuanto mayor es la frecuencia, menor es la frecuencia de la onda cuadrada de salida;

  2. freq es un tipo corto sin cantar, y el valor máximo es 65535;
    por lo tanto, el valor mínimo de la frecuencia de salida depende de la fuente de reloj, y la fuente de reloj predeterminada de PWM es 160M:
unsigned int HalPwmInit(HalWifiIotPwmPort port)
{
    if (hi_pwm_set_clock(PWM_CLK_160M) != HI_ERR_SUCCESS) {
        return (unsigned int)HAL_WIFI_IOT_FAILURE;
    }
    return hi_pwm_init((hi_pwm_port)port);
}

Bajo la condición de fuente de reloj de 160M, la frecuencia más baja de la onda cuadrada de salida es: 160M / 65535 = 2441.44 ..., esta frecuencia es aún un poco más alta y no se encuentran nombres de sonido en la tabla anterior. Pero puedo usar los valores en la tabla anterior para calcular dos octavas y luego puedo cubrir esta frecuencia (pero generalmente solo se usan 7 octavas, por lo que todavía es un poco alto).

Si la frecuencia de la fuente de reloj puede ser menor, la frecuencia de salida también puede ser menor.
Afortunadamente, la fuente del reloj se puede modificar llamando a la interfaz hi_pwm_set_clock:

/**
 * @ingroup iot_pwm
 *
 * Enumerates the PWM clock sources.CNcomment:PWM时钟源枚举。CNend
 */
typedef enum {
    PWM_CLK_160M, /**< 160M APB clock.CNcomment:160M 工作时钟 CNend */
    PWM_CLK_XTAL, /**< 24M/40M crystal clock.CNcomment:24M或40M 晶体时钟 CNend */
    PWM_CLK_MAX   /**< Maximum value, which cannot be used.CNcomment:最大值,不可使用CNend */
} hi_pwm_clk_source;

hi_u32 hi_pwm_set_clock(hi_pwm_clk_source clk_type);

A través de los comentarios, sabemos que hi_pwm_set_clock (PWM_CLK_XTAL); puede configurar la fuente del reloj en el reloj de cristal, el reloj de cristal puede ser 24M o 40M;
entonces la pregunta es: ¿cuál es la frecuencia del reloj de cristal?

¿Cuál es la frecuencia del reloj de cristal?
La frecuencia del reloj de cristal se puede calcular a través de experimentos, los pasos específicos son los siguientes:

  1. Utilice hi_pwm_set_clock (PWM_CLK_XTAL); para configurar la fuente del reloj en reloj de cristal;

  2. Utilice PwmStart (WIFI_IOT_PWM_PORT_PWM0, 20 1000, 40 1000); señal de onda cuadrada de salida;

  3. Utilice un osciloscopio para medir la frecuencia de onda cuadrada y calcule la frecuencia de la fuente de reloj de acuerdo con la frecuencia medida;

Después de la medición real, la frecuencia de onda cuadrada es 1000 Hz,

Por lo tanto, la frecuencia de reloj es 1000 40 1000, que es 40 MHz;

La frecuencia más baja de la onda cuadrada que se puede emitir.
Por lo tanto, la frecuencia más baja de la onda cuadrada es 40M / 65535, que es:

40 1000 1000/65535
610.3608758678569
tabla de frecuencia de control anterior, se sabe, sobre todo capaz de emitir notas y E5;

Preparar la partitura
Para facilitar la implementación del código, elegí la partitura de "Two Tigers" como material y encontré la partitura en la red musical numerada:
Inserte la descripción de la imagen aquí

La notación musical numerada explica
algunas de las marcas en la notación musical numerada. Es posible que algunos estudiantes no sepan lo que significan. Aquí hay una breve explicación:

  1. El 1 = C en la esquina superior izquierda significa el modo (no necesita preocuparse por eso), 1 es el nombre del rollo, C es el nombre de la nota, 1 = C es el tono de avance (la correspondencia normal: 1-C, 2-D, 3-E, 4 -F, 5-G, 6-A, 7-B);

  2. El 4/4 en la esquina superior izquierda es de cuatro o cuatro tiempos, lo que significa que la negra es un tiempo y hay cuatro tiempos por compás;

  3. La línea vertical en la partitura a continuación es cada barra de separación, correspondiente a 4/4;

  4. "Ejecutar rápido" La línea horizontal detrás de 5 indica un retraso de un tiempo;

  5. En la oración "uno sin ojos", el punto después del 5 significa medio tiempo, un subrayado significa la mitad del tiempo y dos subrayados significan un cuarto de tiempo;

Escribir código
Con el conocimiento anterior, podemos escribir código, el código clave es el siguiente:

static const uint16_t g_tuneFreqs[] = { // 音符对应的分频系数
    0, // 40M Hz 时钟源,C6 ~ B6:
    38223, // 1 1046.5
    34052, // 2 1174.7
    30338, // 3 1318.5
    28635, // 4 1396.9
    25511, // 5 1568
    22728, // 6 1760
    20249, // 7 1975.5
    51021 // 5_ 783.99 // 低一个八度的 5
};

// 曲谱音符
static const uint8_t g_scoreNotes[] = {
    // 《两只老虎》简谱:http://www.jianpu.cn/pu/33/33945.htm
    1, 2, 3, 1,        1, 2, 3, 1,        3, 4, 5,  3, 4, 5,
    5, 6, 5, 4, 3, 1,  5, 6, 5, 4, 3, 1,  1, 8, 1,  1, 8, 1, // 最后两个 5 应该是低八度的,链接图片中的曲谱不对,声音到最后听起来不太对劲
};

// 曲谱时值,根据简谱记谱方法转写
static const uint8_t g_scoreDurations[] = {
    4, 4, 4, 4,        4, 4, 4, 4,        4, 4, 8,  4, 4, 8,
    3, 1, 3, 1, 4, 4,  3, 1, 3, 1, 4, 4,  4, 4, 8,  4, 4, 8,
};

static void *BeeperMusicTask(const char *arg)
{
    (void)arg;

    printf("BeeperMusicTask start!\r\n");

    hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟(40MHz,默认时钟源160MHz)

    for (size_t i = 0; i < sizeof(g_scoreNotes)/sizeof(g_scoreNotes[0]); i++) {
        uint32_t tune = g_scoreNotes[i]; // 音符
        uint16_t freqDivisor = g_tuneFreqs[tune];
        uint32_t tuneInterval = g_scoreDurations[i] * (125*1000); // 音符时间
        printf("%d %d %d %d\r\n", tune, (40*1000*1000) / freqDivisor, freqDivisor, tuneInterval);
        PwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor/2, freqDivisor);
        usleep(tuneInterval);
        PwmStop(WIFI_IOT_PWM_PORT_PWM0);
    }

    return NULL;
}

Los dos últimos 5 en la partitura son incorrectos, deberían ser 5 octavas más bajos, es decir, debería haber un punto debajo del 5. Modifiqué el código para que toda la canción suene más natural;

Código completo:https://gitee.com/hihopeorg/HarmonyOS-IoT-Application-Development/blob/master/02_device_control/beeper_music_demo.c


Enlace original:
https://developer.huawei.com/consumer/cn/forum/topic/0204398682948650101?fid=0101303901040230869
Autor: Thinking

Supongo que te gusta

Origin blog.51cto.com/14772288/2549430
Recomendado
Clasificación