Программируйте ATtiny13 как аудио генератор с переменной частотой и длительностью импульса

8

Я хочу создать простой генератор прямоугольных импульсов, аналогичный тому, который можно сделать с 555, но я хочу использовать поддержку ШИМ на основе прерываний для управления шириной и частотой импульсов.

Я изучал таблицу данных, API-интерфейсы AVR и все примеры ШИМ, которые я могу найти, но я не совсем смог собрать все это вместе.

Можно ли создать такой генератор со встроенной функцией AVR PWM и, если да, то как? Мой друг сделал нечто подобное с 8-контактным ПИК.

Я рассуждаю так: я получу интересные звуки, меняя ширину импульса и, следовательно, форму волны на заданной частоте. Подобно тому, как работает Atari Punk Console, но, надеюсь, более стабильным способом, то есть изменением ширины импульса, но оставляя частоту постоянной или наоборот.

шум
источник
2
не могли бы вы уточнить, в чем ваш вопрос?
Джейсон С
Я не уверен, насколько они будут интересны, но это легко попробовать, и вы можете судить. По мере сужения импульса амплитуды гармоник возрастают. Продолжайте сужать пульс, и вы получите белый шум. Я думаю, что у вас было бы больше интересных вариантов сделать генератор с числовым управлением. Вы можете изменить сигналы, загруженные в таблицу.
jluciani

Ответы:

5

Это поможет вам продвинуться довольно далеко, а остальное вы сможете сделать с помощью таблицы данных. Начните строить по частям, от мерцания до формы волны, чтобы форма волны менялась со временем на тона. Некоторые источники могут помочь с фильтрацией и воспроизведением аудиовыходов (активный LPF может выполнять оба действия аккуратно).

Я предлагаю вернуться с более конкретными вопросами.

tissit
источник
4

Период ШИМ определяется скоростью переполнения вашего таймера. В разделе «Режимы работы» есть много настроек, о которых стоит подумать. Если все, что вы хотите сделать, это сгенерировать прямоугольную волну с постоянным периодом с переменным рабочим циклом, я думаю, вы захотите использовать режим CTC (Сброс таймера при сравнении совпадений). Основная идея состоит в том, чтобы установить OCR0A на число тактов таймера до тех пор, пока вы не захотите, чтобы штифт переключился в следующий раз, и использовать прерывание Compare Match, чтобы изменить это значение в следующий раз. Так что в avr-gcc это будет выглядеть примерно так:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

// global variables defining number of ticks on and off
uint8_t on_time_ticks, off_time_ticks, csxx_bits=0; 


void setup_timer(double p_ms, double duty){
  TCCR0A = _BV(COM0A0) // toggle OC0A on Compare Match
  TCCR0B = _BV(WGM02); // set CTC mode WGM0[2,1,0] = 0b100

  // ... do some stuff based on your CPU frequency
  // to define the csxx_bits of TCCR0B when the timer is running
  // and consequently, to set on_time_ticks and off_time_ticks
  OCR0A = on_time_ticks;
  TCCR0B |= your_settings_here;
}


void start_timer(){
  //start the timer running at the desired rate
  TCCR0B |= csxx_bits; 
}


int main(int argc, char **argv){
  double period_ms, duty_cycle;
  setup_timer(period_ms, duty cycle);
  start_timer();  
  for(;;){
    //spin or sleep or whatever
  }
}


ISR(TIM0_COMPA_vect){
  if(OCR0A == on_time_ticks){
    OCR0A = off_time_ticks;
  }
  else{
    OCR0A = on_time_ticks;
  }
}

Предупреждение, это непроверенный код, но я думаю, что идея верна. Это ни в коем случае не единственный способ сделать это.

Кстати, есть одна вещь, которую вы должны знать о ATTiny13. Точность внутреннего генератора RC гарантируется только в пределах 10% от заводского уровня. Вы можете пройти процедуру пользовательской калибровки (описанную приложением atmel ), которая обеспечит вам точность 2% для ATTiny13. Если вы хотите добиться большего, чем это, вам, вероятно, понадобится использовать чип, который поддерживает внешний кристалл ...

vicatcu
источник
1
Ваш ответ помог прояснить нечто подобное, с чем у меня были проблемы - спасибо. Одно замечание (для тех, кто читает это много позже оригинальной темы): ваш выбор 0b100 для WGM0 [2,1,0] не будет устанавливать режим CTC. (Фактически он установит режим, зарезервированный Atmel.) В спецификации ATtiny13 сказано, что режим CTC требует значения 2; вы случайно дали ему bit_number 2 (т.е. значение 4). Из-за этого также необходимо не только изменить (т.е. очистить) WGM02 в TCCR0B, но также установить биты WGM01 и WGM00 в 1 и 0 соответственно. Эти биты находятся в TCCR0A, поэтому недостаточно установить TCCR
3

Не прямой ответ на ваш вопрос, но это может быть уместно и дать некоторые советы -

Я только что создал генератор с числовым управлением (NCO), используя ATmega uC и ЦАП. Массив целых чисел используется для хранения одного цикла формы волны (wavetable). Аккумулятор фазы (long int) используется для определения адреса выходных данных в волновой таблице. Каждое прерывание таймера увеличивает фазовый аккумулятор на фиксированное значение. Приращение фазы определяет частоту.

В моем приложении я использовал 64-байтовую таблицу, которая содержала один цикл синусоиды. Легко расширить волновую таблицу и добавить большее разрешение к образцам. Моя заявка на приложение находится по адресу http://wiblocks.com/docs/app-notes/nb1a-nco.html.

jluciani
источник
1

В основном ШИМ не меняет частоту. ШИМ в основном используются для контроля «интенсивности» сигнала.

Для генерации прерывания для разных частот я бы предложил использовать таймер в режиме CTC.

Он будет работать с вашим значением сравнения, переключать прерывания, очищать и перезапускать себя, пока снова не достигнет вашего значения сравнения ...

После каждого прерывания вы можете переключать один или несколько портов, а в остальное время (таймер все еще работает автоматически) вы можете наблюдать за любыми входами ...

Вы все еще можете «модулировать» свою прямоугольную волну с помощью ШИМ для управления «усилением». Но один из них должен быть сделан "вручную", потому что у ATtiny13 есть только один аппаратный таймер ...

Greenonline
источник
1
большинство аппаратных ШИМ-периферийных устройств позволяют выбирать частоту; если вы сохраняете постоянный рабочий цикл, то ШИМ все еще может дать вам управление переменной частотой
Jason S
1
Изменение ширины импульса не меняет основную частоту, но меняет гармоники.
Jluciani