Translations of this page:

Проигрывание семпла записанного во внутренний флеш

Теперь попробуем озвучить нашу ёлочку чудесными звуками звонка от старого телефона. Качества звука нам на этом этапе не добиться, из-за примитивности железной части, но программную реализацию отработать удастся.

Будем развивать написанный ранее скелет приложения.

Настройка ШИМ

ШИМ - Широтно-импульсная модуляция один из методов преобразования цифорового сигнала в аналоговый. В нашем случае мы будет преобразовывать цифровую величину сигнала в отклонение диафрагмы динамика, и следовательно в звук. Желающие, могут ознакомится с популярным изложением принципов работы ШИМ.

Подробное описание можно найти в LPC210x User Manual 'Chapter 15: LPC2104/05/06 Pulse Width Modulator (PWM)'.

Изменения в программном коде коснулись файла main.c

main.c

...
 
// Расположение и размер звукового семпла записанного во FLASH память процессора.
char* phonebell_raw = (char *)0x010000;
unsigned int phonebell_raw_len = 43866;
 
// Инициализация PWM
void initSound(void)
{
    // При отключенном PWM мы должны отключать и устройства им управляемые
    IODIR   |= (1<<7) | (1<<21);
    IOSET   = (1<<7);  // Выключаем динамик
    IOCLR   = (1<<21); // Выключаем светодиод
 
    //initialize PWM unit and start PWM2
    PWM_PR  = 0x00;    // Настраиваем предделитель счётчика PWM (0 - нет деления)
    PWM_MCR = 0x02;    // Сброс счётчика PWM при совпадении с MR0
    PWM_MR0 = 256;     // Период счёта 256 шагов, при достижении этого значения произойдёт сброс счётчика
    PWM_MR2 = 0;       // Ширина импульса PWM2
    PWM_MR5 = 0;       // Ширина импульса PWM5
    PWM_LER = (1<<5) | (1<<2) | (1<<0);    // Защёлкиваем значения из MR0, MR2, MR5 во внутренние регистры сравнения
    PWM_PCR = (1<<10) | (1<<13);  // Разрешаем вывод импульсов PWM2, PWM5 на выводы процессора
    PWM_TCR = 0x09;    // Разрешаем счёт (bit 0), разрешаем режим PWM (bit 3)
    // Подробное описание регистров смотрите в официальном User Manual
 
}
 
void playSound(void)
{
    unsigned int i, j;
    char v;
    char* p = phonebell_raw;
 
    // Подключаем выводы процессора к выходам ШИМ
    // Enable PWM2 on P0.7
    PINSEL0 &= ~(3<<14);
    PINSEL0 |= (2<<14);
 
    // Enable PWM5 on P0.21
    PINSEL1 &= ~(3<<10);
    PINSEL1 |= (1<<10);
 
    for(i=0; i<phonebell_raw_len; ++i)
    {
        v = *p;
        //v = i & 0xff;
        PWM_MR2 = v; // Выставляем новую ширину импульсов
        PWM_MR5 = v;
        PWM_LER = (1<<5) | (1<<2);    // Защелкиваем новые значения
        p++;
        for (j = 0; j < 400; j++ ); // "Ленивая" задержка
    }
 
    // Отключаем выводы от PWM
    PINSEL0 &= ~(3<<14);
    PINSEL1 &= ~(3<<10);
 
}
 
...

И в Makefile у нас появилась новая цель, для прошивки звукового фрагмента во вторую половину памяти:

Makefile

...
 
loadwav:
	$(LPCFLASH) $(LPCFLAGS) -e 4:4
	$(LPCFLASH) $(LPCFLAGS) -p 0x10000 -l phonebell.raw

После приведённых манипуляций проект примет следующий вид: 03-pwm-use.tar.gz (см. также репозиторий).

Отметим следующие моменты:

  • Регистры PINSELx управляют подключением внутренней преферии процессора к внешним выводам (см. LPC210x User Manual 'Chapter 7: LPC2104/05/06 Pin connect block')
  • После загрузки новых значений в регистры PWMMRx необходимо защёлкнуть их содержимое во внутренние регистры сравнения записав регистр PWMLER.
, ,

Дискуссия

Enter your comment (wiki syntax is allowed):
 
tutorial/arm-lpc2104-intro/03-pwm-use.txt · Последние изменения: 2008/09/30 01:00 От plumbum
 
За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии:CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Valid XHTML 1.0 Valid CSS Driven by DokuWiki $ Баблабы