Jump to content
Ivarrr

Опрос двух каналов АЦП

Recommended Posts

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

 

#define F_CPU 8000000U
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>

#define INDICATOR PORTD
#define RANK PORTB

unsigned int UR1=0, UR2=0, UR3=0, UR4=0; //переменные для деления на разряды значения напряжения
unsigned int IR1=0, IR2=0, IR3=0, IR4=0; //переменные для деления на разряды значения силы тока
int GainControl=1;
int current_ch=0;
float I, U;
unsigned char voltage, current;

unsigned int NUMS [10] = {0b11000000, 0b11111001, 0b10100100, 0b10110000, 0b10011001, 0b10010010, 0b10000010, 0b11111000, 0b10000000, 0b10010000}; // от 0 до 9

int main(void)
{
    DDRB=0xFF; PORTB=0x00; //ножки порта B для разряда
    DDRC=0x00; PORTC=0x00; //ножки порта C для АЦП
    DDRD=0xFF; PORTD=0xFF; //ножки порта D для индикаторов
    
    TCCR0 |= (1<<CS01); TCCR0 &= ~((1<<CS00) | (1<<CS02)); //настройка частоты таймера f/8
    TIMSK |= (1<<TOIE0); //разрешение прерываний по переполнению таймера
    TCNT0=0; // обнуление счетчика
    
    ADCSRA |= ((1<<ADEN) | (1<<ADSC) | (1<<ADPS2)); // запуск АЦП, запуск преобразования, предделитель 16
    ADCSRA &= ~((1<<ADFR) | (1<<ADIF) | (1<<ADPS1) | (1<<ADPS0)); // режим преобразвания прерывестый, флаг перобразования опущен, предделитель 16
    ADMUX |= ((1<<REFS0) | (1<<REFS1)); //источник опорного напряжения 2.56В
    ADMUX &= ~((1<<ADLAR) | (1<<MUX0) | (1<<MUX1) | (1<< MUX2) | (1<<MUX3)); // направление записи, измерительная ножка ADC0;
    
    sei(); // вкл прерывания
    while (1) 
    {
        if (ADCSRA & (1<<ADIF))
        {
                    U_Convert((U*5.00/1024)*100);
                    I_convert((I*5.00/1024)*100);
        }
    }
}

void U_Convert (unsigned int U_num)  //деление на разряды напряжения
{
    UR1=U_num/100;
    UR2=U_num%100/10;
    UR3=U_num%10;
}

void I_convert (unsigned int I_num) //деление на разряды тока
{    IR1=I_num/100;
    IR2=I_num%100/10;
    IR3=I_num%10;
}

ISR (TIMER0_OVF_vect)
{        
    if (GainControl == 1) {INDICATOR = 0b11111110; RANK = NUMS[UR1];} //отображение 1ого разряда напряжения
    if (GainControl == 2) {INDICATOR = 0b11111101; RANK = NUMS[UR2];} //отображение 2ого разряда напряжения
    if (GainControl == 3) {INDICATOR = 0b11111011; RANK = NUMS[UR3];} //отображение 3ого разряда напряжения    
    if (GainControl == 4) {INDICATOR = 0b11110111; RANK = NUMS[IR1];} //отображение 1ого разряды силы тока
    if (GainControl == 5) {INDICATOR = 0b11101111; RANK = NUMS[IR2];} //отображение 2ого разряды силы тока
    if (GainControl == 6) {INDICATOR = 0b11011111; RANK = NUMS[IR3];} //отображение 3ого разряды силы тока
    GainControl++;
    if (GainControl > 6) GainControl=0; //  мониторинг переменной для управления затворами    
}

ISR (ADC_vect) 
{
    if (current_ch == 0)
      {
          U = ADC;
          voltage = (U*2.56/1024)*100;
          ADMUX |= (1<<MUX0);
          current_ch = 1;
          ADCSRA |= (1<<ADSC);
      }
      else
      {
          I = ADC;
          current = (I*2.56/1024)*100;
          ADMUX &= ~(1<<MUX0);
          current_ch = 0;
          ADCSRA |= (1<<ADSC);
      }
}

Share this post


Link to post
Share on other sites

Да блин этих измерителей вольт/амперов да ещё с исходниками в инете полно.

Самому похоже лень искать и разбираться:use_search:

Share this post


Link to post
Share on other sites

Разбираться в чем? В исходниках с машинным кодом?

Share this post


Link to post
Share on other sites

Вебинар «Экосистема MEAN WELL. Решения для любых задач электропитания» (20.05.2021)

Приглашаем 20 мая на вебинар, посвященный линейке поставок компании MEAN WELL и ее подходу к производству источников питания — как экосистемы продукции и услуг, которая позволяет подобрать оптимальный источник питания для любых задач электропитания. Рассмотрим весь спектр выпускаемой продукции MEAN WELL в области AC/DC-, DC/DC- и DC/AC-преобразователей с подробным разбором интересных и уникальных новинок, их применении и многое другое.

Подробнее

1 hour ago, Ivarrr said:

float I, U;
unsigned char voltage, current; 

...

voltage = (U*2.56/1024)*100;

Жесть...

Share this post


Link to post
Share on other sites

Барьерные силовые клеммы от Degson – расширение складского ассортимента Компэл

Обновленная линейка барьерных клеммных блоков Degson, поступивших на склад Компэл, содержит широкий ряд клемм, подходящих для соединения проводников различного сечения (от 22AWG до 10AWG). Барьерные клеммные колодки сочетают в себе удобство, простоту и надежность соединения. Это достигается за счет ответственного производства и использования высококачественных материалов. Винтовые клеммные блоки барьерного типа Degson предназначены в первую очередь для коммутации в сильноточных цепях, например, в распределительных и измерительных системах.

Подробнее

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

в чем? В исходниках с машинным кодом?

что значит машинный код ?

пример с работающей программы ;

rcall  I_ADC

 rcall U_ADC

rjmp PC-2

I_ADC:

ldi temp,(1<<REFS1)+(1<<REFS0)+(1<<adlar)+(1<<MUX2)+(1<<MUX1)+(1<<MUX0); Выбор ADC7, выравнивание влево, ИОН=2.56 подключен к AREF
out ADMUX, temp
ldi  temp,(1<<ADEN)+(1<<ADSC)+(1<<ADPS1)+(1<<ADPS2) out ADCSRA,temp
sbic ADCSRA,ADSC rjmp PC-1 in temp,ADCH

но походу у вас  другие проблемы

 

Share this post


Link to post
Share on other sites

Материалы вебинара «Решения Analog Devices для гальванической изоляции. Обзор технологий и новинок»

Опубликованы материалы вебинара, посвященного решениям Analog Devices для гальванической изоляции. На вебинаре рассказали о: технологии гальванической изоляции iCoupler, цифровых изоляторах, технологии isoPower, гальванически изолированных интерфейсах (RS-485, CAN, USB, I2C, LVDS) и многом другом. Материалы вебинара будут интересны разработчикам промышленной автоматики и медицинской техники.

Подробнее

Что именно не получается, и что происходит вместо того, что должно быть? Яб может подсказал, но знакомый экстрасенс в отпуске. :lol:

И где у вас, как минимум, прототипы функций перед main()? Или это я отстал от жизни и это какой-то новомодный СИ?:crazy:

12 часов назад, Ivarrr сказал:

unsigned int UR1=0, UR2=0, UR3=0, UR4=0; //переменные для деления на разряды значения напряжения
unsigned int IR1=0, IR2=0, IR3=0, IR4=0; //переменные для деления на разряды значения силы тока

А зачем вам 2-х байтовые переменные, для храниния чисел от 0 до 9-ти? Понятно что ресурсы позволяют, но это называется быдлокодингом.

11 часов назад, _abk_ сказал:

Жесть...

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

Edited by Ermak

Share this post


Link to post
Share on other sites
13 часов назад, Ivarrr сказал:

ISR (TIMER0_OVF_vect)
{        
    if (GainControl == 1) {INDICATOR = 0b11111110; RANK = NUMS[UR1];} //отображение 1ого разряда напряжения
    if (GainControl == 2) {INDICATOR = 0b11111101; RANK = NUMS[UR2];} //отображение 2ого разряда напряжения
    if (GainControl == 3) {INDICATOR = 0b11111011; RANK = NUMS[UR3];} //отображение 3ого разряда напряжения    
    if (GainControl == 4) {INDICATOR = 0b11110111; RANK = NUMS[IR1];} //отображение 1ого разряды силы тока
    if (GainControl == 5) {INDICATOR = 0b11101111; RANK = NUMS[IR2];} //отображение 2ого разряды силы тока
    if (GainControl == 6) {INDICATOR = 0b11011111; RANK = NUMS[IR3];} //отображение 3ого разряды силы тока
    GainControl++;
    if (GainControl > 6) GainControl=0; //  мониторинг переменной для управления затворами    
}

unsigned char NUMS[6];

ISR (TIMER0_OVF_vect)
{
    INDICATOR = ~(1<<GainControl);
    RANK = NUMS[GainControl];
    GainControl++;
        if (GainControl > 6) GainControl=0; //  мониторинг переменной для управления затворами    
}

13 часов назад, Ivarrr сказал:

void U_Convert (unsigned int U_num)  //деление на разряды напряжения
{
    UR1=U_num/100;
    UR2=U_num%100/10;
    UR3=U_num%10;
}

void I_convert (unsigned int I_num) //деление на разряды тока
{    IR1=I_num/100;
    IR2=I_num%100/10;
    IR3=I_num%10;
}

void NumToSymb(unsigned char Num)
{
    unsigned char i=0, j=0;
      while(Num>99)
    {
        j++;
        Num -=100;
    }
    while(Num>9)
    {
        i++;
        Num -=10;
    }

    Symb[2]=j
    Symb[1]=i;
    Symb[0]=Num;
}

Помоему так рациональнее, чем куча делений, которые контроллер не умеет.

Edited by Ermak

Share this post


Link to post
Share on other sites
30.01.2021 в 12:17, Ivarrr сказал:

Разбираться в чем? В исходниках с машинным кодом?

Если можете, то и в кодах есть.

А так и Си и асемблер и прочее, прочее  есть, в инете всё есть.

А вы пытаетесь сделать что то своё, кривое

30.01.2021 в 11:05, Ivarrr сказал:

Помогите понять где ошибка... не получается

Так можно кучу времени сэкономить и изобретать велосипед с треугольными колёсами, взять исходник (обычно даже с коментариями) и его понять.

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...

  • Сообщения

  • Similar Content

    • By dima040891
      Приветсвую!
      Кто ни будь работал с микросхемой STLED316S?  Это драйвер семисегментонго индикатора.
      Можете привести минимальный кусок кода который выводит любую цифру на дисплей. Из документации не пойму как с ней работать...
      На форумах инфы почти нет. Из того что есть тоже толку мало. Буду рад любой инфе по этой микросхеме.

      Ещё правильно же понимаю биты по SPI передаются младшим вперёд, а такты нужно передавать инверсные?

      В качестве МК применяю STM32.
    • By Yahont7
      Здравствуйте коллеги, друзья и единомышленики.
      Вообще моя специфика это электротехника и электрооборудование. Поскольку нередко приходится проектировать и изготовлять различные щиты, управления различного электрооборудования, то есть необходимость в различных контроллерах, которые бы измеряя параметры сети предпринимали те или иные функциональные процедуры. Да сегодня существую различные ПЛК, и прочие устройства под дин рейку на которых можно реализовать все, что угодно. Но к сожалению, либо, они дороги, либо недоступнн. Кроме того вообще ПЛК умеющих "из коробки" измерять сетевое напряжение по всем фазам (не говоря про ток)  в природе пока не встречал. Поэтому к ПЛК, приходится покупать т.н. датчики или измерители сетевых параметров, стоимость которых сопоставима с ПЛК, к тому же растет габарит щита где все это будет стоять. Так или иначе я решил научится делать хотябы простейшие контроллеры, с обычной прошивкой, которые бы могли реализовать все мои предпочтения. 
      Выбрав МК STM32, подобрав схемотехнику внешних интерфейсов и исполнительных устройств.
      Пока, я остановился перед выбором каким образом измерять, сетевое напряжение переменного тока. На первый взгляд почти, все производители реле напряжений используют вот такую схему:
       
      Но мнению специалистов, эта схема плоха наличия невысокого внутреннего сопротивления самого АЦП микроконтроллера.
      Поэтому рекомендуют добавить ОУ в режиме буфера:

      В обоих схемах, измеряемый сигнал смещают на половину питающего/опорного напряжения, в результате теряется один бит точности АЦП.
      Поиск в интернете, навел на следующие материалы:
      1. Диапазон преобразования АЦП микроконтроллера можно расширить вдвое без потери точности. В схеме используются два однопериодных выпрямителя на ОУ, соответственно необходимо два входа АЦП. Соответственно хочется схема по лучше.
      2. Двухполупериодный активный выпрямитель без диодов. Все прекрасно и просто, но рекомендуется использовать дорогой и труднодоступный ОУ. Простые и дешевые ОУ типа МСP6002/4, при моделировании этой, схемы (в Multisim) ее работоспособность не подтвердили. Я был не один, кто хотел ее реализовать, у котов на форуме есть обсуждение этой схемы, но там тоже судя по всему тоже успехов не достигли. Поэтому я продолжил поиск и попал на третий вариант, это...
      3. Учебный материал - Прецизионные выпрямители. Предложенная схема в идеальных условиях (когда на вход подключен генератор сигналов) показала работоспособность в среде Multisim. Однако когда я дочертил высоковольтный делитель, и подал высокое напряжение, то на выходе получил также модуль синусоиды, но его амплитуда была снижена на 35-40%, от того кот. был на выходе резист делителя. В итоге в эту схему я добавил буферный каскад ОУю В итоге, схема обрела следующий вид:

      В этот раз моделирование уже подтвердило ожидаемые результаты:
      - на выходе имеем, модуль синусоиды, причем с той же амплитудой, которая имеется на входном резистивном делителе.
      - если подать напряжение превышающее номинал резист делителя, то на входе МК оно будет срезанным на уровне 3вольт.
      - теперь можно использовать все 12бит АЦП, для оцифровки
      Но получилась схема какая-то громоздкая на один канал напряжения.
      Можно ли ее упростить, и есть ли более простые схемы решающие данную проблему??
       
    • By sunjob
      добрый день
      проект v-usb
      выкус из спецификации/инета/форумов:
      - реализация не полностью соответствует стандарту
      - работа на 100% не гарантируется
      - питание по USB / с компа может провалиться до 4-4.5В (а F_CPU идет в "притирочку" ...)  :))
      у всех рекомендованных схем подключения (3 шт) имеются те или иные очевидные минусы.



      как следствие стабильно может работать только при "определенных условиях"
      в планах поработать с библиотекой.
      для начало решил "набросать" альтернативный вариант. (так сказать, попытаться закрыть все возможные дыры в подключении)


       
      достаем помидоры, баркова, мысли, высказываемся (заранее благодарен)
      tag: v-usb, usb, avr, atmega328p, avr-gcc, linux/mac-osx
      NO atmega32u4, NO arduino pro micro etc...

    • By yakutyonok7
      Нужен аналог индикатора ИЖЦ4-14/7 и АЦП КР572ПВ13. Кто-нибудь может подсказать? Нужно для курсового проекта 
    • By Обычный Человек
      Микроконтроллер ATmega328p, внешний кварц 16МГц. Компилятор avr-gcc с оптимизацией O1

      Написал код для управление шаговым двигателем. Работает так: требуемая скорость задается переменной STP1_ReqSpeed, дальше с частотой 100Гц срабатывает таймер TIM0, который высчитывает с какой частотой надо подавать сигналы на вход шагового драйвера. TIM1 работает в режиме частотно импульсной модуляции и по прерыванию меняет значение пина на противоположное.

      Управление работает, скорость регулируется, но по какой то причине случаются пропуски шагов. Чаще всего во время ускорения. Количество пропусков от 0 до 4, обычно 2-3, длятся 32мс.

      Из кода вырезал неиспользуемое. Заменить прерывания на аппаратный ШИМ возможности нет. Как убрать эти пропуски?
      Осциллограммы:
       
       
×
×
  • Create New...