Attini13A АЦП на 2 канала...
Добавлено: Вт июн 20, 2017 18:36:07
В общем, понадобился мне простенький терморегулятор на 2 канала...
и решено было его сделать на Attiny13A. датчик NTC термистор на 10 килоом от ноги тиньки с АЦП на +5. от той же ноги тиньки резистор на 4,7 килоом на землю...
Код используется примерно такой (сильно не пинать, для контроллера пишу буквально второй раз в жизни)...
#define F_CPU 9600000UL // 9.6 MHz
#include <avr/io.h>
#include <util/delay.h>
int ohlajdatADC1PB1 = 0;
int ohlajdatADC3PB0 = 0;
int main(void)
{
DDRB = 0b00000011;
PORTB = 0b00000000;
ADCSRA=0b10000101; //разрешаем работу АЦП, (для 9,6 мегагерц лучше 0b10000110 т.е. на 64)
//но не включаем его,
//выставляем делитель на 32
while (1)
{
ADMUX=0b00000001; //назначаем ADC1 как вход АЦП
//и напряжение питания ATTiny13A
//для сравнения с нашим напряжением
ADCSRA |= 0b01000000; //включаем АЦП (старт одного преобразования АЦП)
while ((ADCSRA & (1 << ADIF)) == 0);//ждем окончания
//преобразования,
//только после этого
//идем дальше
if (ADCW > 510) //читаем датчик, если разогрелось выше порога...
{
ohlajdatADC1PB1 = 1; // ставим флаг необходимости охлаждения
PORTB |= _BV(PB1); // включаем вентилятор
_delay_ms(3000); // даем три секунды на разкрутку вентилятора
}
if (ADCW < 400) //если температура упала ниже порога выключения
{
if (ohlajdatADC1PB1 == 1) // а флаг охлаждения стоит
{
ohlajdatADC1PB1 = 0; // сбрасываем флаг охлаждения
PORTB &= ~_BV(PB1); // выключаем вентилятор
}
}
ADMUX=0b00000011; //назначаем ADC3 как вход АЦП
ADCSRA |= 0b01000000; //включаем АЦП (старт одного преобразования АЦП)
while ((ADCSRA & (1 << ADIF)) == 0);//ждем окончания
//преобразования,
//только после этого
//идем дальше
if (ADCW > 510) //читаем датчик, если разогрелось выше порога...
{
ohlajdatADC3PB0 = 1; // ставим флаг необходимости охлаждения
PORTB |= _BV(PB0); // включаем вентилятор
_delay_ms(3000); // даем три секунды на разкрутку вентилятора
}
if (ADCW < 400) //если температура упала ниже порога выключения
{
if (ohlajdatADC3PB0 == 1) // а флаг охлаждения стоит
{
ohlajdatADC3PB0 = 0; // сбрасываем флаг охлаждения
PORTB &= ~_BV(PB0); // выключаем вентилятор
}
}
}
}
Так вот, проблема в том, что данные от одного датчика попадают в другой канал... и наоборот.
т.е. я грею один термистор, у меня включается один вентилятор и следом за ним второй, хотя второй датчик я не грею... наоборот, если греть другой датчик, такая же фигня...
Собственно вопрос... что я делаю не так...?
И почему после смены канала АЦП и запуска нового преобразования ADCW возвращает данные со старого преобразования
ADCW = 0; перед новым преобразованием АЦП я пробовал, не помогает... все работает ровно так же как описано
и решено было его сделать на Attiny13A. датчик NTC термистор на 10 килоом от ноги тиньки с АЦП на +5. от той же ноги тиньки резистор на 4,7 килоом на землю...
Код используется примерно такой (сильно не пинать, для контроллера пишу буквально второй раз в жизни)...
#define F_CPU 9600000UL // 9.6 MHz
#include <avr/io.h>
#include <util/delay.h>
int ohlajdatADC1PB1 = 0;
int ohlajdatADC3PB0 = 0;
int main(void)
{
DDRB = 0b00000011;
PORTB = 0b00000000;
ADCSRA=0b10000101; //разрешаем работу АЦП, (для 9,6 мегагерц лучше 0b10000110 т.е. на 64)
//но не включаем его,
//выставляем делитель на 32
while (1)
{
ADMUX=0b00000001; //назначаем ADC1 как вход АЦП
//и напряжение питания ATTiny13A
//для сравнения с нашим напряжением
ADCSRA |= 0b01000000; //включаем АЦП (старт одного преобразования АЦП)
while ((ADCSRA & (1 << ADIF)) == 0);//ждем окончания
//преобразования,
//только после этого
//идем дальше
if (ADCW > 510) //читаем датчик, если разогрелось выше порога...
{
ohlajdatADC1PB1 = 1; // ставим флаг необходимости охлаждения
PORTB |= _BV(PB1); // включаем вентилятор
_delay_ms(3000); // даем три секунды на разкрутку вентилятора
}
if (ADCW < 400) //если температура упала ниже порога выключения
{
if (ohlajdatADC1PB1 == 1) // а флаг охлаждения стоит
{
ohlajdatADC1PB1 = 0; // сбрасываем флаг охлаждения
PORTB &= ~_BV(PB1); // выключаем вентилятор
}
}
ADMUX=0b00000011; //назначаем ADC3 как вход АЦП
ADCSRA |= 0b01000000; //включаем АЦП (старт одного преобразования АЦП)
while ((ADCSRA & (1 << ADIF)) == 0);//ждем окончания
//преобразования,
//только после этого
//идем дальше
if (ADCW > 510) //читаем датчик, если разогрелось выше порога...
{
ohlajdatADC3PB0 = 1; // ставим флаг необходимости охлаждения
PORTB |= _BV(PB0); // включаем вентилятор
_delay_ms(3000); // даем три секунды на разкрутку вентилятора
}
if (ADCW < 400) //если температура упала ниже порога выключения
{
if (ohlajdatADC3PB0 == 1) // а флаг охлаждения стоит
{
ohlajdatADC3PB0 = 0; // сбрасываем флаг охлаждения
PORTB &= ~_BV(PB0); // выключаем вентилятор
}
}
}
}
Так вот, проблема в том, что данные от одного датчика попадают в другой канал... и наоборот.
т.е. я грею один термистор, у меня включается один вентилятор и следом за ним второй, хотя второй датчик я не грею... наоборот, если греть другой датчик, такая же фигня...
Собственно вопрос... что я делаю не так...?
И почему после смены канала АЦП и запуска нового преобразования ADCW возвращает данные со старого преобразования
ADCW = 0; перед новым преобразованием АЦП я пробовал, не помогает... все работает ровно так же как описано