ILYAUL писал(а):- ОшибкаКод: Выделить всё
ADCSRA |= 0x40;
Что пишет?
Хидеры "avr/io.h", "avr/iom8.h" и соответствующие им библиотеки присутствуют и целые?
ILYAUL писал(а):- ОшибкаКод: Выделить всё
ADCSRA |= 0x40;
Angmar писал(а):ILYAUL писал(а):- ОшибкаКод: Выделить всё
ADCSRA |= 0x40;
Что пишет?
Хидеры "avr/io.h", "avr/iom8.h" и соответствующие им библиотеки присутствуют и целые?
ibiza11 писал(а)::shock: скоро начнут просить исходник "как сложить два числа"
Код: Выделить всё
void adc_init(void){
ADMUX = 0; // опора Vref, ADLAR = 0, канал = 0
ADCSRA |= (1<<ADEN)|(1<<ADFR)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //вкл АЦП, Free Runnig Mode, предделитель 128
}
unsigned short get_adc_result(void){
while(!(ADCSRA & (1<<ADIF))); // ожидание преобразования
ADCSRA |= (1<<ADIF); // сброс флага
return (unsigned short)(ADCH<<8)|(ADCL);
}
void main(void){
adc_init();
unsigned short ADCResult, ADCSumm = 0;
unsigned char i = 0;
while(1){
while(i<30){
ADCSum += get_adc_result();
i++;
}
ADCSum /= 30;
/* вот здесь надо забирать результат интегирования */
i = 0;
ADCSum = 0;
}
}
Код: Выделить всё
interrupt [ADC_INT] void adc_isr(void)
{
float cont;
if (schet==12500) //считывние около 5 раз в секунду
{cont=(float)ADCW;
SIG[a]=65010-(int)(cont*0,1221); //Чтение результата АЦП преобразования, 0,1221 - уравнивающий коэффициент
if (SIG[a]>63046) SIG[a]=63046; //ограничение длительности сигнала
if (a==4){a=0;
schet=0;} //Проверяем значение счётчика
else a++;
ADMUX=a; //Готовимся считывать сигнал с другого канала
delay_us(10); //Выдержка времени для стабилизации входного напряжения
ADCSRA|=0x40; //Старт АЦП преобразования
}
else schet++;
PortB=(~PortB)&0b00000001;//Ирвертирование PB0 для проверки работы прерыванния
}
То есть повторное преобразование запускаете только если schet строго равен 12500, при всех остальных значениях АЦП остановлен, не выполняет преобразований и не генерирует прерываний. Интересно, почему же они не возникают.shadivl писал(а):Похоже, по какой-то причине прерывание не срабатывает.Код: Выделить всё
interrupt [ADC_INT] void adc_isr(void)
{
float cont;
if (schet==12500) //считывние около 5 раз в секунду
{
ADCSRA|=0x40; //Старт АЦП преобразования
}
else schet++;
PortB=(~PortB)&0b00000001;//Ирвертирование PB0 для проверки работы прерыванния
}
Код: Выделить всё
if (schet==12500) //считывние около 5 раз в секунду
{cont=(float)ADCW;
SIG[a]=65010-(int)(cont*0,1221); //Чтение результата АЦП преобразования, 0,1221 - уравнивающий коэффициент
if (SIG[a]>63046) SIG[a]=63046; //ограничение длительности сигнала
if (a==4){a=0;
schet=0;} //Проверяем значение счётчика
else a++;
ADMUX=a; //Готовимся считывать сигнал с другого канала
delay_us(10); //Выдержка времени для стабилизации входного напряжения
}
else schet++;
PORTB=(~PORTB)&0b00000001;
ADCSRA|=0x40; //Старт АЦП преобразованияКод: Выделить всё
cont=(float)ADCW;
SIG[a]=65010-(int)(cont*0,1221); //Чтение результата АЦП преобразования, 0,1221 - уравнивающий коэффициент
if (SIG[a]>63046) SIG[a]=63046; //ограничение длительности сигнала
if (a==4) a=0; //Проверяем значение счётчика
else a++;
ADMUX=a; //Готовимся считывать сигнал с другого канала
delay_us(10); //Выдержка времени для стабилизации входного напряжения
PORTB=(~PORTB)&0b00000001;
ADCSRA|=0x40; //Старт АЦП преобразованияПлохая идея использовать магические числа.ADCSRA|=0x40; //Старт АЦП преобразования
Это зачем? Тем более что очевидные вещи прокомментированы а физический смысл этой константы и допустимые значения - нет.(ADC_VREF_TYPE & 0xff)
Задержки в прерывании - плохая идея.delay_us(10); //Выдержка времени для стабилизации входного напряжения
резервировать регистр только для прерывания? Учитывая использование задержки - скорость не требуется, а тогда зачем?register static unsigned char input_index=0;
А чего указали последний канал вместо количества? Остальные записи были бы проще. Другое дело что в общем случае между используемыми аналоговыми каналами могут быть цифровые.unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];
А если в середине присвоения возникнет прерывание АЦП и изменит значение массива?ch_1= adc_data[0]; //Запись в переменную ch_1 результата ADC 1-го канала
ch_2= adc_data[1]; //Запись в переменную ch_2 результата ADC 2-го канала
Про магические числа я уже писал.ADCSRA=0xCB;
В чем конкретно проблема? Не можете вычислить разность? Не можете вывести знаковое число на дисплей?пытаюсь добавить вывод на LCD разницу значений (adc_data[0]- adc_data[1])