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

Настройка АЦП в ATMega32.

Добавлено: Сб сен 28, 2013 21:46:19
Pika4u
Всем привет. Делаю устройство на этом МК,столкнулся с проблемой при использовании АЦП. Режим-однократное преобразование,запуск-записью единицы в соответствующий бит соответствующего регистра,но все время шлет одно и тоже значение,причем не 255 или 0,а 69. В программе измерения накапливаются(5 раз) и выводится среднее арифметическое. 5 измерений в моей программе-где-то секунда. Если искусственно понизить напряжение(присоединить двигатель),то показания наоборот растут. Стоит делитель напряжения(5.6к на вывод питания и 1.5к на землю). МК отправляет данные по радиоканалу и компьютер сам считает напряжение,но я сделал вывод самого значения АЦП-оно не меняется почти никогда. Питание-аккумулятор 6 В,последние два бита в регистре ADC отбрасываются. Вот код,заранее спасибо:

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

 CB(DDR_ADC,PIN_ADC);
  ADMUX=(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3)|(0<<MUX4)|(0<<REFS0)|(0<<REFS1)|(0<<ADLAR)|(0<<ADATE);
  ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADIF)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);
  ADCSRA|=(1<<ADSC);

Re: Настройка АЦП в ATMega32.

Добавлено: Вс сен 29, 2013 18:10:37
Jack_A
Pika4u писал(а):

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


  ADMUX=(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3)|(0<<MUX4)|(0<<REFS0)|(0<<REFS1)|(0<<ADLAR)|(0<<ADATE);



И это весь код ? Надеюсь, ожидание окончания преобразования и приём результата имеется?
А чем приведённая конструкция лучше ADMUX=0 -- не понимаю. И вообще, если в данном бите 0, то при формировании константы его никуда двигать не надо, бо он нулём и так останется.

Re: Настройка АЦП в ATMega32.

Добавлено: Вс сен 29, 2013 19:53:27
Pika4u
Код не весь,результат считывается по прерыванию по окончанию,оно же включено.

Re: Настройка АЦП в ATMega32.

Добавлено: Пн сен 30, 2013 14:03:38
AaNnDdRrEeYy
для АЦП нужно опорное напряжение, так сказать линейка по которой мерить
задается битами REFS1 REFS0
у тебя нули а это значит Internal Vref turned off

Re: Настройка АЦП в ATMega32.

Добавлено: Пн сен 30, 2013 16:52:50
Pika4u
AaNnDdRrEeYy писал(а):для АЦП нужно опорное напряжение, так сказать линейка по которой мерить
задается битами REFS1 REFS0
у тебя нули а это значит Internal Vref turned off

Блин,а этот момент я пропустил,попробую сейчас...

Re: Настройка АЦП в ATMega32.

Добавлено: Пн сен 30, 2013 18:23:42
Pika4u
Еще интересней-когда стоит ЛЮБАЯ комбинация REFS1 и REFS0,то все равно одно и тоже значение! Даже,когда значение Reserved. Все равно та же цифра-69. И странно-с Мегой 8 все работало,пока не перешел на 32. AREF соединен с AVCC и VCC,вплотную к ногам висит конденсатор на землю 0.1 мкФ. Причем,что при внутреннем ИОН,что при ARED одно и тоже,вот что меня напрягает. Подключаю двигатель-показания иногда прыгают до 70 и все,опять 69 потом. Померил напряжение на выходе 7805-4.92 Вольта,совпадает с мультиметром,а на аккумуляторе по мультиметру 6.27,а показывает 6.41(

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 08:37:26
AaNnDdRrEeYy
вот еще что проверь:
бит ADATE у тебя 0 - это значит что преобразовывать постоянно не надо, только один раз.
потом установкой бита ADCSRA|=(1<<ADSC); ты запускаешь преобразование - установка этого бита запускает преобразование только 1 раз.
я не вижу полный код программы но если установка этого бита происходит только 1 раз при инициализации то АЦП не будет преобразовывать постоянно.

есть два варианта
1. заставить преобразовывать постояно ADATE в 1
2. в главном цикле устанавливать бит ADCSRA|=(1<<ADSC);

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

while(1)
{
   ADCSRA|=(1<<ADSC);
}


мне кажется первый луче.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 14:46:25
Pika4u
Вот полный код,касающийся работы АЦП. Преобразование запускается только в нужный момент.

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

unsigned short voltage_in=0,voltage=0;
unsigned char count_adc;//Количество отсчетов для АЦП
void adc_init()//Функция инициализации АЦП
{
  CB(DDR_ADC,PIN_ADC);
  ADMUX|=(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3)|(0<<MUX4)|(1<<REFS0)|(1<<REFS1)|(1<<ADLAR)|(0<<ADATE);
  SFIOR|=(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);
  ADCSRA|=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADIF)|(1<<ADPS2)|(0<<ADPS1)|(1<<ADPS0);
  ADCSRA|=(1<<ADSC);//Делаем первый отсчет
}
void Start_ADC_Convert()
{
  ADCSRA|=(1<<ADSC);
}

void ADC_Result()
{
  if(count_adc==5)//Если сделали 5 замеров напряжения
  {
    voltage_in=voltage;
    count_adc=0;//Обнуляем кол-во замеров
    voltage=0;//Обнуляем переменную для суммирования
  }

В главном файле:

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

#pragma vector =ADC_vect//Прерывание по завершению преобразования напряжения
__interrupt void ADC_vector(void)
{
  voltage+=ADCH;//Для большей точности накапливаем измерения
  count_adc++;//Сделано еще одно преобразование
}

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:02:35
__Alexander
Если опорное берется с AREF, то в REFS0 и REFS1 должны быть нули.

второе, где результат из ADCL?
и третье, вы накапливаете пять раз...

if(count_adc==5)//Если сделали 5 замеров напряжения
{
voltage_in=voltage;
count_adc=0;//Обнуляем кол-во замеров
voltage=0;//Обнуляем переменную для суммирования
}

а делить на пять потом кто будет?

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:03:33
AaNnDdRrEeYy
глупость конечно сморозю, но все же, переменную count_adc не надо volatile обозвать?
давай код из main() сюда, всякие там sei() смотреть будем

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:07:19
AaNnDdRrEeYy
__Alexander писал(а):Если опорное берется с AREF, то в REFS0 и REFS1 должны быть нули.


нет должно быть так REFS1 =0 REFS0=1

__Alexander писал(а):второе, где результат из ADCL?


у него ADLAR = 1, ADCL не нужен, его можно просто отбросить.

__Alexander писал(а):и третье, вы накапливаете пять раз...


if(count_adc==5)//Если сделали 5 замеров напряжения
{
voltage_in=voltage;
count_adc=0;//Обнуляем кол-во замеров
voltage=0;//Обнуляем переменную для суммирования
}

а делить на пять потом кто будет?


проблема в том что число в ADCH не меняется, даже если не делить то сумма то должна меняться, просто она будет в пять раз больше.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:16:47
Vov123
Всё-таки спрошу,я думал у товарища описка,но 2 раза это слишком,и как компилятор такое пропускает:
С какого перепугу в регистре ADMUX 9 бит?
И второе, это Вас Стиф Джобс научил так биты в ноль устанавливать?

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:21:32
AaNnDdRrEeYy
не существующий бит (0<<ADATE) в ADMUX он все равно в 0 устанавливает.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:24:46
Pika4u
Ой,извините,сейчас код поправлю. Насчет деления на 5-сумма отправляется другому устройству через радиоканал посредством nrf24l01,напряжение рассчитывается компьютером. И еще,я уже писал,что почему-то на REFS ему пофиг,при любых значениях(включая Reserved) значение не меняется. :( Переменные,используемые для АЦП,в программе больше нигде не используются.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:40:26
__Alexander
Что-то мне подсказывает, что сейчас ТС запутается окончательно.

AaNnDdRrEeYy писал(а):нет должно быть так REFS1 =0 REFS0=1

А давайте вы сейчас сделаете снимок страницы из документации, где вы вычитали этот бред.
__Alexander писал(а):второе, где результат из ADCL?

AaNnDdRrEeYy писал(а):у него ADLAR = 1, ADCL не нужен, его можно просто отбросить.

Конечно не нужен, т.к. число 1023 вполне умещается в один байт. )
Когда код не работет, такие отбросы не канают, надо для начала всё правильно настроить.
AaNnDdRrEeYy писал(а):проблема в том что число в ADCH не меняется, даже если не делить то сумма то должна меняться, просто она будет в пять раз больше.

число меняется, аж от нуля до трёх. только никому не говорите.
и даже если там пусто, то сумма из младшего разве не может переполнить переменную?
AaNnDdRrEeYy писал(а):не существующий бит (0<<ADATE) в ADMUX он все равно в 0 устанавливает.

мда. а откуда уверенность, что компилятор откинет именно этот бит? а я уверен что (0<<MUX0). Не?
Vov123 писал(а):С какого перепугу в регистре ADMUX 9 бит?

Ага. Только на меге8 работало )))))))
Pika4u писал(а): И еще,я уже писал,что почему-то на REFS ему пофиг

Ясно что пофиг, пытаясь записать 9 бит... настройки не проходят. У вас в каждой строчке ошибка, что вы хотели.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 15:49:35
Vov123
А вот это для чего?

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

CB(DDR_ADC,PIN_ADC);


Судя по настройкам ADMUX считывание производится с ADC0 c 40 ножки(корпус DIP) проца.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 16:10:20
Pika4u
Я переключаю ножку на вход,корпус у меня tqfp,вот

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

#define DDR_ADC DDRA
#define PIN_ADC 0

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 16:29:13
Pika4u
Сейчас поотправлял значения регистров-все биты ставятся,все нормально,но все равно-даже при работе от внутреннего ИОН все то же значение.....

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 16:33:23
__Alexander
Pika4u писал(а):Сейчас поотправлял значения регистров-все биты ставятся,все нормально,но все равно-даже при работе от внутреннего ИОН все то же значение.....


давай весь код.

Re: Настройка АЦП в ATMega32.

Добавлено: Вт окт 01, 2013 16:47:43
Pika4u
Вот,код в архиве.Некоторые комментарии могли устареть.