Форум РадиоКот https://radiokot.ru/forum/ |
|
АЦП-Atmega 8 https://radiokot.ru/forum/viewtopic.php?f=57&t=189791 |
Страница 1 из 1 |
Автор: | aleksey chilov [ Чт авг 31, 2023 16:56:12 ] |
Заголовок сообщения: | АЦП-Atmega 8 |
Добрый день форумчане! Вопрос такой. МК ( Atmega8 ) необходимо измерять 2 напряжения одновременно,как переключатся между каналами? Как грамотно построить программу? Один канал делал как 2 не пойму. Подскажите пожалуйста. Спасибо. |
Автор: | roman.com [ Чт авг 31, 2023 17:11:50 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
// создаём переменную куда быдем записывать результат измерения unsigned int u; // буфер АЦП-Atmega 8 // создаём функцию АЦП-Atmega 8 ////////////////////////////////// АЦП: -0,000.070c void adc(unsigned char adc_input) { ADMUX = 0b01000000 | adc_input; // опорное AVCC // канал ADC0...ADC7 delay_us(10); ADCSRA|=0b01000000; while (ADCSRA & 0b01000000); } ////////////////////////////////// // настраиваем АЦП-Atmega 8 ADCSRA=0x85; // вкл. ADC // 8 МГц/32=250.000 Hz // вызываем функцию АЦП-Atmega 8 (из любого места программы) // при вызове функции АЦП-Atmega 8 указываем номер канала на котором будем измерять напряжение (0...7) adc(5); // канал ADC 5 //полученный результат сохраняем в переменную u (для последующей обработки) u=ADCW; |
Автор: | aleksey chilov [ Чт авг 31, 2023 17:54:21 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Вот моя конструкция: #if 1 //______________Под аккумулятор_______________________// ADMUX = 5; // вход ADC5 (PORTC5) ADMUX|=(1<<REFS0); // ИОН - AVCC с внешним конденсатором 5 вольт. ADCSRA|=(1<<ADPS1)|(1<<ADPS2);// 125.000 Гц. ADCSRA|=(1<<ADIE); // разрешаем прерывание от ацп ADCSRA|=(1<<ADEN); // Разрешение АЦП ADCSRA|=(1<<ADSC);// Начинаем преобразование ADCSRA|=(1<<ADFR);// непрерывный режим #endif void ADC_battery(volatile uint8_t *adc_count, volatile uint32_t *adc_buff, volatile uint16_t *MO_adc) // Читаем МОТОР { if(*adc_count == 250) { *MO_adc = ((*adc_buff*5*4*100)/1024)/ *adc_count; *adc_buff = 0; *adc_count = 0; } } Вопрос! Как пререключать их чтобы 2 канала работали??? И где? Пробовал в ISR тогда всё сыпется... |
Автор: | roman.com [ Чт авг 31, 2023 18:27:09 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
странная конструкция... зачем непрерывное преобразование для аккумуляторов... ну да ладно)) переключение каналов осуществляется в регистре ADMUX (он же мультиплексор). а вот и сам регистр)) //ADMUX //1... .... REFS1 - опорное напряжение - 0 //.1.. .... REFS0 - опорное напряжение - 1 - AVCC //..1. .... ADLAR - Выравнивание результата //...1 .... - //.... 1... MUX3 - номер канала //.... .1.. MUX2 - номер канала //.... ..1. MUX1 - номер канала //.... ...1 MUX0 - номер канала - ADC0...ADC7 (0000=ADC0) //REFS1=0 REFS0=0 - ИОН=AREF //REFS1=0 REFS0=1 - ИОН=AVCC //REFS1=1 REFS0=0 - не используется (зарезервировано) //REFS1=1 REFS0=1 - ИОН=2.56V (встроенный ИОН 2.56V) значит надо в каком то месте программы прописывать регистр по новой... ADMUX = 5; // вход ADC5 (PORTC5) ADMUX|=(1<<REFS0); // ИОН - AVCC с внешним конденсатором 5 вольт. ... ADMUX = 6; // вход ADC5 (PORTC5) ADMUX|=(1<<REFS0); // ИОН - AVCC с внешним конденсатором 5 вольт. ... ADMUX = 7; // вход ADC5 (PORTC5) ADMUX|=(1<<REFS0); // ИОН - AVCC с внешним конденсатором 5 вольт. ... и т.д.)) правда как это делать в случае непрерывное преобразования... ну наверное это логичнее всего делать в обработчике прерывания... каждый раз по окончанию преобразования срабатывает обработчик прерывания... вот там то и надо менять канал АЦП-Atmega 8... чтоб пока не закончится преобразование канал не менялся... а то будут ошибки преобразования... и неверный результат преобразования... ![]() вообще то так никто не делает... ну да ладно)) ![]() |
Автор: | aleksey chilov [ Чт авг 31, 2023 18:53:56 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Ну непрерывное потому что он у меня меряет потоянно и кождое прерывание по окончаню измерения складывается переменную uint_32, и так 250 раз. Потом результат высчитывается по формуле. Точность поражает просто. С мультиметром один в один показания. Для такого МК я считаю это офигенно! Пробовал другие способы ну они что-то не зашли... То показания прыгаю то не точно... Этот способ понравился поэтому его и использую. Только мне нужно измерять разные напряжения. 2 канала нужны. Хотя бы сделать сначала одно измерение потом другое... Ну буду что-то придумывать. |
Автор: | kote52 [ Чт авг 31, 2023 19:13:27 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Переходи на stm32f103 хотя бы. Сам мастерю себе зу для акб, его парный режим АЦП меня больше радует чем АЦП меги. |
Автор: | roman.com [ Чт авг 31, 2023 19:21:57 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
так переключать каналы мы можем и главной программе... делаем одиночное преобразование... и вызываем функцию преобразования столько сколько нужно)) // создаём переменную куда быдем записывать результат измерения unsigned int u; // буфер АЦП-Atmega 8 // создаём функцию АЦП-Atmega 8 ////////////////////////////////// АЦП: -0,000.070c void adc(unsigned char adc_input) { ADMUX = 0b01000000 | adc_input; // опорное AVCC // канал ADC0...ADC7 delay_us(10); ADCSRA|=0b01000000; while (ADCSRA & 0b01000000); } ////////////////////////////////// // настраиваем АЦП-Atmega 8 ADCSRA=0x85; // вкл. ADC // 8 МГц/32=250.000 Hz // главная программа. while(1) { // вызываем функцию АЦП-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 в режиме непрерывного преобразования не будет ждать пока мы переключим каналы)) точность показаний может пойти на смарку)) хотя... если бы мы писали программу на Ассемблере... мы бы могли всё рассчитать с точность до такта процессора)) тогда другое дело. но на Си гарантий нет что всё точно будет работать... это уже как компилятор Си решит)) ![]() |
Автор: | aleksey chilov [ Чт авг 31, 2023 19:29:55 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Та под STM нужна среда. CUBE IDE а меня его нет. И программатор STM link комп перестал поддерживать. Вернее не сам программатор а прошивальщик не открывается. Пишет ошибку типа там не хватает фала какого-то там. И не реально его поставить. Не ставится. Тоже запрещает. Наверное Америкосы какую то западлянку намутили. Добавлено after 4 minutes 58 seconds: Ну вот так и получается если я в прерывании начинаю чё-то там манипулировать каналами у меня протеус начинает подвисать! Он не может понять что от него хотят... А Ассемблер это для людей "Индиго". Это мне недоступно! |
Автор: | roman.com [ Чт авг 31, 2023 20:03:16 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
ну в данном случае переходить на Ассемблер не вижу смысла... и так всё будет нормально работать)) на Си. ![]() переходить на Ассемблер приходится... если нужно что-то необычное...)) например генератор нестандартных сигналов)) включаю несколько Atmega 8 в параллель... с тактированием от общего кварца... синхронизируем все инструкции во всех Atmega 8... причём надо не только синхронное выполнение всех инструкций с точностью до такта процессора... но и с точностью до фазы ! Вложение: тут без Ассемблера никуда... ![]() это что... я человек "Индиго" ? )) ничё се... каждый день узнаю про себя что-то новое)) ![]() |
Автор: | kote52 [ Чт авг 31, 2023 20:05:10 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
я вот так считаю три канала меге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 |
Автор: | Ivanoff-iv [ Пт сен 01, 2023 09:40:21 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
1) скачай из сундука и установи кодевиженавр 2) запусти мастер настроек 3) установи галочки в нужных местах 4) забери рабочий код |
Автор: | >TEHb< [ Пт сен 01, 2023 11:31:20 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Предделитель побольше поставь, меньше шумов будет и отпадёт необходимость в таком большом буфере. А ещё при переключении каналов есть такой прикол, что УВХ-то там одно и каналы могут друг на друга влиять. Если этот эффект будет заметен, то можно первое преобразование запускать вхолостую, а потом серию измерительных. |
Автор: | Ivanoff-iv [ Пт сен 01, 2023 12:09:19 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
не, он шумы во благо использует - для повышения разрядности оцифровки. а вот про холостой первый замер - инфа стоящая! |
Автор: | kote52 [ Пт сен 01, 2023 12:21:58 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
Предделитель побольше поставь, меньше шумов будет и отпадёт необходимость в таком большом буфере. А ещё при переключении каналов есть такой прикол, что УВХ-то там одно и каналы могут друг на друга влиять. Если этот эффект будет заметен, то можно первое преобразование запускать вхолостую, а потом серию измерительных. Как это сделать если ты по очередно замеры делаешь, adc0 потом adc1 потом adc2... По два замера, и откидывать первый? Тогда в двое время увеличится на все замеры. |
Автор: | Ivanoff-iv [ Пт сен 01, 2023 12:30:01 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
так ТС 250 делает... ну будет делать 251... Добавлено after 1 minute 1 second: зато задержку между переключением входа и измерением можно будет убрать... |
Автор: | Starichok51 [ Пт сен 01, 2023 12:43:07 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
задержку между переключением входа и измерением нет смысла делать, так как само переключение входа еще не означает, что вход подключился к УВХ. к УВХ вход подключается непосредственно в начале измерения. |
Автор: | kote52 [ Пт сен 01, 2023 12:46:59 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
так ТС 250 делает... ну будет делать 251... Если так тож сделаю для эксперимента |
Автор: | >TEHb< [ Пт сен 01, 2023 14:45:17 ] |
Заголовок сообщения: | Re: АЦП-Atmega 8 |
kote52 писал(а): если ты по очередно замеры делаешь, 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 Вольт for(uint8_t i=0; i<ADCFLUSHCOUNT; i++) { ADCSRA|=0b01000000; //запуск для обновления УВХ while(ADCSRA&0b01000000){}; }; for(uint8_t i=0; i<count;i++){ ADCSRA|=0b01000000; //запуск перобразования while(ADCSRA&0b01000000){}; //ожидание окончания преобразования result+=ADCW; }; return result; }; |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |