Самсусамыч, ну и кто в твоем хексе увидит твой алгоритм?
Я пишу программы не для демонстрации своего алгоритма. Так как не являюсь виртуозом в данном направлении (даже в ближайшем приближении). Это пусть профессионалы демонстрируют меж собой свои умения. Для меня главное, чтобы программа корректно работала в железе как ранее задумано. А как это написано не столь важно. Да и исходники написанные в АВ мало кому помогут понять что в алгоритме реализовано. Или Вы забыли, что я пишу исключительно на АВ (Algorithm Builder) и другими языками программирования не владею? Ранее Вы с лёгкостью дизассемблировали мой код, а что случилось в этот раз? Стало лениво? При Ваших знаниях и умениях, Вам-то он зачем? Ткнуть меня носом, где я делаю что-то не так глядя с Вашей колокольни? Так я Вам сразу скажу, я много чего делаю не так… главное алгоритм работает в железе как тому требуется. И только этот факт мне приносит удовольствие.
Что касается макета… кому интересно, тот соберёт в железе или в протеусе… а кому не интересно, то о чём тогда разговор…
Ну а для АВ_шников то вот исходник крайней версии прошивки. Только тапками не закидывайте...
NStorm, выше уже писал. Когда то и я учился на подобных обсуждениях. И также же как ТС, задам вопрос, мэтры подтягиваются и началось. Так тема живёт своей жизнью. На данный момент ничего плохого не происходит. Скажете, создадим новую тему. Есть но, новый топик будет не жизнеспособен. Потому что нужны конкретные примеры. В данной теме он есть. Есть ТЗ от ТС, и уже есть примеры.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Ivanoff-iv, аплодирую стоя! Даже не спрашиваю , как до этого дошёл. Сколько смотрел роликов и от камрада libral1973 , и в книгах Лебедева и Белова -- близко похожего не было, чтобы хоть как-то оттолкнуться или провести аналогию. Так что , " кирпичик для лего " получен и будет заложен. P.S. Во истину, сколько людей -- столько и мнений, и каждый прав, и мнение каждого имеет место быть. ВСЕМ СПАСИБО! Берегите себя и всех близких.
Рад, что кому-то мой метод понравился, а, т.к. возможно теперь его применять буду не я один, то должен выложить не только преимущества, но и обнаруженные нюансы метода: 1) используемые в потоках переменные (все, которые должны пережить паузу (а точнее перезапуск) потока) должны быть глобальными или статик. 2) кодевижен не очень хорошо разделяет области видимости переменных - имена переменных в разных потоках не должны быть одинаковыми (это не косяк метода, это косяк кодевижена). 3) внутри цикла for паузу поставить не получилось (пока не знаю почему), но for можно заменить на while, там всё работает. 4) не выйдет поставить задержку внутри функции, вызываемой из потока. Объявить поток в потоке, или в вызываемой из потока функции теоретически можно, но работать оно будет непредсказуемо. (т.к. чтобы правильно работали задержки в потоке поток должен вызываться регулярно, а поток внутри потока уже не будет вызываться регулярно) 5) семафоров и прочего тут нет, взаимодействие между потоками осуществляется через общие переменные. в т.ч. и приостановка потока - делается цикл с задержкой, условие цикла меняется извне потока. 6) метод проверен в кодевижене и в алгоритм билдере, в других средах не проверялся... как проверю отпишусь.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Посмотрел ваши примеры, обсуждение. ТС по ТЗ так и не отписался. Как быть в той ситуации, когда нажаты несколько кнопок. Предлагаю ТС-у все таки расколоться и пояснить как должны работать все кнопки на его устройстве. А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.
А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.
А если нажать, то что будет?
У меня два варианта на любой вкус… в первом можно нажимать любое количество кнопок в группе и они будут отрабатывать. Во втором варианте можно тоже нажимать любое количество кнопок в группе, но отработает только первая нажатая в группе, остальные в группе будут игнорироваться.
А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.
А я все нажму, это не соревнование, есть ТЗ, делайте, или не делайте.
Ivanoff-iv, глянул я ваш код, это гораздо проще, чем у Demiurg, собирается вот в такоеСпойлер
Код:
StartPotok(key_trigg); { static unsigned int key_trigg_EscapeIteration=1; static unsigned char key_trigg_StepOfPotok=0;
if (key_trigg_EscapeIteration) { (key_trigg_EscapeIteration)--; if ((key_trigg_EscapeIteration)==0) { switch (key_trigg_StepOfPotok) { case 0: (key_trigg_EscapeIteration)=0 if(!PINC.2) //проверка { //задержка 10 ms (номера могут быть не по порядку, главное, чтоб не повторялись и были от 1 до 255) key_trigg_StepOfPotok=3; key_trigg_EscapeIteration=(10)+1; goto key_trigg_End; case(3): (key_trigg_EscapeIteration)=0 if(!PINC.2) //повторная проверка { PINC.0=1; // переключение d9 (записью 1 в регистр PIN производится переключение 1->0 0->1 порта) do { key_trigg_StepOfPotok=1; key_trigg_EscapeIteration=(0)+1; goto key_trigg_End; case(1): (key_trigg_EscapeIteration)=0 }while (!PINC.2);//ждём отпускания }; } default: key_trigg_EscapeIteration=(tim)+1; key_trigg_StepOfPotok=0;
key_trigg_End: }; }; }; }
StartPotok(largeoperation); { static unsigned int largeoperation_EscapeIteration=1; static unsigned char largeoperation_StepOfPotok=0;
if (largeoperation_EscapeIteration) { (largeoperation_EscapeIteration)--; if ((largeoperation_EscapeIteration)==0) { switch (largeoperation_StepOfPotok) { case 0: (largeoperation_EscapeIteration)=0 PORTC.4=1; //мигаем желтым светодиодом D13 _delay_ms(300); //вот он - зависон (не знаю, какими вычислениями занять, поэтому просто делай) PORTC.4=0; largeoperation_StepOfPotok=1; largeoperation_EscapeIteration=(300)+1; goto largeoperation_End; case(1): (largeoperation_EscapeIteration)=0
а благодаря #asm("sei") в прерывании - разрешены вложенные прерывания, у вас на блокировке входа основано, иначе бы стек адресами возврата бы переполнился.
Да, всё так. раньше для выхода из потока была команда brake; но если пауза стояла в цикле, то брейк выходил из цикла, а не из потока... пришлось добавить метку.
Добавлено after 2 minutes 44 seconds: Dimon456, а чем ты дефайны развернул? и в какой ИДЕ?
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Demiurg, в моём проекте несколько нажатых кнопок не рассматривалось за ненужностью. Генератор ЗЧ, одна группа из 4-ёх кнопок -- выбор диапазона, другая -- делитель, коммутация -- реле Panasonic TX212 , разумеется, с ключами. Группы между собой независимы, одновременное нажатие в разных группах ничего особенного не даст, только штатное включение в каждой группе. А в пределах одной группы -- так сверх-одновременно не получится, с опозданием хоть на микросекунду последняя кнопка и сработает. По сути -- кнопка-защёлка, без антидребезга . 9-ая кнопка -- режим МЕАНДР. Моргунчик для большей наглядности, знать бы , что так архи-сложно -- можно было и не делать
Sergbern, можно реализовать отработку множественного нажатия кнопок по разному: 1) "по старшинству" - кнопка с большим приоритетом отменяет действие кнопок с меньшим (так у тебя сделано) 2) "первая" - отрабатывается только первая нажатая кнопка,(легко сделать, организовав 2 потока (по потоку на каждую группу кнопок) и по маленькому циклу внутри потока - для каждой кнопки. В зависимости от условия цикла остальные кнопки могут блокироваться либо до отпускания этой кнопки (1 группа) или до отпускания всех кнопок группы (2я группа))Спойлер
Код:
///////// 1-я группа кнопок StartPotok(Group1); while (!PIND.0) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0; Delay_t(Group1,1,0);}; while (!PIND.1) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0; Delay_t(Group1,2,0);}; while (!PIND.2) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0; Delay_t(Group1,3,0);}; while (!PIND.3) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0; Delay_t(Group1,4,0);}; EndPotok(Group1); ///////// 2-ая группа кнопок StartPotok(Group2); if (!PIND.4) {PORTB.4=1; PORTB.5=0; PORTB.6=0; PORTB.7=0;}; if (!PIND.5) {PORTB.5=1; PORTB.6=0; PORTB.7=0; PORTB.4=0;}; if (!PIND.6) {PORTB.6=1; PORTB.4=0; PORTB.5=0; PORTB.7=0;}; if (!PIND.7) {PORTB.7=1; PORTB.4=0; PORTB.5=0; PORTB.6=0;}; while ((~PIND)&0b11110000){Delay_t(Group2,1,0);}; EndPotok(Group2);
3) "последняя" - тут нужно добавить переменную состояния кнопок на прошлом витке, находить изменения состояния кнопок и по ним зажигать светодиоды.Спойлер
Код:
char Key=~PIND; //сразу инвертировал чтоб 1 соответствовала нажатой кнопке static char OldKey=0; if ((1<<0)&(Key)&(~OldKey)) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0;}; if ((1<<1)&(Key)&(~OldKey)) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0;}; if ((1<<2)&(Key)&(~OldKey)) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0;}; if ((1<<3)&(Key)&(~OldKey)) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0;}; OldKey=Key;//запомнили уже нажатые кнопки
можно нахождение разницы "вынести за скобки"
Код:
char Key=~PIND; //сразу инвертировал чтоб 1 соответствовала нажатой кнопке static char OldKey=0; char NewKey=Key&~OldKey; if ((1<<0)&(NewKey)) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0;}; if ((1<<1)&(NewKey)) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0;}; if ((1<<2)&(NewKey)) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0;}; if ((1<<3)&(NewKey)) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0;}; OldKey=Key;//запомнили уже нажатые кнопки
присоединяюсь к вопросу о генераторе: нужно ли его в этот мк добавить?
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
У ТС три группы кнопок. Все независимые. Диапазон. Уровень сигнала. Меандр. Получается, что у первых двух групп в рамках группы одновременное нажатие кнопок недопустимо. А одновременное нажатие трех групп допустимо. А это меняет всю картину... Я недаром просил ТЗ с самого начала.
include <tiny13a.h> #define K_speed 30 #define MIN 1 #define MAX 40000 #define Butt (~PINB&(1<<0)) #define Out() (PINB=(1<<4)) //переключение ножки unsigned int Frq=10; //текущая частота eeprom unsigned int E_Frq; //запомненная частота unsigned int Tim=1000; //период unsigned char Ost=0xff; //остаток
void Calc(void) //вычисляем период и довесок { unsigned long int tTim=12000000/Frq; //вычисляем период unsigned char tOst=tTim; //последний байт (до256) tOst>>=1; //делим на 2 tOst|=0x80; //прибавим 128 (вычисляем довесок) //у нас 2 довеска - сумма их как-раз и получится 1 полный оборот и остаток (но их пришлось делить на 2 т.к. трудно обработать 2 близко стоящих прерывания) tTim>>=8; //делим период на 256 #asm("cli") Tim=tTim; //выводим в буфера Ost=tOst; #asm("sei") };
// Timer 0 output compare A interrupt service routine interrupt [TIM0_COMPA] void timer0_compa_isr(void) { static unsigned int countS=0; //счетчик периодов таймера для работы static unsigned char ReductK=0; //счетчик периодов таймера для опроса кнопки (делитель) static unsigned char K_tim=0; //время нажатия кнопки static unsigned char K_count=0; //количество нажатий кнопки
PORTB.5=1; //машем лапкой, обозначающей работу АЛУ (загрузка ЦП) if (countS) {countS--;} else { countS=Tim; //взводим таймер обратно Out(); //работаем работу }; OCR0A=(countS<2)? Ost:0xff; //выбираем скорость таймера //if (SPL>0x9C) //проверял срыв стека... { //обрабатываем нажатие кнопки #asm("sei") //это для того, чтобы основная работа продолжалась ReductK++; //переменная сбрасывается по переполнению if (ReductK==0) { if (K_tim) { K_tim++; if (K_tim>K_speed) { if Butt { K_tim=K_speed; if (K_count==2) Frq=(Frq>MIN)? Frq-1:MIN; //кнопка удерживается - убавляем скорость if (K_count==4) Frq=(Frq<MAX)? Frq+1:MAX; //нажата 1 раз и удерживается - добавляем скорость if (K_count>=6) if (E_Frq!=Frq) E_Frq=Frq; //нажата 3 раза (или более) - обновляем сохраненную скорость Calc(); //возможно скорость изменилась - пересчитаем периоды } else{K_tim=0;}; //если кнопка уже отпущена - сбросим и остановим таймер } else { if Butt {if ((K_count&1)==1) K_count++;} //приращаем счет при каждом нажатии и отпускании кнопки else {if ((K_count&1)==0) K_count++;}; }; } else{if Butt K_tim++; K_count=1;}; //если кнопка нажата впервые - запускаем её таймер и устанавливаем счет }; }; }
// Declare your global variables here
void main(void) { // Declare your local variables here
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: pasha71 и гости: 39
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения