Перейти к содержанию

Atmega8 Ацп


kraftu

Рекомендуемые сообщения

Имеется Atmega8 на внешнем кварце 7,3728; По даташиту подключил АЦП с конденсатором и индуктивностью что бы подключить внешнее опорное напряжение на 5В;

Требовалось измерить напряжение в пределах 5-10В от аккумулятора соединил два резистора по 5кОм последовательно, и подключил к клеммам аккамулятора. Снимаю показания вольтметром и atmega. Показание не сходиться вообще, при разрядке аккумулятора atmega показывает, что потенциал возрастает на резисторе.

Код программы.

void ADC_init()
{
ADMUX = (1<<REFS0);
//ADMUX |= (0 << REFS1)|(0 << REFS0); // внешний ИОН
ADCSRA = 0x8D;
}
unsigned int ADC_result(unsigned char adc_input)
{
ADMUX=adc_input | (ADMUX & 0xF0);
//задержка для стабилизации входного напряжения
delay_us(10);
//начинаем преобразование (ADSC = 1)
ADCSRA |= 0x40;
while((ADCSRA & 0x10)==0); //ждем, пока АЦП закончит преобразование (ADIF = 0)
ADCSRA|=0x10;//устанавливаем ADIF
return ADCW;//ADCW - содержит ADCH и ADCL как нам нужно
}

Если измеряю батарейку 1,5В, то АЦП все правильно показывает. (Кажись..)

Вот что АЦП выдает при разрядке 1,5В батарейки.

1.807 1.812 1.812 1.812 1.816 1.816 1.807 1.816 1.807 1.807 1.821 1.812 1.812 1.812 1.821 1.816 1.816 1.816 1.816 1.816 1.816 1.831 1.826 1.821 1.816 1.821 1.831 1.831 1.831 1.821 1.821 1.831 1.836 1.836 1.836 1.826 1.836 1.836 1.836 1.836 1.826 1.826 1.831 1.826 1.826 1.826 1.831 1.841 1.831 

Почему показывает, что потенциал возрастает?

Что может быть? помогите пожалуйста.

post-168609-0-88580800-1362339807_thumb.png

Изменено пользователем kraftu
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

На входе должен стоять делитель 1/10, а результат нужно умножать на 10.

Да я понимаю, но напряжение измеренное вольтметром и АЦП не сходиться, вот в чем проблема.

Ссылка на комментарий
Поделиться на другие сайты

А кто такой ADCW????? В даташите его ни разу не видел.

void ADC_init()

{

ADMUX = (1<<REFS0);

//ADMUX |= (0 << REFS1)|(0 << REFS0); // внешний ИОН

ADCSRA = 0x8D;

}

unsigned int ADC_result(unsigned char adc_input)

{

ADMUX=adc_input | (ADMUX & 0xF0);

//задержка для стабилизации входного напряжения

delay_us(10);

//начинаем преобразование (ADSC = 1)

ADCSRA=ADCSRA|(1<<ADSC);

while(ADCSRA & (1<<ADSC));//ждем, пока АЦП закончит преобразование (ADIF = 0)

return ADC;//ADC - содержит ADCH и ADCL как нам нужно}

Изменено пользователем Rhime

- А совесть в курсе? - А совесть в доле! :-D

Эксперт — это человек, который совершил все возможные ошибки в некотором узком поле.

Все грамматические ошибки являются авторским стилем изложения материала.

Ссылка на комментарий
Поделиться на другие сайты

А кто такой ADCW????? В даташите его ни разу не видел.

void ADC_init()

{

ADMUX = (1<<REFS0);

//ADMUX |= (0 << REFS1)|(0 << REFS0); // внешний ИОН

ADCSRA = 0x8D;

}

unsigned int ADC_result(unsigned char adc_input)

{

ADMUX=adc_input | (ADMUX & 0xF0);

//задержка для стабилизации входного напряжения

delay_us(10);

//начинаем преобразование (ADSC = 1)

ADCSRA=ADCSRA|(1<<ADSC);

while(ADCSRA & (1<<ADSC));//ждем, пока АЦП закончит преобразование (ADIF = 0)

return ADC;//ADC - содержит ADCH и ADCL как нам нужно}

Не реклама.

http://samou4ka.net/page/analogo-cifrovoj-preobrazovatel-mk-atmega8

Ссылка на комментарий
Поделиться на другие сайты

Ну хорошо оставь строчку return ADCW.

- А совесть в курсе? - А совесть в доле! :-D

Эксперт — это человек, который совершил все возможные ошибки в некотором узком поле.

Все грамматические ошибки являются авторским стилем изложения материала.

Ссылка на комментарий
Поделиться на другие сайты

У самоучки тактовый генератор 4МГц, у тебя в 2раза быстрее, поэтому лучше ADCSRA = 0x8Е. Не понял необходимости ручной установки флага прерывания ADCSRA|=0x10;//устанавливаем ADIF И паузу перед началом преобразования увеличь для начала до 100uS (полезно для дифф. входа), потом уменьшишь по необходимости.

Ссылка на комментарий
Поделиться на другие сайты

Блин, я не знаю в чем дело, все перебрал варианты.

01_adc_noise.GIF

Все также сделал и еще AREF конденсатор поставил на 100nF, а если AVCC просто на прямую соединить с VCC, это только на точность повлияет?

Изменено пользователем kraftu
Ссылка на комментарий
Поделиться на другие сайты

Да... Вместо батарейки поставь переменник и подключи его к шинам Vref, ADC(на котором измеряешь), GND. Сделай несколько измерений с разными уровнями напряжения (меняя их переменником). Данные АЦП и мультиметра давай сюда, подумаем.

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

Вот что АЦП выдает
Почему показывает
Что значит "выдаёт" ? Куда показывает, кому ?

АЦП не может ни выдавать, ни показывать, тем более в таких числах, как Вы привели. АЦП преобразовывает аналоговый сигнал в цифровой, выраженный в неких условных единицах.

Вы на техническом форуме, в котором вопрос нужно задавать чётко, ясно и без всяких отсебяческих словечков, типа "Кажись", предоставляя максимум информации, включая необходимый код. Никто на кофейной гуще гадать не собирается, и выжимать информацию из Вас тоже.

Ссылка на комментарий
Поделиться на другие сайты

Попробуйте откалибровать АЦП по максимальному входному напряжению. То есть нужно узнать чем точнее, чему равен 1бит в вашем АЦП при установленных резисторах. То что плавает это нормально, для того чтоб не плавало и получить максимальную точность нужно активировать особый режим. В котором отключается вся периферия что то на подобие sleep режима на время преобразования. Я уже точно не помню как он называется.

Ссылка на комментарий
Поделиться на другие сайты

Все, проблема решена=) было дело в стабилизаторе, он почему то давал 4,2В вместе 5В, и было внешнее опорное напряжение на АЦП,стабилизатор заменил на новый, все отлично, всем спасибо=)

Ссылка на комментарий
Поделиться на другие сайты

  • 4 года спустя...
В 03.03.2013 в 21:01, kraftu сказал:

Господа, возникла потребность, поэтому, дабы не создавать новую тему, поднимаю эту и имею вопрос по статье с данной ссылки. Даже несколько вопросов, а именно:

1. Если я хочу испльзовать в качестве источника опрного напряжения внутренний источник, то в какой части кода мне упоминать про биты REFS1:REFS0? А также следует упоминать и REFS1, и REFS0 или же оба?

2. Интереса ради: если я хочу задействовать два канала ADC, то, опять же, мне нужно указывать биты MUX3, MUX2, MUX1 или MUX0? И какому из них присваивать значения 0000 и 0001? И, если два канла АЦП будут опрашиваться последовательно, то для одного из них будет получаться величина unsigned int ADC_result(unsigned char adc_input), а для второго, например,unsigned int ADC_result1(unsigned char adc_input) или опять же unsigned int ADC_result(unsigned char adc_input)?

3. Бит ADEN, разрешающий АЦП, почему-то вообще ни в одном коде вольтметров на Atmega8 мной не встречался. Зачем его тогда упоминают, если его не используют?

4. Тактовая частота АЦП и биты ADPS2:ADPS0. Т.к. меня интересует максимальная точность измерения, а скорость является второстепенным фактором, то, согласно статье, "для достижения полной 10-битной точности рекомендуется использовать частоты ниже 200кГц". Следовательно, "Частота нашего МК равна 4,096Мгц. Мы хотим выбрать частоту АЦП меньше 200кГц. Этому соответствует СК/32 = 128кГц (ADPS2:ADPS0 - 101)" - в какой части кода указывается этот бит? И, опять, же. который именно? ADPS2, ADPS1 или ADPS0?

Ссылка на комментарий
Поделиться на другие сайты

//функция инициализации
void ADC_init()
{
//воспользуемся значениями регистров, определенными ранее
         ADMUX = 0x00;
         ADCSRA = 0x8D;
}

Наглядный пример как делать НЕ НАДО.

1 час назад, oner сказал:

1. в какой части кода мне упоминать про биты REFS1:REFS0? А также следует упоминать и REFS1, и REFS0 или же оба?

Эти биты управляют опорным напряжением. Когда хотите его изменить тогда и биты меняйте. Если все каналы будут измеряться относительно одного ИОНа, можно в инициализации, а если для каждого индивидуально - перед измерением. Работают эти биты только в паре, сам по себе бит REFS1 не значит ничего.

1 час назад, oner сказал:

2. Интереса ради: если я хочу задействовать два канала ADC, то, опять же, мне нужно указывать биты MUX3, MUX2, MUX1 или MUX0? И какому из них присваивать значения 0000 и 0001?

Биты MUX3, MUX2, MUX1, MUX0 по отдельности тоже не работают, только все вместе. Как вы собираетесь присваивать БИТУ значения 0000 и 0001 по 4 бита каждое (хотя в такой записи это восмеричные числа размером по 9 бит, но спишем на то что это не число в последовательность битов). Кстати, рекомендую погуглить о записях чисел с разными основаниями - двоичные, восьмеричные, шестнадцатеричные, десятичные - и чем они отличаются.

Наводящий вопрос: за что отвечает переменная-аргумент adc_input функции ADC_result?

Надеюсь, хотя бы Си вы знаете...

1 час назад, oner сказал:

3. Бит ADEN, разрешающий АЦП, почему-то вообще ни в одном коде вольтметров на Atmega8 мной не встречался. Зачем его тогда упоминают, если его не используют?

В "коде" по ссылке этот бит выставляется. Если бы автор писал по нормальному, это было бы видно. На самом деле его версия инициализации АЦП должна выглядеть примерно так:

void ADC_init(){
  ADMUX = (0b00 <<  REFS0 | 0 << ADLAR); //внешний ИОН на выводе Aref... нафига?! Лучше выставить REFS в 0b01 для использования AVCC или 0b11 для внутреннего ИОН, равного 2.26 В для ATmega8
  ADCSRA = (1<<ADE | 1<<ADIE | 0b101<<ADPS0); // F_ADC = F_CPU/32 = 128 кГц ~ 9800 измерений в секунду
//зачем разрешено прерывание неизвестно, учитывая что работа с АЦП у того "автора" идет через функцию
}

С точки зрения компилятора и контроллера этот код идентичен приведенному по ссылке. Но в отличие от того, тут сразу видно что и как настраивается. Еще лучше было бы заменить настройки REFS и ADPS на именованные константы, но именно для настроек периферии это не обязательно.

2 часа назад, oner сказал:

4. Тактовая частота АЦП и биты ADPS2:ADPS0. Т.к. меня интересует максимальная точность измерения, а скорость является второстепенным фактором, то, согласно статье, "для достижения полной 10-битной точности рекомендуется использовать частоты ниже 200кГц". Следовательно, "Частота нашего МК равна 4,096Мгц. Мы хотим выбрать частоту АЦП меньше 200кГц. Этому соответствует СК/32 = 128кГц (ADPS2:ADPS0 - 101)" - в какой части кода указывается этот бит? И, опять, же. который именно? ADPS2, ADPS1 или ADPS0?

Главный источник информации не статья (тем более _такая_) в даташиты или, если с английским совсем туго, Евстифеев. Впрочем, он не только перевел но и здорово структурировал информацию из даташитов, так что книга в любом случае полезная. А согласно даташиту, для максимальной точности АЦП, частота его тактирования должна быть не только меньше 200 кГц, но и не меньше 50 кГц. Это указывается всеми тремя битами ADPS (см. мой перевод того кода на нормальный язык).

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

12 часа назад, COKPOWEHEU сказал:

В "коде" по ссылке этот бит выставляется. Если бы автор писал по нормальному, это было бы видно. На самом деле его версия инициализации АЦП должна выглядеть примерно так:


void ADC_init(){
  ADMUX = (0b00 <<  REFS0 | 0 << ADLAR); //внешний ИОН на выводе Aref... нафига?! Лучше выставить REFS в 0b01 для использования AVCC или 0b11 для внутреннего ИОН, равного 2.26 В для ATmega8
  ADCSRA = (1<<ADE | 1<<ADIE | 0b101<<ADPS0); // F_ADC = F_CPU/32 = 128 кГц ~ 9800 измерений в секунду
//зачем разрешено прерывание неизвестно, учитывая что работа с АЦП у того "автора" идет через функцию
}

Спасибо. Правильно ли я понимаю, что, если мне нужно инициализировать два АЦП с ИОН 2,26В от внутреннего источника, то код будет таким:

void ADC_init(){
  ADMUX = (0b11 <<  REFS0 | 0 << ADLAR); //внутренний ИОН, равный 2.26 В для ATmega8
  ADCSRA = (1<<ADE | 1<<ADIE | 0b101<<ADPS0); // F_ADC = F_CPU/32 = 128 кГц ~ 9800 измерений в секунду
//зачем разрешено прерывание неизвестно, учитывая что работа с АЦП у того "автора" идет через функцию
}

А как запустить одновременную работу двух АЦП?

И  как присваивать значения результатам работы этих двух АЦП? Ведь тогда переменных, по идее, должно быть две. Из них одна - это unsigned int ADC_result(unsigned char adc_input), но ведь и вторая будет такая? Или как в этих переменных учесть то, с каким АЦП они связаны?

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, oner сказал:

А как запустить одновременную работу двух АЦП?

 в МК один АЦП , так что два АЦП вы никак не сможете запустить одновременно , так как нет второго . Есть несколько входов , которые вы можете подключать к АЦП - по очереди

Изменено пользователем DmitryS
Ссылка на комментарий
Поделиться на другие сайты

1 час назад, DmitryS сказал:

 в МК один АЦП , так что два АЦП вы никак не сможете запустить одновременно , так как нет второго . Есть несколько входов , которые вы можете подключать к АЦП - по очереди

Я это и имел в виду.

Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, oner сказал:

Спасибо. Правильно ли я понимаю, что, если мне нужно инициализировать два АЦП с ИОН 2,26В от внутреннего источника, то код будет таким:

Да. Только надо все-таки разобраться с инициализацией а не бездумно повторять чужой код. Например, пересмотреть комментарии и бит ADIE - точно ли это нужно?

3 часа назад, oner сказал:

А как запустить одновременную работу двух АЦП?

И  как присваивать значения результатам работы этих двух АЦП? Ведь тогда переменных, по идее, должно быть две. Из них одна - это unsigned int ADC_result(unsigned char adc_input), но ведь и вторая будет такая? Или как в этих переменных учесть то, с каким АЦП они связаны?

Одновременную работу двух АЦП вы не запустите - в контроллере он физически один. Разве что переключать каналы по очереди.

Ответьте все-таки за что отвечает переменная-аргумент adc_input функции ADC_result()?

Вы вообще понимаете как работает эта функция?

Вы понимаете как работают функции в Си?

По вопросам об АЦП складывается впечатление что не знаете. Если так и есть - почитайте Кернигана и Ричи "Язык Си" для начала. Без знания языка (более высокоуровневые чем Ассемблер лучше осваивать не на контроллере а не компьютере, это проще) и представления о работе контроллера (тут лучше всего учить Ассемблер для контроллера) много не сделаете.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

58 минут назад, COKPOWEHEU сказал:

Ответьте все-таки за что отвечает переменная-аргумент adc_input функции ADC_result()?

Вы вообще понимаете как работает эта функция?

Если бы я понимал, то, очевидно, меня бы не было на этом форуме и мне было бы крайне странным задавать подобные вопросы.

Изменено пользователем oner
Ссылка на комментарий
Поделиться на другие сайты

Про это я уже писал. Берете даташит или Евстифеева и разбираете какой регистр за что отвечает, как именно автор функции пытается считать АЦП, какие параметры за что отвечают.

Форум предназначен чтобы помогать в сложных моментах, когда спрашивающий уже пытался разобраться, когда он хочет научиться. А отвечать на вопросы, подробно рассмотренные в десятке мест быстро надоедает. Кроме того, "форум по электронике" - не то место где должны обучать основам программирования.

1 минуту назад, Alex сказал:

@oner , почитайте про функции, передачи в них значений через аргументы, возвращение значений (в данном случае - не актуально, но для общего развития - обязательно).

Как раз в данном случае актуально. Человек не понимает что функция принимает и что возвращает. И, такое ощущение, что не понимает отличия фнкции от переменной. А без этого помочь почти невозможно - проще сделать за него.

 

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Цитата

Я, кажется, непонятно выражаюсь.


Да всё понятно Вы выражаетесь.

Почитайте, хотябы, комментарий к функции ADC_result В нём всё предельно ясно написано..

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...