Опрос 6 каналов АЦП ATmega8
Добавлено: Чт апр 06, 2017 23:11:20
Здравствуйте!Есть проблема. Есть программа двух канального вольтметра с индикацией на WH1602, которая работает и моделируется в протеусе:
Однако, когда я пытаюсь опросить таким способом хотя бы 4 канала, возникают проблемы и протеус показывает пустой экран. Пробовал так:
И так:
Бесполезно. В чем может быть проблема?
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "lcd_lib.h"//библиотека для работы с дисплеем
#include <stdio.h>
unsigned int voltage[4], voltage_1, adc_counter;
volatile unsigned long voltage_value[4], voltage_value_1;
uint8_t res;
//Функция вывода переменной
void lcd_num_to_str(unsigned int value, unsigned char nDigit)
{
switch(nDigit)
{
case 4: lcd_dat((value/1000)+'0');
case 3: lcd_dat(((value/100)%10)+'0');
case 2: lcd_dat(((value/10)%10)+'0');
case 1: lcd_dat((value%10)+'0');
}
}
// Обработчик прерывания от АЦП
ISR(ADC_vect)
{
ADCSRA = 0; // Выключаем АЦП
if ((ADMUX & 0x0F)==1)
{
voltage_value = voltage_value + ADC; // Суммируем измеренные значения тока и помещаем в буфер
ADMUX = (ADMUX & 0xF0) | 0; // Выбираем канал ADC0
// Увеличиваем счетчик выборок АЦП на 1
}
else{
voltage_value_1 = voltage_value_1 + ADC; // Суммируем измеренные значения тока и помещаем в буфер
ADMUX = (ADMUX & 0xF0) | 1;
adc_counter++;
}
// Включаем АЦП
ADCSRA |= (1 << ADEN)|(1 << ADSC)|(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0)|(1 << ADIE)|(0<<REFS1)|(0<<REFS0);
}
int main(void)
{
ADMUX |= (0 << REFS1)|(0 << REFS0); // Внутренний ИОН 2,56V
ADMUX |= (1 << MUX0); // Подключаем канал ADC1
ADCSRA |= (1 << ADEN) // разрешение АЦП
|(1 << ADSC) |(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0) // предделитель на 128
|(1 << ADIE); // разрешение прерывания от АЦП
sei(); // Глобально разрешаем прерывания
lcd_init(); // Инициализация LCD
_delay_ms(25);
while(1)
{
// вычисляем среднее значение АЦП
if (adc_counter > 40)
{
ADCSRA = 0; // Выключаем АЦП
// преобразуем данные в реальное значение напряжения
voltage[0] = (voltage_value[0]/adc_counter)* 1.075;
voltage[1] = (voltage_value[1]/adc_counter)* 1.075;
voltage[2] = (voltage_value[2]/adc_counter)* 1.075;
voltage[3] = (voltage_value[3]/adc_counter)* 1.075;
adc_counter = 0; // Обнуляем счетчик выборок АЦП
voltage_value[0] = 0; // Обнуляем буфер значений напряжения
voltage_value[1] = 0; // Обнуляем буфер значений напряжения
voltage_value[2] = 0; // Обнуляем буфер значений напряжения
voltage_value[3] = 0; // Обнуляем буфер значений напряжения
lcd_gotoxy(0,1);
lcd_num_to_str(voltage[0]/100, 2);
lcd_string(".",1);
lcd_num_to_str(voltage[0], 2);
// Включаем АЦП
ADCSRA |= (1 << ADEN)|(1 << ADSC)|(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0)|(1 << ADIE)|(0<<REFS1)|(0<<REFS0) ;
}
_delay_ms(1);
}
}
Код: Выделить всё
switch (ADMUX & 0x0F)
{
case 0:voltage_value0+=ADC;break;
case 1:voltage_value1+=ADC;break;
case 2:voltage_value2+=ADC;break;
case 3:voltage_value3+=ADC;break;
}
ADMUX=(ADMUX & 0xF0)+((ADMUX & 0x0F)++ % 4);
Код: Выделить всё
voltage_value[ADMUX & 0x0F]+=ADC;
ADMUX=(ADMUX & 0xF0)+(((ADMUX & 0x0F)+1) % 4);