ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ARM MBED 엠베드 음악 연주하기 (내장 DAC 사용)
    개발 팁/Embedded 2017. 11. 12. 02:37
    반응형





    여러가지 방법이 있지만 일단 DAC 아날로그 출력을 이용한 방법을 소개한다.


    1) 엠베드 NXP FRDM K64F 보드에는 DAC 출력 (아날로그 출력)이 있어 그것을 이용한다.

    스피커와 보드의 연결은 다음과 같다:

    DAC output -> 스피커 +

    GND -> 스피커 -




    2) 아날로그 출력 관련 소스를 가져온다.

    https://os.mbed.com/users/4180_1/code/speaker_demo_Analog/

    mbed add가 안되니 그냥 header 파일(Speaker.h)을 가져와서 프로젝트에 넣으면 된다.

    이 헤더파일에 포함된 Speaker class를 이용한다.


    음악 연주에 대해서는 아두이노 관련 코드를 참조한다:

    https://gist.github.com/baojie/4522173


    3) K64F 소스 코드의 경우 DAC Enable 코드가 막혀 있다. 이를 해결한다.

    아래 부분에서 DAC Enable 코드를 찾아 주석 처리를 없앤다.

    파일 위치: 프로젝트폴더/mbed-os/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_dac.c

    DAC_Enable(base, true);


    4) Speaker Class(와 아두이노 예제)를 이용하여 작성한 예제 코드

    작성한 코드는 아래와 같다. 곡은 반짝반짝 작은별이다.


    #include "mbed.h"
    #include "Speaker.h" // https://os.mbed.com/users/4180_1/code/speaker_demo_Analog/

    #define LITTLE_STAR

    void playNote(char note, int duration);
    void playSong( void );

    #ifdef LITTLE_STAR
    char notes[] = "ccggaag ffeeddc ggffeed ggffeed ccggaag ffeeddc "; // a space represents a rest
    float beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1 };
    int tempo = 210;
    int length = 47; // the number of notes
    #endif

    Speaker mySpeaker(DAC0_OUT);

    // main() runs in its own thread in the OS
    int main( void ) {

    printf( "\nplaySong\n" );
    playSong();

    }

    void playSong( void ) {
    for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
    // printf( "wait_ms1\n");
    wait_ms(beats[i] * tempo); // rest
    } else {
    playNote(notes[i], beats[i] * tempo);
    }
    // printf( "wait_ms2\n");
    // pause between notes
    wait_ms(tempo / 2);
    }
    }
    void playNote(char note, int duration) {
    char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
    int tones[] = { 1046, 1174, 1318, 1396, 1567, 1760, 1975, 2093 };
    // play the tone corresponding to the note name
    for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
    // printf ("mySepaker.Playnote([%c]%d, (%d)%f, 1.0)\n", names[i], tones[i], duration, duration/600.0);
    mySpeaker.PlayNote(tones[i], duration/600.0, 0.1);
    }
    }
    }

    # 몇가지 파라메터 셋팅에 따라 딜레이가 달라지며, 그 결과로 인터럽트 쪽이 죽는 경우가 종종 발생한다. 셋팅을 바꾸든지, printf를 넣어서 타이밍이 달라지면 정상 동작한다. 이 부분은 나중에 수정해야 할 듯 하다.


    출처 및 관련자료

    https://os.mbed.com/users/4180_1/code/speaker_demo_Analog/

    Using a speaker for audio output, https://os.mbed.com/users/4180_1/notebook/using-a-speaker-for-audio-output/

    AnalogOut does not work for K64F, https://github.com/ARMmbed/mbed-os/issues/3999

    Plat twinkle twinkle little star in Aduino, https://gist.github.com/baojie/4522173




    반응형

    댓글

Designed by Tistory.