Товарищи, нужна ваша помощь. Уже второй день бьюсь над проблемой Вобщем устройство - кнопка старт\стоп для двигателя. Алгоритм -один раз нажали включилось ACC -второй раз включилось зажигание -третий раз всё выключилось -если на любом этапе и нажат сцеплеие то включается стартер
Так вот никак невыходит описать алгоритм включения кнопки. Нужно как то переводить состояние кнопки из одного в другое. Кнопка если первое нажатие отрабатывает нормально, то дальше второе может не отработать, а может отработать и на этом остановиться. Кнопка подключена к выводу PINB.0 . Когда она нажата - у нас логический ноль.
Товарищи, может поможете новичку с кодом, а то уже аж руки опускаются....
Project : Version : Date : 20.07.2012 Author : Company : Comments:
Chip type : ATmega8 Program type : Application AVR Core Clock frequency: 4,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/
#include <mega8.h>
#include <delay.h>
// Timer1 output compare A interrupt service routine interrupt [TIM1_COMPA] void timer1_compa_isr(void) { // Place your code here
}
#define ADC_VREF_TYPE 0x40
// ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { unsigned int adc_data; // Read the AD conversion result adc_data=ADCW; // Place your code here
}
// Declare your global variables here int time; // переменная для отсчёта времени unsigned char OFF; unsigned char ACC; unsigned char ING; unsigned char STARTER; unsigned char status; unsigned char rejim_avtomat; // Состояние режима запуска авто unsigned char rejim_ruchnoy; // Сосстояние режима запуска авто void _OFF (void) { PIND.0=0; PIND.1=0; PIND.2=0; }
1 - организуем переменную - счетчик нажатий кнопки; 2 - при первом нажатии проверяем счетчик, если он равен "0", то инкрементируем счетчик, ставим ловушку, если кнопка нажата, то возвращаемся на опрос состояния кнопки, если кнопка отжата, то проскакиваем ловушку, и после ловушки выдерживаем некоторую паузу, чтобы исключить дребезг, проверяем счетчик, если "1", то выполняем необходимые действия для включения АСС; 3 - при втором нажатии проверяем счетчик, если он равен "1", то инкрементируем счетчик, ... , проверяем счетчик, если "2", то выполняем необходимые действия для включения зажигания; 4 - при третьем нажатии проверяем счетчик, если он равен "2", то инкрементируем счетчик, ... , проверяем счетчик, если "3", то выполняем необходимые действия для выключения питания, обнуляем счетчик; и т.д.
На счет сцепления не понятно, что значит на любом этапе? а если на скорости стоит? нужно тогда отслеживать и сцепление и нейтраль. Можно, конечно в этой же переменной включать бит - флаг нажатого сцепления, и проверять нажатие кнопки маскируя этот бит.
Тогда проверять флаг выжатого сцепления при счетчике равном "2", т.е. когда кнопка нажата второй раз, в этот момент и проверять сцепление, в других случаях наверно не стоит.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
вот пытался написать, но так вообще ничего не выходит Я и понимаю что алгоритм простой, но что то ну никак невыходит он у меня
Код:
// Global enable interrupts #asm("sei") while (1) { if (PINB.0==0) // если нажата кновпка { if (status==0) // проверяем в каком положении наш счётчик { status++; // инкрементируем статус в первое положение if (PINB.0==0) // проверяем, если кнопка до сих пор нажата { while (PINB.0==0) //заходим в замкнутый цикл { }
} else // иначе, если кнопка выходит что отжата { if (status==1) // проверяем статус,если равен 1 { _ACC(); // включаем acc } }
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Вот ещё один вариант попробовал написать. Но в протеусе видно что нажал раз на кнопку, на выводе начинается моргание (вывод как всетомузыка работает)
и дальше сколько не нажимай - ничего не происходит. Где я ошибаюсь???
Код:
// Global enable interrupts #asm("sei") while (1) { if (PINB.0==0) // если нажата кновпка { delay_ms(100); if (PINB.0==0) // если нажата кновпка { if (status==0) // проверяем в каком положении наш счётчик { status=+1; // инкрементируем статус в первое положение while (PINB.0==0) {} //ждём отжатия кнопки } else if (status==1) // проверяем в каком положении наш счётчик { status=+1; // инкрементируем статус в первое положение while (PINB.0==0) {} //ждём отжатия кнопки } else if (status==2) // проверяем в каком положении наш счётчик { status=+1; // инкрементируем статус в первое положение while (PINB.0==0) {} //ждём отжатия кнопки } else if (status==3) // проверяем в каком положении наш счётчик { status=0; // инкрементируем статус в первое положение while (PINB.0==0) {} //ждём отжатия кнопки } }
} if (status==0) { _OFF(); } else if (status==1) { _ACC(); } else if (status==2) { _IGN(); } else if (status==3) { _STARTER(); } } }
Думаю, лучше убрать первую проверку счетчика, а просто тупо его увеличивать, а потом когда он будет "3" обнулить его. Както вот так должно быть, синтаксис исправь если чё, просто на си не пишу, поэтому примерно накидал.
Код:
// Global enable interrupts #asm("sei") while (1) { if (PINB.0==0) // если нажата кновпка {status++; if (PINB.0==0) // проверяем, если кнопка до сих пор нажата {while (PINB.0==0){}} //заходим в замкнутый цикл else // иначе, если кнопка выходит что отжата {if (status==1){_ACC();}} // проверяем статус,если равен 1 {if (status==2){_IGN();}} // проверяем статус,если равен 2 {if (status==3){_OFF(); status==0;}} // проверяем статус,если равен 3 } }
Проверка статуса должна происходить только когда нажимаем кнопку, а не все время проверяться в цикле, и задержку небольшую надо поставить после else, когда кнопка отжата. В основном цикле можно по этому статусу определять в каком режиме находишься ACC, IGN или OFF, если это необходимо.
Вот поправил немного и добавил сброс счётчика если он больше 3. Всё как бы отрабатывает но с глюками страшнейшими. Кнопка сначала включается, потом через раз потом чёрт зна что и с 10 го нажатия выключает всё таки всё.
Мне кажется это из за присвоения статусу признаков зажигания и т.д во время нажатой кнопки. Скорей всего наверное это нужно выносить в отдельное место.
вот приложил ещё прект в протеусе.
Код:
// Global enable interrupts #asm("sei") while (1) { if (PINB.0==0) // если нажата кновпка { status++; if (status >3) //проверяем, если status больше 3, то присваиваем ему 0 (кнопка ывключена) {status=0;} if (PINB.0==0) // проверяем, если кнопка до сих пор нажата {while (PINB.0==0){}} //заходим в замкнутый цикл else // иначе, если кнопка выходит что отжата delay_ms(200); {if (status==0){_OFF();}} // проверяем статус,если равен 0 {if (status==1){_ACC();}} // проверяем статус,если равен 1 {if (status==2){_IGN();}} // проверяем статус,если равен 2 {if (status==3){_STARTER();}} // проверяем статус,если равен 3 }
Эврика , только что перелистывал учебник по АВР и тут пришла идейка По кнопке, теперь она отрабатывает как нужно. Теперь главное чтоб ничего не начало мешать в написании алгоритмов работы от концевиков лампы АКБ и концевика педали сцепления.
Код:
#asm("sei") while (1) { if (PINB.0==0) // если нажата кновпка { status++; if (status >3) //проверяем, если status больше 3, то присваиваем ему 0 (кнопка ывключена) {status=0;} if (PINB.0==0) // проверяем, если кнопка до сих пор нажата {while (PINB.0==0){}} //заходим в замкнутый цикл else {} // иначе, если кнопка выходит что отжата
}
switch (status) //Положение OFF { case 0: PORTD.0=0; PORTD.1=0; PORTD.2=0; PORTD.3=0;
Получается функция switch постоянно в цикле проверяет состояние status, так чтоли? Надо, чтобы она вызывалась только при нажатии кнопки, а то как-то очень хорошо получается, и тогда она мешать ничему не будет.
товарищи. перешёл к ещё одному элементу. Я то его сделал но может подскажете как его можно упростить. Чтоб контроллеру меньше вычислять.
Просто незнаю как в течении трёх секунд, во время кручения стартера, чтоб при погасании лампы зарядки АКБ или блокировки стартера он отключался. Как его опрашивать эти три секунды не нагружая его процик...
Код:
if (ruchnoy==0) //если мы бытро нажали и бросили кнопку то переходм автоматический режим {
status=3; //включаем стартер delay_ms(100);//ждём 100 милисекунд if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} проверяем состояние лампы АКБ и стартера if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} if((PINB.4==1)||(PINB.5==0)){status=2;engine=1;}else{delay_ms(100);} status=2; //двигатель завёлся и оставляем включеным зажигание engine=1; ruchnoy=0; } else { status=2; //двигатель у нас уже выходит запущен, и стратер нельзя запускать engine=1; //мы не даём ему запуститься и оставляем просто включеное зажигание } //, и присваем признак заведённого мотора
Я бы подключил для этого дела таймер, и пускай он отсчитывает 3 секунды, а лампу зарядки АКБ повесил бы на внешнее прерывание со срабатыванием по переднему фронту, т.е. с "0" на "1", при погасании лампы зарядки, по-моему, на нее со стороны минуса приходит +12, по-этому думаю по переднему фронту, и процик вобще не в напряге.
Использовать можно любой таймер, даже 8 битный, разрешаем прерывания по переполнению этого таймера, прескалер можно вообще вручную написать, используя переменные как счетчики. Например частота 8 МГц, получается: устанавливаем прескалер для таймера = 256, в обработчике прерывания таймера устанавливаем счетчик таймера TCNTx = 6, одну переменную используем как старший разряд счетчика и будем её увеличивать до 125, так получим 1 секунду, итого получим: 8000000 / 256 / (256-6) / 125 = 1 секунда, вторую переменную используем как счетчик секунд и увеличиваем её до 3, получим 3 секунды.
Да... тяжело быть программистом.. Я ещё в таймерах и прерываниях несовсем разобрался. И ещё вопросик, мой код, он работает. Но вот в этот момент когда он будет выполняться он несильно перегрузит атмегу?
Может лучше тогда цикл организовать типа for, зачем столько одинаковых строк делать? Процик не перегрузится, в любом случае, он постоянно чтото выполняет, если не в спящем режиме.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения