Jump to content
Sign in to follow this  
Discovery 66

2 И Более Канала Ацп Как Опросить Их (Атмега8)

Recommended Posts

Как опросить 2 канала ацп котроллера, пример кода для одного канала АЦП как второй канал задействовать, третий и т.п. ? помогите кто чем может, давно уже ищю всю както не конкретно и не понятно, в гугль не отсылать был я там

// Использование АЦП. Цифровой вольтметр
02.
03.#include <avr/io.h>
04.#include <avr/interrupt.h>
05.#include <util/delay.h>
06.
07.//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp
08.char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};
09.
10.volatile unsigned char segcounter = 0;
11.volatile int display = 0;
12.
13.// Прерывание по переполнению T2, динамическая индикация
14.ISR (TIMER2_OVF_vect)
15.{	
16.PORTD = 0xFF;
17.PORTB = (1 << segcounter);
18.
19.switch (segcounter)
20.{	
21.case 0:
22.PORTD = ~(SEGMENTE[display % 10000 / 1000]);
23.break;
24.case 1:
25.PORTD = ~((SEGMENTE[display % 1000 / 100])|0x80); // добавляем десятичную точку
26.break;	
27.case 2:
28.PORTD = ~(SEGMENTE[display % 100 / 10]);
29.break;		
30.}
31.if ((segcounter++) > 2) segcounter = 0;	
32.}
33.
34.volatile unsigned long value;
35.volatile unsigned int adc_counter;
36.
37.// Прерывание по окончанию преобразования АЦП
38.ISR (ADC_vect)
39.{
40.value = value + (ADC*11/4);
41.adc_counter++;
42.}
43.
44.// Главная функция
45.int main (void)
46.{
47.DDRD = 0xFF;
48.DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);
49.PORTD = 0x00;
50.PORTB = 0x00;
51.DDRC = 0x00;
52.
53.TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2
54.TCCR2 |= (1 << CS21); //предделитель на 8
55.
56.ADCSRA = (1 << ADEN) // разрешение АЦП
57.|(1 << ADSC) // запуск преобразования
58.|(1 << ADFR) // непрерывный режим работы АЦП
59.|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0) // предделитель на 64 (частота АЦП 125kHz)
60.|(1 << ADIE); // разрешение прерывания
61.
62.ADMUX = (1 << REFS1)|(1 << REFS0) // внутренний ИОН 2,56V
63.|(0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0); // вход ADC0
64.
65._delay_ms(50);
66.
67.sei(); //глобально разрешаем прерывания
68.
69.while(1)
70.{
71.if (adc_counter > 300) // вычисляем среднее значение АЦП
72.{
73.display = value/adc_counter;
74.adc_counter = 0;
75.value = 0;
76.}	
77._delay_ms(50);
78.}
79.}

Share this post


Link to post
Share on other sites

Объясню на пальцах. Выставляете ADMUX на интересующий канал, запускаете однократное преобразование, дожидаетесь завершения, переставляете на другой, снова запускаете. Запускать АЦП надо после установки ADMUX'a а не до.

Share this post


Link to post
Share on other sites

Технология Maxim Integrated nanoPower: когда малый IQ имеет преимущества

При разработке устройств с батарейным питанием важно выбирать компоненты не просто с малым потреблением, но и с предельно малым током покоя. При этом следует обратить внимание на линейку nanoPower производства компании Maxim Integrated. В статье рассмотрено их применение на примере системы датчиков беспроводной оконной сигнализации.

Подробнее

Я пользуюсь такой функцией (опрос, без прерываний):

// Read the AD conversion result
word read_adc(byte adc_input)
{		
word i;

// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
ADMUX=0x00;
ADCSRA=0x83; // 0x10000011 - Enable, CLK/8=1MHz

ADMUX=adc_input;		

// Delay needed for the stabilization of the ADC input voltage
delay_us(50);

// 3 холостых чтения
for (i=0; i<3; i++)
{
// Start the AD conversion (ADSC)
ADCSRA|=0x40;			

// Wait for the AD conversion to complete (ADIF)
while ((ADCSRA & 0x10)==0);

ADCSRA|=0x10;

i=ADCW;	
} // for

// Читать значение АЦП
i=ADCW&0xFFFE;

// ADC off
ADCSRA=0x00;
ADMUX=0x00;
return i;
} // read_adc

Делаются 3 холостых чтения (где-то читал, что так надёжнее). Если не нужно - уберите.

Если по прерываниям, то вместо

while ((ADCSRA & 0x10)==0);

написать родственный цикл с ожиданием флага, который устанавливается в прерывании.

Edited by hd44780

Share this post


Link to post
Share on other sites

помогите у меня сейчас мозг уже взорвется, я не могу понять почему единица записывается в АDMUX |=(1<<MUX0) а нуль нет, после того как там стоит 1...

// Использование АЦП. Цифровой вольтамперметр

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp

char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};

volatile unsigned char segcounter = 0;

volatile int display_1;

volatile unsigned long value_1;

unsigned int u, g, t = 0, k = 15, z = 4;

volatile unsigned int adc_counter;

// Прерывание по переполнению T2, динамическая индикация

ISR (TIMER2_OVF_vect)

{

PORTD = 0xFF;

PORTB = (1 << segcounter);

switch (segcounter)

{

case 0:

PORTD = ~(SEGMENTE[display_1 % 100000 / 10000]);

break;

case 1:

PORTD = ~((SEGMENTE[display_1 % 10000 / 1000])|0x80); // добавляем десятичную точку

break;

case 2:

PORTD = ~(SEGMENTE[display_1 % 1000 / 100]);

break;

case 3:

PORTD = ~(SEGMENTE[display_1 % 100 / 10]);

break;

}

if ((segcounter++) > 2) segcounter = 0;

}

/***Главная функция***/

int main (void)

{

DDRD = 0xFF;

DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);

PORTD = 0x00;

PORTB = 0x00;

TIMSK = (1 << TOIE2); // разрешение прерывания по таймеру2

TCCR2 = (1 << CS21); //предделитель на 8

ADCSRA = (1 << ADEN) // разрешение АЦП

|(1 << ADFR) // непрерывный режим работы АЦП

|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0); // предделитель на 64 (частота АЦП 125kHz)

ADMUX = (1 << REFS1)|(1 << REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);

_delay_ms(50);

sei(); //глобально разрешаем прерывания

while (1)

{

ADCSRA |= (1 << ADSC); //Начинаем преобразование

while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования

u = (ADCL|ADCH << 8); // Считываем ADC

value_1 = value_1 + (u * k/z);

adc_counter++;

if (adc_counter > 100)

{

display_1 = (value_1*10/adc_counter);

adc_counter = 0;

value_1 = 0;

_delay_ms(50);

g++;

if (g > 10)

{ADMUX |= (1<<MUX0); k = 5; z = 2;}// переход на АДС1 (выполняется)

if (19 < g)

{ADMUX |= (0<<MUX0); k = 15; z = 4; g = 0;}// вот здесь должен происходить переход на АДС0, но перехода нет

}

}

}

hd44780

я не могу понять предоставленный Вами код, как в этом коде установить канал для чтения? как их менять? с уважением

Share this post


Link to post
Share on other sites
                     

Платы Nucleo на базе STM32G0: чего можно добиться с помощью связки Nucleo и Arduino

Платы Nucleo и платы расширения X-NUCLEO от STMicroelectronics можно интегрировать в платформу Arduino с помощью библиотеки STM32duino. Связка плат Nucleo и платформы Arduino, и наличие готовых библиотек – представляет удобный инструмент для создания прототипов и конечных приложений в условиях ограниченного времени. Статья содержит пошаговые инструкции по установке библиотек и запуску примеров для Nucleo.

Подробнее...

Ваша ошибка здесь:

ADMUX = (1 << REFS1)|(1 << REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);

Нуль вы так никогда не запишете. Изучите примитивные лог. операции - http://cxem.net/begi...beginner104.php

Ноль надо писать так:

ADMUX &= ~(1<<MUX0);

или

ADMUX &= ~((1<<MUX0)|(1<<MUX1));

С цветами неохота разбираться :)

Edited by hd44780

Share this post


Link to post
Share on other sites

hd44780

Спасибо, все заработало!!!!

вот полный исправленный код, может таким как я пригодится это для меги 8

// Использование АЦП. Цифровой вольтамперметр

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp

char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80};

volatile unsigned char segcounter = 0;

volatile int display_1;

volatile unsigned long value_1;

unsigned int u, g, t = 0, k = 15, z = 4;

volatile unsigned int adc_counter;

// Прерывание по переполнению T2, динамическая индикация

ISR (TIMER2_OVF_vect)

{

PORTD = 0xFF;

PORTB = (1 << segcounter);

switch (segcounter)

{

case 0:

PORTD = ~(SEGMENTE[display_1 % 100000 / 10000]);

break;

case 1:

PORTD = ~((SEGMENTE[display_1 % 10000 / 1000])|0x80); // добавляем десятичную точку

break;

case 2:

PORTD = ~(SEGMENTE[display_1 % 1000 / 100]);

break;

case 3:

PORTD = ~(SEGMENTE[display_1 % 100 / 10]);

break;

}

if ((segcounter++) > 2) segcounter = 0;

}

/***Главная функция***/

int main (void)

{

DDRD = 0xFF;

DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);

PORTD = 0x00;

PORTB = 0x00;

TIMSK = (1 << TOIE2); // разрешение прерывания по таймеру2

TCCR2 = (1 << CS21); //предделитель на 8

ADCSRA = (1 << ADEN) // разрешение АЦП

|(1 << ADFR) // непрерывный режим работы АЦП

|(1 << ADPS2)|(1 << ADPS1)|(0 << ADPS0); // предделитель на 64 (частота АЦП 125kHz)

ADMUX = (1 << REFS1)|(1 << REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);

_delay_ms(50);

sei(); //глобально разрешаем прерывания

while (1)

{

ADCSRA |= (1 << ADSC); //Начинаем преобразование

while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования

u = (ADCL|ADCH << 8); // Считываем ADC

value_1 = value_1 + (u * k/z);

adc_counter++;

if (adc_counter > 300)

{

display_1 = (value_1*10/adc_counter);

adc_counter = 0;

value_1 = 0;

_delay_ms(50);

g++;

if (g > 10)

{ADMUX |= (1<<MUX0); k = 5; z = 2;}// переход на АДС1 (выполняется)

if (19 < g)

{ADMUX &= ~(1<<MUX0); k = 15; z = 4; g = 0;}// переход на АДС0

}

}

}

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Similar Content

    • By Olga Kovin
      Вольтметр В2-36. В хорошем состоянии. Без ЗИП. В наличии: 1шт. Цена: 9500р     
      Измеритель С6-7. В хорошем состоянии. Без ЗИП. В наличии: 1шт. Цена: 6500р     
      Генератор Г5-63. В  хорошем состоянии. Без ЗИП. В наличии: 1шт. Цена: 7500р    
      Генератор перепадов и синхронизатор СВЧ Я4С-20А.  В хорошем состоянии. Без ЗИП. В наличии: 1шт. Цена: 4000р    
      Динамометр ДОСМ-3-3.  С хранения, в ящике (в комплекте нет шайбы и шарика). В наличии: 1шт. Цена: 3300р.
      г. Энгельс, Саратовская обл.
      Отправлю: почтой, транспортной компанией, привезем в Москву на Митино
       
      Контакты: 
      Моб. тел.:+7904-240-51-17.
      E-mail: olgalosewa86@mail.ru









    • By Максим123456789
      делаю диплом, в схеме у меня микроконтроллер PIC16F688 и мне нужно его заменить на ATmega. Не могу найти похожий
    • By Dima34
      Марка Вольтметр В7-27А/1
      Страна производитель СССР
      Год выпуска 1981
      Состояние техническое, неисправный показывает перегрузку или набор чисел, внутри все на месте, есть пару замененных электролитических конденсаторов. Как достался так и продаю!
      Косметика на 4 отсутствует заглушка на верхней крышке есть потертости на корпусе.
      Комплект сам прибор могу в довесок кинуть различных кабелей, если это вам нужно конечно.
      Цена по сути металла.
      6500 рублей
      Если есть вопросы все в ЛС и по существу, или на почту istomindimavolga@mail.ru
      Отправлю ТК выгоднее будет Энергия или ПЭК 400-600 рублей примерно. Можно и почтой но из-за веса может выйти дорого, могу рассчитать предметно! Оплата на карту СБ.
       
    • By Anton Bondarenko
      Всем привет
      Прошу не ругать, впервые подобный вопрос задаю.
      Хочу сделать прибор, который будет посылать сигнал, когда возле прибора будет проходить металлический предмет. 
      — угол отслеживания до 30° а лучше прямая линия, траектория
      — время реакции очень высокое до 100 мс
      — ширина проема в котором нужно сканировать от 10 до 20метров,
      — передача сигнала через вифи
      Может есть готовые решения, или отдельные компоненты.
      Подскажите пжл в каком направлении искать.
      Смотрел датчики движения, но главная проблема — время реакции.
      Спасибо
       
  • Сообщения

    • Помню на 100%, что было две обмотки выходных на трансформаторе, и без средней точки. Если память не изменяет, то были задействованы 2 синих провода, вот только как?, не помню.
    • Сколько людей, столько и мнений. Пока нет 1кГц. Переделал под 18+19кГц. Сделаю позже.   С одной ячейки вытащил, а там и те, и те. Звиняй   Да. Обмерял им бэту - сильно плавает. Брал на ебэе, типа оригинальные мотороллы.
    • Конденсаторы какой минимальной емкости можно протестировать этой "чирикалкой"?
    • Балаболка, а ты уверен в своих словах? Серьезно, ведешь себя, как ребенок. Все дело в том, что умные люди могут рассчитать результат и собирать всякую хрень им не требуется. Дураки же тратят время и бегают вокруг микроволновки с показометрами.   Смотрю, голову ты так и не полечил. ГДЕ Я ТАКОЕ ГОВОРИЛ, балаболка?   Да просто у тебя мозгов не хватит, что-либо доказать. Ты ведь на протяжении всей темы не можешь сказать, какую частоту ловит твой говномер. Более того, ты не можешь даже самые простые действия сделать, такие как рассчитать ослабление сигнала на заданном расстоянии. А ведь формула там простейшая. У тебя получаются измерения ради измерений, а практическая ценность стремится к нулю, ибо их невозможно привязать к каким-либо величинам.   А якобы высокий уровень исходящий от микроволновки - твоя надуманная проблема.   В старых телефонах передатчики мощнее были, чем сейчас.    Так он может и на 4G работать, а это уже выше двух гигов частота.
    • Выше берите! Отпуск! 
    • Власти Индии решили закупить истребители Rafale вместо российских Су-30МКИ, поскольку французские машины превзошли их по своим показателям. Как пишет The Economic Times, дальность полета Rafale составляет от 780 до 1055 километров, а дальность Су-30МКИ оценивается в 400-550 километров. Кроме того, Rafale могут совершить пять боевых вылетов в день, тогда как российские — всего три. Наконец, способность длительного барражирования французских истребителей в 1,5 раза выше, чем у российских. В индийском минобороны нашли у Су-30МКИ только одно преимущество — он дешевле. Французские самолеты обладают лучшими системами обнаружения и вооружения, отметили в ведомстве. Индия купила 36 истребителей Rafale на общую сумму 7,87 млрд евро. Первые самолеты должны прибыть в страну в мае 2020 года. https://www.rosbalt.ru/world/2019/11/17/1813631.html
    • Стабилизатор и есть. Надпись читается?
×
×
  • Create New...