Страница 1 из 1

АЦП на attiny13

Добавлено: Пт окт 27, 2023 10:26:02
Lww
Здравствуйте, уважаемые форумчане.
Уже 2 дня бьюсь над проблемой, почему не работает правильно код на attiny13.
Суть в том, что тини берет значение напряжения с 3 входов ADC0, ADC1 и ADC2, преобразует их в ацп и в зависимости от того, какое наибольшее, включает соответствующий выход PB0, PB1 или PB3, а остальные выключает.
1) В прерывании ацп (каждые ~10 мкс) происходит запись в переменную и переключение пина ацп, т.е. ADMUX++, а так же запуск нового преобразования.
2) По прерыванию таймера Т0 с предделителем 1024 (около 27мс) происходит сравнивание значений с ацп, выключение всех выходов и включение соответствующего наибольшему напряжению с ацп, после чего все значения с ацп обнуляются и оно заново набирает их.
Беда в том, что оно то работает, то не работает. На скрине например на ADC0 4.6в, самое большое из 3, но почему-то работает выход PB3, а должен PB0. Но если подергать туда-сюда, то начинает работать. Потом опять клинит.
Живая микросхема работает так же, как в симуляторе. Значит ошибка где-то в коде.
Никак не могу найти ошибку, проблема еще в том, что нет толкового отладчика, atmel studio не поддерживает usbasp.
Вот код:
Спойлер

Код: Выделить всё

#include <avr/io.h>
#include <avr/interrupt.h>  //Для доступа к функции sei()
#include <avr/signal.h>     //Для доступа к макросу INTERRUPT

volatile uint8_t adcVal[3] = {0, 0, 0};
volatile uint8_t max = 0;
volatile uint8_t max1 = 0;

ISR(ADC_vect)
{
	uint8_t a = ADCH;
	if (a > adcVal[ADMUX - 32])						//если значение с ацп больше записанного, то записываем это значение 
	{
		adcVal[ADMUX - 32] = a;						
	}
	 
	if (ADMUX < 34)									//переключаем пин ацп на следующий
	{
		ADMUX++;
	} else 
	{
		ADMUX = 32;
	}	
	ADCSRA = ADCSRA | 0x40; //Устанавливаем разряд ADSC в регистре ADCSR, чтобы начать новое преобразование
}

ISR(TIM0_OVF_vect)
{	

	max = 0;
	if (adcVal[1]>adcVal[0]) max = 1;
	if (adcVal[2]>adcVal[1]) max = 2;				//Находим наибольшее напряжение
	
	if (max == max1)								//если наиб. напряжение=предыдущему периоду, то устанавливаем выход
	{		
		switch (max)
		{
			case 0:
			PORTB = 1;
			break;
			case 1: 
			PORTB = 2;
			break;
			case 2:
			PORTB = 8;
			break;
		}
	} else                                        //иначе отключаем все выходы
	{
		max1 = max;
		PORTB = 0;		
	}
	adcVal[0] = 0;									//обнуляем ацп каждый период
	adcVal[1] = 0;
	adcVal[2] = 0;

}

int main(void)
{		
	TIMSK0 = 2;
	TCCR0A = 0;
	TCCR0B = 0b00000101;
	ADMUX = 32;
	ADCSRA = 0b11001000;
	DDRB = 0b00001011;
	sei();
    /* Replace with your application code */
    while (1) 
    {		
    }
}
Изображение
Фьюзы:
CLKDIV8: 1
RSTDISBL: 0
CKSEL: 10
SUT: 10

Re: АЦП на attiny13

Добавлено: Пт окт 27, 2023 12:42:54
Ivanoff-iv
а нужны ли такие сложности? с массивами..
нужны 3 переменные: одна для хранения значения, вторая для хранения номера, ну, и номер текущего опрашиваемого входа.
пробегаем входы с 0 по 2 (ADMUX=in+ADC_VREF_TYPE)
в прерывании сравнивам ADCW (или его часть) с хранимым значением, если ADCW больше - обновляем переменные значения и номера входа.
когда все входы опрошены, по данным из номера конфигурируем выходы, затем обнуляем переменную значения (переменная номера сама обновится в следующем цикле)

Re: АЦП на attiny13

Добавлено: Пт окт 27, 2023 13:09:56
Lww
Не, без массива никак. Ведь по переполнению таймера должны сравниваться сразу все 3 значения.
Ацп опрашивается тысячи раз в секунду. А таймер только 36 раз в секунду.

Re: АЦП на attiny13

Добавлено: Пт окт 27, 2023 15:12:26
>TEHb<
У них УВХ одно на всех. Надо или холостую выборку канала делать, а потом измерение, либо резко уменьшать выходное сопротивление измерительной цепи, либо увеличивать время выборки. Но не факт, что причина в этом.

Re: АЦП на attiny13

Добавлено: Сб окт 28, 2023 08:19:18
veso74

Код: Выделить всё

if ((adcVal[0] > adcVal[1]) & (adcVal[0] > adcVal[2]))
    max = 0;
  else if (adcVal[2] > adcVal[1])
    max = 2;
  else max = 1;
Изображение

Re: АЦП на attiny13

Добавлено: Сб окт 28, 2023 13:51:14
metan
veso74 писал(а):&
&& :)

Re: АЦП на attiny13

Добавлено: Сб окт 28, 2023 15:09:31
veso74
[uquote="metan",url="/forum/viewtopic.php?p=4494874#p4494874"]... &&[/uquote]
Да, правильно. Спс. Утром рано, еще спим :P ...
А и с Bitwise AND работало на симуляцией ...

Re: АЦП на attiny13

Добавлено: Сб окт 28, 2023 15:19:51
OKF
А в данном случае неважно что побитовое И, что логическое. Просто как то неаккуратненько.)

Re: АЦП на attiny13

Добавлено: Сб окт 28, 2023 19:19:09
BOB51
"пузырьки" с тремя (и более) значениями
:roll: