Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прошивка для ATmega16
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Nameless19
Здравствуйте! Очень нужна помощь с созданием прошивки для ATmega16 (на C++).
Задача: реализовать цифровой режекторный фильтр (БИХ,Чебышева 2 рода) на мк AVR. Параметры фильтра: нижняя полоса пропускания 0-30 Гц, верхняя - 220 - 525 Гц, полоса подавления - от 50 до 200 Гц, уровень пульсаций в полосе пропускания - 3 дБ, в полосе подавления - 20 дБ. Фильтр 4 порядка, реализуется в параллельной структуре, билинейное звено - в прямой схеме.
Используются мк ATmega16 и ЦАП MAX504. Есть пример кода, только работать он не хочет, а в чем дело - разобраться не могу.
CODE
#include <mega16.h>
//запишем коэффициенты в энергонезависимую память EEPROM
eeprom float b01 = 0.859872,b11 = -1.541836,b21=0.859872,
a11 = -1.3647, a21 = 0.65341,
b02 = 0.859872,b12 = -1.635476,b22=0.85987,
a12 = -1.787, a22 = 0.8389;
double rn,rn1,rn2,y1n,y1n1,y1n2,y2n,y2n1,y2n2;
// Результат преобразования АЦП
unsigned int read_adc()
{
ADCSRA|=0x40; //Регистр управления состоянием АЦП, запуск АЦП
while ((ADCSRA & 0x10)==0); //Ждем завершения преобразования АЦП
ADCSRA|=0x10;
return ADCW;
}

out(double out_var)
{
int vix,i,a[10];
vix = (int)out_var;
for (i=0;i<10;i++) {a[10-i]= vix%10; vix = vix/10;};
PINB.2 = 1;
PIND.0 = a[10]; PIND.1 = a[9];
PIND.2 = a[8]; PIND.3 = a[7];
PIND.4 = a[6]; PIND.5 = a[5];
PIND.6 = a[4]; PIND.7 = a[3];
PINB.0 = a[2]; PINB.1 = a[1];
PINB.2 = 0;
}

void main(void)
{

PORTB=0x00; //Программируем порт В на вывод
DDRB=0xFF;

PORTC=0x00; //С на ввод
DDRC=0x00;

PORTD=0x00; //D на вывод
DDRD=0xFF;

MCUCR=0x00;// прерывания выключены
TIMSK=0x00;

ACSR=0x80; //компаратор выключен
SFIOR=0x00;

ADMUX=0x40; //вход АЦП - ADC0, опорное напряжение - AVcc
ADCSRA=0x85;// Разрешение работы АЦП, частота преобразования 375 кГц

rn = read_adc();
y1n = b01*rn;
y2n = b02*y1n;
out(y2n);
y1n1 = y1n; y2n1 = y2n;
rn1 = rn; rn = read_adc();
y1n = b01*rn+b11*rn1 - a11*y1n1;
y2n = b02*y1n + b12*y1n1 - a12*y2n1;
out(y2n);
while (1)
{
y1n2 = y1n1;
y1n1 = y1n;
rn2 = rn1;
rn1 = rn;
rn = read_adc();
y1n = b01*rn+b11*rn1+b21*rn2-a11*y1n1-a21*y1n2;
y2n2 = y2n1;
y2n1 = y2n;
y2n = b02*y1n+b12*y1n1+b22*y1n2-a12*y2n1-a22*y2n2;
out(y2n);
};
}
Xenia
У вас с выводом, функцией
out(double out_var)
что-то не то.
Значения массива a[] по смыслу алгоритма заполнения - десятичные цифры округленного числа,
а вы их битам присваиваете, из-за чего их содержимое фактически теряется.

Что там за фигня sm.gif у вас на порту B и D висит? Дисплей? Вот с ним сперва и разберитесь.
Напишите сперва програмульку, чтобы числа нормально показывал.
Потому модифицируйте ее, чтобы значения с АЦП показывало, а уж потом фильтрацией занимайтесь.

Если на портах B и D не дисплей, а ЦАП, когда дело хуже, но метода та же самая -
начинайте с вывода известных констант, пока не убедитесь, что они выводятся правильно. А потом пятитесь назад.

Впрочем, на и ЦАП MAX504 это совсем не похоже. Такой ЦАП десятичными цифрами не кормят.
У него, кажись, SPI-интерфейс, а там подход к передаче совсем другой.
VNS
Заданный вопрос интересен тем, что повторяется "стандартный" метод разработки - всё в памяти разработчика и компьютера...
Для начала должена быть разработана функциональная схема алгортма на бумаге или, точнее, как показано на примере во вложенном файле. Только так можно совместить технические возможности контроллера с требованиями программы. Причина состоит в ограниченных возможностях мозга человека. Не хочется выглядеть пессимистом, но в данном случае легче и быстрее всё начать сначала.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.