Зарегистрирован: Вс мар 27, 2022 09:38:17 Сообщений: 160
Рейтинг сообщения:0
Добрый день форумчане!
Вопрос такой. МК ( Atmega8 ) необходимо измерять 2 напряжения одновременно,как переключатся между каналами? Как грамотно построить программу? Один канал делал как 2 не пойму. Подскажите пожалуйста. Спасибо.
// вызываем функцию АЦП-Atmega 8 (из любого места программы) // при вызове функции АЦП-Atmega 8 указываем номер канала на котором будем измерять напряжение (0...7) adc(5); // канал ADC 5
//полученный результат сохраняем в переменную u (для последующей обработки) u=ADCW;
правда как это делать в случае непрерывное преобразования... ну наверное это логичнее всего делать в обработчике прерывания...
каждый раз по окончанию преобразования срабатывает обработчик прерывания... вот там то и надо менять канал АЦП-Atmega 8... чтоб пока не закончится преобразование канал не менялся... а то будут ошибки преобразования... и неверный результат преобразования...
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
Зарегистрирован: Вс мар 27, 2022 09:38:17 Сообщений: 160
Рейтинг сообщения:0
Ну непрерывное потому что он у меня меряет потоянно и кождое прерывание по окончаню измерения складывается переменную uint_32, и так 250 раз. Потом результат высчитывается по формуле. Точность поражает просто. С мультиметром один в один показания. Для такого МК я считаю это офигенно! Пробовал другие способы ну они что-то не зашли... То показания прыгаю то не точно... Этот способ понравился поэтому его и использую. Только мне нужно измерять разные напряжения. 2 канала нужны. Хотя бы сделать сначала одно измерение потом другое... Ну буду что-то придумывать.
// вызываем функцию АЦП-Atmega 8 // при вызове функции АЦП-Atmega 8 указываем номер канала на котором будем измерять напряжение (0...7) adc(5); // канал ADC 5 //полученный результат сохраняем в переменную u (для последующей обработки) u=ADCW;
// вызываем функцию АЦП-Atmega 8 // при вызове функции АЦП-Atmega 8 указываем номер канала на котором будем измерять напряжение (0...7) adc(6); // канал ADC 6 //полученный результат сохраняем в переменную u (для последующей обработки) u=ADCW;
// вызываем функцию АЦП-Atmega 8 // при вызове функции АЦП-Atmega 8 указываем номер канала на котором будем измерять напряжение (0...7) adc(7); // канал ADC 7 //полученный результат сохраняем в переменную u (для последующей обработки) u=ADCW;
}// while(true)
в этом случае работать будет чуть медленней... но зато мы получаем гарантированный результат))
а если мы запустим непрерывное преобразование и будем переключать каналы в обработчике прерывания... то никто ничего не гарантирует)) потому что АЦП-Atmega 8 в режиме непрерывного преобразования не будет ждать пока мы переключим каналы)) точность показаний может пойти на смарку))
хотя... если бы мы писали программу на Ассемблере... мы бы могли всё рассчитать с точность до такта процессора)) тогда другое дело. но на Си гарантий нет что всё точно будет работать... это уже как компилятор Си решит))
Зарегистрирован: Вс мар 27, 2022 09:38:17 Сообщений: 160
Рейтинг сообщения:0
Та под STM нужна среда. CUBE IDE а меня его нет. И программатор STM link комп перестал поддерживать. Вернее не сам программатор а прошивальщик не открывается. Пишет ошибку типа там не хватает фала какого-то там. И не реально его поставить. Не ставится. Тоже запрещает. Наверное Америкосы какую то западлянку намутили.
Добавлено after 4 minutes 58 seconds: Ну вот так и получается если я в прерывании начинаю чё-то там манипулировать каналами у меня протеус начинает подвисать! Он не может понять что от него хотят... А Ассемблер это для людей "Индиго". Это мне недоступно!
ну в данном случае переходить на Ассемблер не вижу смысла... и так всё будет нормально работать)) на Си. переходить на Ассемблер приходится... если нужно что-то необычное...)) например генератор нестандартных сигналов)) включаю несколько Atmega 8 в параллель... с тактированием от общего кварца... синхронизируем все инструкции во всех Atmega 8... причём надо не только синхронное выполнение всех инструкций с точностью до такта процессора... но и с точностью до фазы !
Зарегистрирован: Пт мар 19, 2021 08:58:45 Сообщений: 118
Рейтинг сообщения:0
я вот так считаю три канала меге328 в меге8 аналогично
Код:
#define FIRST_ADC_INPUT 0 #define LAST_ADC_INPUT 2 volatile unsigned long adc[LAST_ADC_INPUT+1];
//********Voltage Reference: AVCC pin******************************************** unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; // Voltage Reference: AVCC pin #define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))
ISR (ADC_vect) { static unsigned int cnt; static uint8_t input_index=0; static unsigned long adc_sum[LAST_ADC_INPUT+1]; //переменная для суммы значения ADC
// Read the AD conversion result cnt++; adc_data[input_index]=ADCW; adc_sum[input_index]+= (unsigned long)adc_data[input_index]; // суммируем
// Select next ADC input if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index; // Delay needed for the stabilization of the ADC input voltage _delay_us(10); // Start the AD conversion ADCSRA|=(1<<ADSC);
if (cnt >= (64*(LAST_ADC_INPUT+1))) { //если сделали 64 замера на каждый канал for (uint8_t i=0; i<=LAST_ADC_INPUT; i++){ adc[i]=adc_sum[i]; adc_sum[i]=0; } cnt=0; //сбросили счетчик adc_status=true; //подняли флаг, что очередная сумма замеров ГОТОВА } }
void ADC_Init(void){ //в этих расчетах у меня сомнения //Время одного преобразования АЦП = 108,25uS //T= ((11.5+2)/ADC Clk freq)+(4/F_CUP)=((11.5+2)/0,125)+(4/16)=0.00010825сек или 108,25uS //где 11,5 для 10бит АЦП //Двойка(2) - минимальное время захвата измеряемого напряжения в УВХ – 2 такта частоты CLK_ADC // ADC Clock frequency: 125,000 kHz // ADC Voltage Reference: AREF pin // ADC Auto Trigger Source: ADC Stopped ADMUX= FIRST_ADC_INPUT | ADC_VREF_TYPE; ADCSRA=(1<<ADEN) | (1<<ADSC) |(1<<ADIE) | (1<<ADPS2) | (1<<ADPS1)| (1<<ADPS0); }
int main(void){ ADC_Init(); while(1){ if(adc_status ){ //ждем окончания измерений ацп for (uint8_t i=0; i<=LAST_ADC_INPUT; i++) { adc[i]=adc[i]>>6;//сумму АЦП делим на 64 } } }//end while }//end main
Последний раз редактировалось kote52 Чт авг 31, 2023 20:06:39, всего редактировалось 1 раз.
1) скачай из сундука и установи кодевиженавр 2) запусти мастер настроек 3) установи галочки в нужных местах 4) забери рабочий код
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Предделитель побольше поставь, меньше шумов будет и отпадёт необходимость в таком большом буфере. А ещё при переключении каналов есть такой прикол, что УВХ-то там одно и каналы могут друг на друга влиять. Если этот эффект будет заметен, то можно первое преобразование запускать вхолостую, а потом серию измерительных.
не, он шумы во благо использует - для повышения разрядности оцифровки. а вот про холостой первый замер - инфа стоящая!
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Предделитель побольше поставь, меньше шумов будет и отпадёт необходимость в таком большом буфере. А ещё при переключении каналов есть такой прикол, что УВХ-то там одно и каналы могут друг на друга влиять. Если этот эффект будет заметен, то можно первое преобразование запускать вхолостую, а потом серию измерительных.
Как это сделать если ты по очередно замеры делаешь, adc0 потом adc1 потом adc2... По два замера, и откидывать первый? Тогда в двое время увеличится на все замеры.
Добавлено after 1 minute 1 second: зато задержку между переключением входа и измерением можно будет убрать...
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
задержку между переключением входа и измерением нет смысла делать, так как само переключение входа еще не означает, что вход подключился к УВХ. к УВХ вход подключается непосредственно в начале измерения.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
если ты по очередно замеры делаешь, adc0 потом adc1 потом adc2
101 замер ацп0, первый выкинуть, потом 101 замер ацп1 и так далее. Разве есть необходимость обязательно перемежать каналы? Я так на аттини25 повышающий преобразователь сделал, где один канал измерял резистор для управления, а второй как раз и отвечал за напряжение. 1 холостой и 4 рабочих замера на каждый канал. Вполне себе отрабатывало всё.
Добавлено after 1 minute 54 seconds: Точнее, количество рабочих замеров задаётся программно, но для моих целей оказалось оптимально именно 4. Но их может быть сколько нужно.
Добавлено after 1 hour 52 minutes 47 seconds: Ага, вот нашёл кусочек кода. Это для тини25, так что регистры и значения в них могут быть другими. Но принцип тот же. Функция получает количество измерений, а возвращает сумму всех всех измерений.
Код:
uint16_t getsup(uint8_t count) //измерение напряжения питания { uint16_t result=0; ADMUX=0b00001100; //питание как опорное, выравнивание вправо, измеряется 1,1 Вольт
Зарегистрирован: Вс мар 27, 2022 09:38:17 Сообщений: 160
Рейтинг сообщения:0
Вот как сделал я. Возможно не по правилам и не так круто но работает 2 канала одновременно. Толь почемуто на делителе ( 128 ) это гдето 65 кГц. При других настрорйках не работает. И мне кажется если так делать то больше 2 каналов не опросить.
ISR(ADC_vect) // прерывание от АЦП { adc_counter++; adc_buffer+=ADC;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 32
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения