Увеличение частоты синусоиды на AVR
Увеличение частоты синусоиды на AVR
Всем привет. У меня такая задачка.
На Atmega 16 получил синусоиду, используя R-2R.
Теперь необходимо, например, раз в секунду увеличивать частоту сигнала на 100 Hz и так от 0 до 10KHz.
С таймерами дела у меня обстоят плохо, помогите реализовать это на CVAVR.
На Atmega 16 получил синусоиду, используя R-2R.
Теперь необходимо, например, раз в секунду увеличивать частоту сигнала на 100 Hz и так от 0 до 10KHz.
С таймерами дела у меня обстоят плохо, помогите реализовать это на CVAVR.
- Реклама
- Engineer_Keen
- Друг Кота
- Сообщения: 3870
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Ну так перебирайте массив быстрее! А каким образом происходит акт обращения к массиву? Если тупо в цикле, тогда поможет только перескакивание через значения. Если по таймеру, то или изменение делителя (грубо - 8, 64 и т.д.) или использование прерывания по сравнению таймера со спец регистрами А или В (плавно 0-255)
- Реклама
- NiTr0
- Друг Кота
- Сообщения: 3051
- Зарегистрирован: Пт авг 10, 2007 12:49:55
- Откуда: kr.ua
- Контактная информация:
Insase писал(а):Есть массив wave[256]
Если хочется уж табличный синтез - то таблички на 64 значения хватит, ибо нефиг дублировать то, то можно высчитать элементарными арифметическими операциями, а если с интерполяцией промежуточных (что для R-2R 5% точности вполне прокатит без ухудшения параметров выходного сигнала) - и того меньше можно урезать, до 16-32 байт...
С таймерами разобрался, wave[256] - это просто для примера пока взял массив.
Получается такая вот штука:
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
k++;
if (k>=freq){
n++;
k=0;
if (n>255) {
n = 0;
freq+=10;
}
PORTC = wave[n];
}
}
Поставив таймер на максимальную частоту получаем, что такт происходит с частотой Foc=16Mhz/2*(1+1), т.е. 4Mhz.
Берем freq=1, каждое значение выплевывается через 0,25мкс
Значит частота выплевывания точки = 4 МГц, а частота выплевывания периода синуса 4МГц/256=15625Гц
Дальше берем f=2, период уже 0,5мкс и частота выплевывания одной точки - 2 мгц.
Значит период синуса в 2 раза меньше, т.е. 7кгц.
Как менять частоту синуса линейно?
Получается такая вот штука:
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
k++;
if (k>=freq){
n++;
k=0;
if (n>255) {
n = 0;
freq+=10;
}
PORTC = wave[n];
}
}
Поставив таймер на максимальную частоту получаем, что такт происходит с частотой Foc=16Mhz/2*(1+1), т.е. 4Mhz.
Берем freq=1, каждое значение выплевывается через 0,25мкс
Значит частота выплевывания точки = 4 МГц, а частота выплевывания периода синуса 4МГц/256=15625Гц
Дальше берем f=2, период уже 0,5мкс и частота выплевывания одной точки - 2 мгц.
Значит период синуса в 2 раза меньше, т.е. 7кгц.
Как менять частоту синуса линейно?


