Уже 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