три вольтметра на одной меге16

Обсуждаем контроллеры компании Atmel.
Ответить
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

ARV писал(а):что за кошмарный код?! ну хоть примерно как-то так надо:
как-то так...
Только работать оно не будет. Всякий раз будет читаться предыдущий канал.
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

ARV писал(а): далее, что за ужасные вычисления у вас?
если вы внимательно посмотрите, то float все закоментированы, это были начальные разработки, для наглядности, а потом я переписал под умножение, вычисления кошмарные, потому что напряжение идёт не с делителя, а с операционного уселителя, который в свою очередь тоже по хитрому подключён, вообщем вычисления станут позже ещё кошмарнее, с использованием интерполяции, и тем не менее это как раз работает, а не работает обычный делитель напряжения (это где 15/8), вернее работает, но до переключения
Реклама
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

Вы учли это?
In Free Running mode, always select the channel before starting the first conversion. The channel
selection may be changed one ADC clock cycle after writing one to ADSC. However, the
simplest method is to wait for the first conversion to complete, and then change the channel
selection. Since the next conversion has already started automatically, the next result will reflect
the previous channel selection. Subsequent conversions will reflect the new channel selection.
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

ещё кошмарнее, с использованием интерполяции
Не тратьте силы, возьмите молоток побольше!
По таблице(ам)...
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

vdavid писал(а):Вы учли это?
столько много буржуйских буковок... как я понял смысл сводиться к тому что первое преобразование не точное, я пробовал сделать задержку, вернее пропуск нескольких итераций, та же фигня один вольтметр считает правильно, другой нет
Реклама
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

kelod писал(а): столько много буржуйских буковок...
Смысл сводится к тому, что смену канала нужно делать по окончании преобразования, например в прерывании. Но следует понимать, что фактически канал переключится только на следующем преобразовании.
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

я пробовал после изменения канала ставить счётчик, что бы измерения были не сразу,в течении нескольких итераций цикла,нечего не изменилось, откуда то берётся дополнительное напряжение или дополнительные тики ацп
видите при запуске некоторое время напряжение 12,00, а потом неожиданно становиться 14.41

я может быть ошибаюсь, но мне кажется что контроллер не переключается обратно на нулевую ножку, а так и остаётся на 1
Вложения
16_3_1.rar
(34.65 КБ) 143 скачивания
GccApplication2.hex
(30.61 КБ) 286 скачиваний
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

kelod писал(а):я пробовал после изменения канала ставить счётчик
Для начала уберите free running mode и переключайте каналы при нулевом состоянии бита ADEN. Преобразование всякий раз запускайте вручную.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18786
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

мой код будет отлично работать, в строгом соответствии с даташитом. удачи всем неверующим!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

нефига он у вас не работает
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

kelod, может он не работает именно у Вас ? Вам не приходило это в голову ? :)
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

vdavid писал(а): Для начала уберите free running mode и переключайте каналы при нулевом состоянии бита ADEN. Преобразование всякий раз запускайте вручную.
сделал так:

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

ADCSRA |= (1 << ADEN) // разрешение АЦП
	//|(1 << ADSC) // запуск преобразования
	//|(1 << ADATE) // непрерывный режим работы АЦП	//|(1 << ADFR) // непрерывный режим работы АЦП
	|(1 << ADPS2)|(1 << ADPS1)|(0<< ADPS0) // предделитель на 64 (частота АЦП 125kHz)
	|(1 << ADIE); // разрешение прерывания
	
	ADMUX |= (1 << REFS1)|(1 << REFS0); // внутренний ИОН 2,56V
	//|(0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
	
	unsigned char buffer[6];	
	unsigned char buffer1[1];
	
	unsigned int fq_tek;

flag_volt=1;

int koy=2,
rma=83,
pgr=31;

	while(1)
	{	
		switch(flag_volt)
		{
			case 0:
			{
				//akk1=0;
				break;
			}
			case 1:
			{
				ADCSRA |= (0 << ADEN);
				ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
				ADCSRA |= (1 << ADEN);
			
				ADCSRA |= (1 << ADSC);
				
				akk1=akk*15*pow(8,-1);

				flag_volt=2;
				break;
			}
			case 2:
			{
				ADCSRA |= (0 << ADEN);
				ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(1 << MUX0); // вход ADC0
				ADCSRA |= (1 << ADEN);
				
				ADCSRA |= (1 << ADSC);
			
			temp1=( rma*( (1200*pow(100,-1))-((temp1*koy)*pow((4*100),-1) - (pgr*pow(1000,-1))) )/ (((temp1*koy)*pow((4*100),-1))- (pgr*pow(1000,-1))) );
				
				flag_volt=1;
				break;
			}
			case 3:
			{
				
				temp2=akk;
				
				flag_volt=1;
				
				break;
			}
		}
и прерывание по окончанию

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

ISR (ADC_vect)
{
	akk = ADC;
}
всё равно не работает при использовании больше чем 1 канал

Alex, может и только у меня, а как починить?
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

Надеюсь akk объявлена как volatile?
Ну и ожидать окончания преобразования тоже нужно. Вот так должно заработать:

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

volatile char ADCReady;  //*
volatile int akk;               //*

ADCSRA |= (1 << ADEN) // разрешение АЦП
   //|(1 << ADSC) // запуск преобразования
   //|(1 << ADATE) // непрерывный режим работы АЦП   //|(1 << ADFR) // непрерывный режим работы АЦП
   |(1 << ADPS2)|(1 << ADPS1)|(0<< ADPS0) // предделитель на 64 (частота АЦП 125kHz)
   |(1 << ADIE); // разрешение прерывания
   
   ADMUX |= (1 << REFS1)|(1 << REFS0); // внутренний ИОН 2,56V
   //|(0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
   
   unsigned char buffer[6];   
   unsigned char buffer1[1];
   
   unsigned int fq_tek;

flag_volt=1;

int koy=2,
rma=83,
pgr=31;

   while(1)
   {   
      switch(flag_volt)
      {
         case 0:
         {
            //akk1=0;
            break;
         }
         case 1:
         {
            ADCSRA |= (0 << ADEN);
            ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
            ADCSRA |= (1 << ADEN);
         
            ADCSRA |= (1 << ADSC);
            
            ADCReady=0;           //*
            while(!ADCReady);    //*

            akk1=akk*15*pow(8,-1);

            flag_volt=2;
            break;
         }
         case 2:
         {
            ADCSRA |= (0 << ADEN);
            ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(1 << MUX0); // вход ADC0
            ADCSRA |= (1 << ADEN);
            
            ADCSRA |= (1 << ADSC);

            ADCReady=0;           //*
            while(!ADCReady);    //*
         
         temp1=( rma*( (1200*pow(100,-1))-((temp1*koy)*pow((4*100),-1) - (pgr*pow(1000,-1))) )/ (((temp1*koy)*pow((4*100),-1))- (pgr*pow(1000,-1))) );
            
            flag_volt=1;
            break;
         }
         case 3:
         {
            
            temp2=akk;
            
            flag_volt=1;
            
            break;
         }
      }

и прерывание по окончанию
Код:
ISR (ADC_vect)
{
  ADCReady=1; //* 
  akk = ADC;
}
Все, что добавил пометил комментарием //*
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

del
Последний раз редактировалось vdavid Пн сен 29, 2014 14:35:59, всего редактировалось 1 раз.
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

к сожалению не работает :cry: , причём если с двумя ножками вторая показывает адекватное значение, первая нет, то с тремя получается что то ужасное, причём если запускать по шагам, то первое измерение более менее нормальное, а на втором круге вылетает вся эта котовасия...
Вложения
GccApplication2.hex
(31.07 КБ) 288 скачиваний
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

kelod писал(а):к сожалению не работает :cry: , причём если с двумя ножками вторая показывает адекватное значение, первая нет, то с тремя получается что то ужасное, причём если запускать по шагам, то первое измерение более менее нормальное, а на втором круге вылетает вся эта котовасия...
Так под третью вообще код не написан фактически. И зачем нам hex. Выкладывайте .c. У Вас это все в симуляторе или в железе?
И зачем нужен pow(8,-1)? Просто разделить на 8 религия не позволяет?
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

Что вижу я: зачем прерывание? вы все равно ждете его срабатывания

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

while(!ADCReady);
ждите флаг от АЦП ADIF. Выкиньте непрерывное преобразование, используйте одиночное и будет вам счастье. Дальше строки:

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

ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0);
ADMUX |= (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(1 << MUX0);
Вы знаете что такое логические операции? В таком случае переключение с 1-го на 0-й канал происходить не будет. Почитайте про логическое или. Сбрасывайте биты так:

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

ADMUX &=~ (1 << MUX3)|(1 << MUX2)|(1 << MUX1)|(1 << MUX0);
дальше устанавливайте нужный канал.
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

eess9 писал(а):зачем прерывание? в
Ну, в дальнейшем вместо while(!ADCReady); можно будет написать while(!ADCReady) sleep_cpu(); для уменьшения шумов.
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

Тогда после цикла switch лучше. Установили канал, обработали данные и уснули. По прерыванию проснулись, пошли на новый виток цикла while и снова попали в switch. Просто лучше вызвать сон раз в одном месте, предварительно убедившись, что сделано абсолютно все, чем тыкать команды сна где придется.
Мучитель микросхем
Сообщения: 410
Зарегистрирован: Чт ноя 13, 2008 16:33:42

Сообщение vdavid »

eess9, Конечно Вы правы. Еще лучше все это оформить в виде функции, как советовал ARV.
Ответить

Вернуться в «AVR»