Posiadam taki program, który działa i odtwarza na płytce dźwięk zapisany w osobnym pliku jako długi ciąg danych w formacie szesnastkowym:
#include "mcu_regs.h"
#include "type.h"
#include "uart.h"
#include "stdio.h"
#include "timer32.h"
#include "gpio.h"

extern const unsigned char sound_8k[];
extern int sound_sz;


int main (void) {

    int i = 0;
    uint32_t cnt = 0;
    uint32_t off = 0;
    uint32_t sampleRate = 0;

    GPIOInit();

    UARTInit(115200);
    UARTSendString((uint8_t*)"Speaker - Tone\r\n");

    GPIOSetDir( PORT1, 9, 1 ); // GPIO_28 - CT16B1MAT0 jako out
    GPIOSetDir( PORT1, 10, 1 ); // GPIO_29 - CT16B1MAT1

    GPIOSetDir( PORT3, 0, 1 ); // clock wzmacniacza na out GPIO_21
    GPIOSetDir( PORT3, 1, 1 ); // up/dn wzmacniacza na out GPIO_22
    GPIOSetDir( PORT3, 2, 1 ); // shutdn wzmacniacza na out GPIO_23
    GPIOSetDir( PORT1, 2, 1 ); // timer 32 bitowy B1 - match 1 GPIO_14

    LPC_IOCON->JTAG_nTRST_PIO1_2 = (LPC_IOCON->JTAG_nTRST_PIO1_2 & ~0x7) | 0x3; //enable CT32B1_MAT1

    GPIOSetValue( PORT3, 0, 0 );  //LM4811-clk
    GPIOSetValue( PORT3, 1, 0 );  //LM4811-up/dn
    GPIOSetValue( PORT3, 2, 0 );  //LM4811-shutdn

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);

    LPC_TMR32B1->TCR = 2;     //reset counter
    LPC_TMR32B1->TCR = 0;
    LPC_TMR32B1->PR = 0;      //prescaler = 0
    LPC_TMR32B1->MCR = (1<<10)|(1<<9); //reset TC on MC3 match
    LPC_TMR32B1->MR3 = 286;   //set period     //256
    LPC_TMR32B1->MR1 = 127;   //set duty cycle
    LPC_TMR32B1->PWMC = 2;    //enable PWM on MAT1 output
    LPC_TMR32B1->IR = 0xf;
    LPC_TMR32B1->TCR = 1;     //counter enable


    /* ChunkID */
    if (sound_8k[cnt] != 'R' && sound_8k[cnt+1] != 'I' &&
        sound_8k[cnt+2] != 'F' && sound_8k[cnt+3] != 'F')
    {
        UARTSendString((uint8_t*)"Wrong format (RIFF)\r\n");
        return 0;
    }
    cnt+=4;

    /* skip chunk size*/
    cnt += 4;

    /* Format */
    if (sound_8k[cnt] != 'W' && sound_8k[cnt+1] != 'A' &&
        sound_8k[cnt+2] != 'V' && sound_8k[cnt+3] != 'E')
    {
        UARTSendString((uint8_t*)"Wrong format (WAVE)\r\n");
        return 0;
    }
    cnt+=4;

    /* SubChunk1ID */
    if (sound_8k[cnt] != 'f' && sound_8k[cnt+1] != 'm' &&
        sound_8k[cnt+2] != 't' && sound_8k[cnt+3] != ' ')
    {
        UARTSendString((uint8_t*)"Missing fmt\r\n");
        return 0;
    }
    cnt+=4;

    /* skip chunk size, audio format, num channels */
    cnt+= 8;

    sampleRate = (sound_8k[cnt] | (sound_8k[cnt+1] << 8) |
            (sound_8k[cnt+2] << 16) | (sound_8k[cnt+3] << 24));

    if (sampleRate != 8000) {
        UARTSendString((uint8_t*)"Only 8kHz supported\r\n");
        return 0;
    }

    cnt+=4;

    /* skip byte rate, align, bits per sample */
    cnt += 8;

    /* SubChunk2ID */
    if (sound_8k[cnt] != 'd' && sound_8k[cnt+1] != 'a' &&
        sound_8k[cnt+2] != 't' && sound_8k[cnt+3] != 'a')
    {
        UARTSendString((uint8_t*)"Missing data\r\n");
        return 0;
    }
    cnt += 4;

    /* skip chunk size */
    cnt += 4;

    off = cnt;

    while(1)
    {
        int val;


        cnt = off;
        while(cnt++ < sound_sz)
        {

            LPC_TMR32B1->MR1 = sound_8k[cnt]+30;

            for (val=0;val<32;val++)
            {
                while (!(LPC_TMR32B1->IR & 0x8));
                LPC_TMR32B1->IR = 0xf;
            }
        }

        //delay
        for(i=0; i<0x100000; i++)
            __ASM(" nop");
    }


    return 0 ;
}
Z tego co rozumiem odbywa się to przez 32 bitowy timer, którego match 1 jest podłączony z generatorem PWM z wbudowanym filtrem LC, który z kolei jest podłączony do wzmacniacza, a ten do głośniczka. Problem w tym, że nie za bardzo rozumiem co się dzieje w głównej pętli programu, gdzie jest odtwarzany dźwięk. Wytłumacz krok po kroku co się dzieje w tej pętli, jeśli oczywiście jesteś w stanie to zrobić na podstawie tylko tego kodu. Czy potrzebujesz do analizy kodu bibliotek dołączanych do programu, bądź dokumentacji płytki?