gogaze Опубликовано 24 сентября, 2020 Поделиться Опубликовано 24 сентября, 2020 (изменено) Программа-счетчик ампер-часов Скрытый текст . #define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include "lcd.h" #define FIRST_ADC_INPUT 0 #define LAST_ADC_INPUT 2 #define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR)) uint32_t adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; volatile uint32_t ach, volt, tok, ah=0; //Переменная для ампер-часов, вольт, ампер uint8_t sek, min, hour; // переменные времени ISR (TIMER1_COMPA_vect) { TCNT1H=0; TCNT1L=0; sek++; // инкрименируем секунду ah=ah+tok; //добавляем каждую секунду значение тока } ISR (ADC_vect) { static unsigned char input_index=0; adc_data[input_index]=ADCW; // Read the AD conversion result if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) input_index=0; ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index; _delay_us(10); ADCSRA|=(1<<ADSC); // Start the AD conversion } void timer_ini (void) { TCCR1A=0x00; TCCR1B=0x05; //Режим СТС сброс по совпадению TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x1E; OCR1AL=0x85; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (1<<OCIE1A) | (0<<OCIE1B) | (1<<TOIE1) | (0<<TOIE0); } int main(void) { timer_ini(); // Настройка АЦП==================================================== // ADC initialization ADC Clock: 125,000 ADC Voltage: AVCC pin ADMUX=FIRST_ADC_INPUT | ADC_VREF_TYPE; ADCSRA=(1<<ADEN) | (1<<ADSC) | (0<<ADFR) | (0<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); SFIOR=(0<<ACME); // Настройка портов================================================= DDRB=0b00000000; // Дисплей PORTB=0b00000000; // Подключен LCD DDRC=0b0000000; //Все на вход PORTC=0b1111100; DDRD=0b10000000; //Порт на вход (bit 8 - Выход) PORTD=0b00000011; // 0 и 1 ноги - с подтяжкой //================================================================== LCDinit(); LCDclear(); sei(); // Globally enable interrupts while (1) { volt=20*adc_data[0]*100/1023; //20 вольт tok=10*adc_data[1]*100/1023; //10 ампер // Условия для часов.============================================ if(sek==60) // если сек = 60 { min++; // добавляем 1 к переменной "минута" sek=0; // обнуляем переменную "секунда" } if (min==60) // Если минуты=60 { hour++; // Добавляем 1 к переменной час min=0; // Обнуляем переменную "минута" } if (hour==24) //Если часы насчитали 24 обнуляем все переменные { hour=0; min=0; sek=0; } //============================================================== if (ach>99999) { ah= 0;} //Если ампер-часов 100 - сброс на 0 // Сброс времени if( !(PIND & (1 << PD0)) ) // Если нажали кнопку (на PORTD0 - 0) { hour=0; min=0; sek=0; } // Сброс ампер-часов if( !(PIND & (1 << PD1)) ) // Если нажали кнопку на PORTD1 { ah=0; } //=====Напряжение минимальное при разрядке FR<============================ if (volt <= 1050) // Если напряжение меньше-равно 10.50 вольт { PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) } else { // Иначе PORTD &= ~( 1 << PD7 );// Устанавливаем бит 7 порта D в 0 (светодиод не горит) } //========напряжение=========================================== LCDGotoXY(10, 1); lcd2x2_dig_to_str(volt,5); //Выводим 5 знаков с точкой ХХ.ХХ LCDGotoXY(15, 1); LCDdata('V'); //Выводим букву V //========ток================================================== LCDGotoXY(10, 0); lcd2x2_dig_to_str(tok,5); //Выводим 5 знаков с точкой ХХ.ХХ LCDdata('A'); //Выводим букву A // ======= показания часов ==================================== LCDGotoXY(0,0); lcd2x2_dig_to_str(hour,2); //Выводим 2 знака часы LCDGotoXY(2,0); LCDdata(':'); //Выводим : LCDGotoXY(3,0); lcd2x2_dig_to_str(min,2); // Выводим 2 знака минуты LCDGotoXY(5,0); LCDdata(':'); //Выводим : LCDGotoXY(6,0); lcd2x2_dig_to_str(sek,2); // Выводим 2 знака секунды // ======= счетчик ампер/часов ================================ LCDGotoXY(0,1); //ach=((ah+tok)/3600); // Пересчитываем в ампер/часы ach=((ah+tok)*10/3600); // Пересчитываем в ампер/часы lcd2x3_dig_to_str(ach,6); //Выводим 5 знаков с точкой ХХ.ХХХ LCDstringXY ("Ah", 6,1); //Выводим Ah _delay_ms(250); } } В ней условие //=====Напряжение минимальное при разрядке аккумулятора============================ if (volt <= 1050) // Если напряжение меньше-равно 10.50 вольт { PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) } else { // Иначе PORTD &= ~( 1 << PD7 );// Устанавливаем бит 7 порта D в 0 (светодиод не горит) } Как проще добавить несколько вариантов условий if (volt <= 1050) // Если напряжение меньше-равно 10.50 вольт для разных напряжений, чтобы при запуске программы можно было выбрать и задействовать нужное? Я ничего подобного раньше еще не делал, так что прошу отнестись соответственно. Изменено 24 сентября, 2020 пользователем gogaze Добавление информации 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Piotr__1 Опубликовано 24 сентября, 2020 Поделиться Опубликовано 24 сентября, 2020 13 минут назад, gogaze сказал: так что прошу отнестись соответственно. https://www.google.com/search?q=case+в+программировании 0 Жизнь не белая или чёрная, а в мелкую серенькую полосочку... Ссылка на комментарий Поделиться на другие сайты Поделиться
Реле, вентиляторы, корпуса, разъемы, а так же любые электронные компоненты в нашем каталоге! Бесплатная доставка + 15% кэшбэк + скидки!Перейти на сайт ТМ Электроникс Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
gogaze Опубликовано 24 сентября, 2020 Автор Поделиться Опубликовано 24 сентября, 2020 Попробовал сделать так: switch ( volt ) { case 1051: PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) break; case 250: PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) break; default: PORTD &= ~( 1 << PD7 );// Устанавливаем бит 7 порта D в 0 (светодиод не горит) break; } Работает, но не совсем так, как надо. Светодиод загорается только при значениях volt точно равных 10.51 и 2.50 вольт. И главное: чтобы в основной программе сделать выбор между case 1051 и case 250 ну и так далее - все равно надо делать меню??? 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
Alex Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 13 часов назад, gogaze сказал: чтобы в основной программе сделать выбор между case 1051 и case 250 ну и так далее - все равно надо делать меню??? Ещё бы понять, что Вы тут написали. "В основной программе", "Выбор между case", "меню" какое-то, .... Сформулируйте нормально вопрос. И по одному, а не всё в кучу... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке. Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 (изменено) 24 минуты назад, Alex сказал: Ещё бы понять, что Вы тут написали. В первом посте я всю задачу описал, как смог. Основная программа там же. Потом мне посоветовали заменить мое условие If - else на switch case. Я попробовал. Результат представил. Изменено 25 сентября, 2020 пользователем gogaze 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Литиевые батарейки и аккумуляторы от мирового лидера EVE в КомпэлКомпания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
солар Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 13 часов назад, gogaze сказал: только при значениях volt точно равных В кейсе и задается на соответствие заданному числу. Пробуйте так: if ((volt > N) && (volt <= K) ) 13 часов назад, gogaze сказал: сделать выбор Вариантов много. И все свалятся к тому, что сравнивать volt надо будет с переменной, а не как сейчас у вас с константой. 0 Я не раздаю удочки. Я продаю рыбу. Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 1 минуту назад, солар сказал: И все свалятся к тому, То условие, которое я показал в начале - отлично работает. Но мне нужно таких условий несколько на разные напряжения. Ну и, соответственно, чтобы при запуске программы была возможность выбрать для использования нужное. 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
ARV Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 Можно сделать, воспользовавшись расширением GCC, вот так: switch ( volt ) { case 1051 ... 1100: PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) break; case 250 ... 300: PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) break; default: PORTD &= ~( 1 << PD7 );// Устанавливаем бит 7 порта D в 0 (светодиод не горит) break; } 0 Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют... Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 @ARV 7 минут назад, ARV сказал: case 1051 ... 1100: А что, это выражение равнозначно <= 1051? 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Zhuk72 Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 (изменено) Это пример использования диапазона в switch-case. Значения диапазона и действия на них выбирайте по надобности. Изменено 25 сентября, 2020 пользователем Zhuk72 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 При исползовании case писанины много - надо писать оба предела, нижний и верхний. Я бы сделал так: if (volt <= 950) // Если напряжение меньше-равно 9.50 вольт { ..... } else if (volt <= 1050) // Если напряжение больше 9.50 и меньше-равно 10.50 вольт { ..... } else if (volt <= 1150) // Если напряжение больше 10.50 и меньше-равно 11.50 вольт { ..... } else //Если напряжение больше 11.50 { } При такой записи значения границ используются в тексте по одному разу только - проще изменять, если чё. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 (изменено) 14 минут назад, Yurkin2015 сказал: Я бы сделал так Ну и я так и сделал . Только для одного напряжения. ГЛАВНОЕ для меня - как реализовать выбор и использование нужного условия если их несколько? Делать меню? Или есть другой вариант? Изменено 25 сентября, 2020 пользователем gogaze 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 25 сентября, 2020 Поделиться Опубликовано 25 сентября, 2020 Непонятно, что надо выбирать-то? Приведите пример, что ли. Вместо 10.5 В нужно установить границу 10.7 В? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 (изменено) 12 часов назад, Yurkin2015 сказал: что надо выбирать-то? По-дилетантски объясню: 1. Запускается основная программа (счетчик ампер-часов). 2. Дальше: либо по кнопке, либо автоматически появляется меню где можно из списка выбрать и задействовать необходимое условие для минимально допустимого напряжения. 3. После выбора счетчик работает с выбранным параметром.Скриншот счетчика прилагаю на всякий случай. Скрытый текст Минимальное напряжение задано условием //=====Напряжение минимальное при разрядке аккумулятора============================ if (volt <= 1050) // Если напряжение меньше-равно 10.50 вольт { PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) } else { // Иначе PORTD &= ~( 1 << PD7 ); // Устанавливаем бит 7 порта D в 0 (светодиод не горит) } Изменено 25 сентября, 2020 пользователем gogaze 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 25 сентября, 2020 Автор Поделиться Опубликовано 25 сентября, 2020 (изменено) 13 часов назад, Yurkin2015 сказал: Вместо 10.5 В нужно установить границу 10.7 В? Условий, типа этого //=====Напряжение минимальное при разрядке аккумулятора============================ if (volt <= 1050) // Если напряжение меньше-равно 10.50 вольт { PORTD |= (1<<PD7); // Устанавливаем бит 7 порта D в 1 (светодиод горит) } else { PORTD &= ~( 1 << PD7 ); // Устанавливаем бит 7 порта D в 0 (светодиод не горит) } нужно несколько. Здесь на 10.5 вольта, такое же добавить на 3.0 вольта ..... и так далее. Вот из них и выбирать нужное при запуске программы. Изменено 25 сентября, 2020 пользователем gogaze Добавление информации 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Starichok Опубликовано 26 сентября, 2020 Поделиться Опубликовано 26 сентября, 2020 9 часов назад, gogaze сказал: 2. Дальше: либо по кнопке, либо автоматически появляется меню где можно из списка выбрать и задействовать необходимое условие для минимально допустимого напряжения. ну, так делай такой список. а в условии будешь проверять переменную, в которую запишется число выбранной уставки. 0 Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду. Ссылка на комментарий Поделиться на другие сайты Поделиться
Zhuk72 Опубликовано 26 сентября, 2020 Поделиться Опубликовано 26 сентября, 2020 "else if" никогда не использовали? if(volt <= 5) func_5(); else if(volt <= 10) func_10(); else if(volt <= 20) func_20(); else if(volt <= 30) func_30(); ... else func_n(); Можно и диапазон проверять: if((volt > 3) && (volt <= 10)) func_x(); else if((volt > 10) && (volt <= 20)) func_y(); ... else func_z(); Выбирайте. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 2 октября, 2020 Автор Поделиться Опубликовано 2 октября, 2020 (изменено) Я так понял, что надо все-таки делать меню. Нашел в сети вариант, https://scienceprog.com/how-to-write-an-lcd-menu-for-avr-in-c/ немного доработал для своих нужд. Вроде неплохо получилось. Осталось самое главное - добавить в меню код моего счетчика. Поделитесь ссылкой или советом по этому вопросу, пожалуйста!!! На данный момент кое-что нашел в книге А.В. Белова "Микроконтроллеры AVR в радиолюбительской практике". Листинг меню и модель в Протеусе в архиве. MENU.rar Изменено 2 октября, 2020 пользователем gogaze 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 6 октября, 2020 Автор Поделиться Опубликовано 6 октября, 2020 (изменено) Можно вопрос считать решенным. Запускаем, выбираем в меню нужный вариант. По достижении минимально допустимого напряжения разряда срабатывает сигнализация. Варианты - от светодиода до полицейской "крякалки" или реле отключения. Скрытый текст Изменено 6 октября, 2020 пользователем gogaze Фото под спойлер 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Электронщик Опубликовано 12 ноября, 2020 Поделиться Опубликовано 12 ноября, 2020 26.09.2020 в 01:58, gogaze сказал: 25.09.2020 в 12:56, Yurkin2015 сказал: Вместо 10.5 В нужно установить границу 10.7 В? ну так вместо числа название переменной пиши, потом switch загони в функцию(если тебе будет удобнее вызывать функцию, нежели постоянно прописывать switch в проге. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
gogaze Опубликовано 14 ноября, 2020 Автор Поделиться Опубликовано 14 ноября, 2020 13.11.2020 в 05:07, Электронщик сказал: ну так вместо числа название переменной пиши, потом switch загони в функцию(если тебе будет удобнее вызывать функцию, нежели постоянно прописывать switch в проге. Спасибо, что до сих пор пытаетесь помочь! Но я уже, как сумел, сделал через меню, собрал прибор, опробовал на Li-ion аккумуляторе. Результатом остался доволен. Только к сигнализации на светодиоде надо все-таки приплюсовать какую-нибудь "пищалку". 0 Мир не без добрых людей! Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.