Страница 4 из 13
Re: Как поместить цикл в case оператора switch
Добавлено: Пт окт 07, 2022 18:44:21
MLX90640
Что-то у вас кажется сломалось в потоке слов

Может, вам требуется переинициализация и перезагрузка?

Нет, если вы изобрели свой лисапэд, вам никто не запрещает его использовать. Только не надо его навязывать остальным. Остальные и сами знают, как что делать. Никто не обязан разделять ваш образ мЫшления. Быть может, это как раз вы застряли в своих шаблонах, а не весь прогрессивный мир. Так то.
Ну а тестирование работы - это ну "альфа и омега" всего процесса разработки. Как же вы выпускаете что-то без тестирования. Это крайне опасно и вредно, в общем-то. Так нельзя. Плохой шаблон. Тестировать надо.
Re: Как поместить цикл в case оператора switch
Добавлено: Пт окт 07, 2022 18:52:16
Demiurg
Del
Re: Как поместить цикл в case оператора switch
Добавлено: Пт окт 07, 2022 18:55:17
BOB51
У моей "игрушки" гораздо проще - один модуль периодического захвата сигналов с контрольных входов с выявлением стабильной за два временных интервала сканирования комбинаций и последующее исполнение функции из массива указателей в ОЗУ.
И никаких switch case... - места в ПЗУ заметно поменьше, а вариантов - больше.
Хотя там ранее было и через switch case решение.

А спорщики снова от темы во флуд удалились - нет смысла спорить о разных вариантах восприятия одного и того же явления. Достаточно предложить свои варианты решений.

Re: Как поместить цикл в case оператора switch
Добавлено: Пт окт 07, 2022 19:03:02
MLX90640
Вызов функций по указателям из таблицы - это хороший табличный метод реализации ветвлений. Особенно хорошо работает в менюшках пользовательского интерфейса. Потому что чем больше различных вариантов в различных состояниях, тем длиннее, запутаннее и трудноредактируемее получается текст с использованием switch-case.
Вот тоже, топикстартеру на заметку - поинтересоваться и изучить указатели на функции и попробовать изпользовать индексированный массив этих указателей для выбора действий.
Re: Как поместить цикл в case оператора switch
Добавлено: Пт окт 07, 2022 21:13:31
uuu000
похоже файл main.c потерялся в архиве temp2.zip
прикрепляю его еще раз
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 06:49:07
Demiurg
Пардон. Вчера, ммм, усталь...
Добавлено after 2 hours 9 minutes 51 second:
Затравка.
Изначально этот материал задумывался как нечто более серьезное. Но, в силу обстоятельств, серьезная часть откладывается, этот материал излагаю в качестве практикума. Хотелось бы сразу обзначить рамки практикума. В задачу практикума не входит всеобъемлюще раскрывать некоторые темы, на которые написана масса статей, книг. Эти темы будут упомянуты, не более. Предполагается, что читатель практикума будет искать информацию самостоятельно.Темы: правила хорошего тона в программировании, эффективное программирование, алгоритмы, структуры и так далее.
В большинстве случаев изучение, освоение микроконтроллеров и программирования идет примерно по следующему сценарию: поэтапное изучение архитектуры, периферии МК, создание пробных проектов, которые, как правило, однозадачны и выполняют строго определенные функции. Постепенно возрастают требования к проектируемым устройствам, соответственно, возрастает сложность алгоритмов, программ. На этом этапе начинающие сталкиваются сразу с несколькими важными проблемами. Нет устоявшегося стиля программирования, нет никакого представления об организации программ, взаимодействии и параллельной работе программных модулей.
Итог:
а) Трудночитаемый код, который трудно поддерживать и вносить какие-либо изменения.
б) Так как аппаратных таймеров мало, обычно это один, два таймера, это сбивает начинающих с толку, в случае, если требуется отслеживать несколько временных параметров.
в) Есть наработки, простые однозадачные программы, проекты. Но нет ни малейшего представления, как все это свести в один проект, добиться взаимодействия и параллельной работы программных модулей.
В этом материале я хочу показать набор некоторых правил и подход, который решает перечисленные проблемы. Облегчает разработку электронных устройств, при этом в разы сокращает временные затраты на создание проектов, по сравнению с устоявшимися подходами.
Предлагаю вашему вниманию автоматное программирование. Если вы попробуете посмотреть в интернете, что это такое, то на вас обрушится огромная лавина информации. Пусть это вас не пугает. Попробую объснить простыми словами. Автоматное программирование - это подход в программировани, при котором программа или программные модули рассматриваются как модель автомата, поведение которого анализируется и прогнозируется исходя из его СОСТОЯНИЙ. Количество состояний конечно. Отсюда термин - конечные автоматы.
В свое время, еще когда я только начинал трудиться на ниве промышленной электроники, один мой коллега, тогда мой непосредственный руководитель, в одном из наших диалогов сказал следующее: наша профессия — это ремесло. Помню, тогда я с ним горячо поспорил, утверждал, что наша деятельность — это творчество, и был в этом твердо уверен. Спустя несколько лет я убедился, что он был прав. Элемент творчества в нашей профессии, деятельности, конечно же, присутствует. Но он жестко подчиняется определенным принципам. И так как наша деятельность касается электроники, то это самая настоящая инженерная работа. Проектирование. Создание электронных устройств, приборов, блоков управления. Инженерная работа — это определенный склад ума, мышление. Если вы решили заниматься электроникой, то закладывать фундамент такого мышления нужно прямо сейчас.
Поэтому, с этого момента любое устройство, будь это простейшая мигалка или блок управления станком начинается с проектирования и считается проектом. Также это касается и программирования. Любая программа — это проект и также подчиняется законам проектирования. Залог успешности создания любого проекта — применение определенных принципов, подходов, жесткое соблюдение правил.
На тему программирования написано очень много статей, книг. В задачу практикума это не входит, поэтому предполагается, что вы должны самостоятельно искать материалы.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 06:56:26
MLX90640
[uquote="uuu000",url="/forum/viewtopic.php?p=4301262#p4301262"]похоже файл main.c потерялся в архиве temp2.zip
прикрепляю его еще раз[/uquote]
Да, в прошлый раз я его не обнаружил.
Ну в принципе то неплохо. Разве что КА в англоязычной лит-ре зовется FSM (finite-state machine). Ну и сама проблема происходит из-за того, что есть три не связанных между собой КА, а нужно сделать один.
Demiurg, facepalm... чтобы "учить" автоматному проектированию, неплохо, чтобы "учитель" отличал КА от комбинаторной логики

Так ведь? Ну. Вы можете составить графы переходов КА? А разбираетесь в математике множеств? Можете составить МДКА? А знаете, чем отличается ДКА от НКА и как привести один к другому? Ну а чему вы тут "учить" собрались то? Тому, как поставить инициализацию через switch?

switch-case "технология" не является КА-технологией. Ну что вы, это шаблонный рамочный подход. КА - широко применяется в разборе входных последовательностей, типа парсинга текста или поиска заданных последовательностей.
Ох, кажись, щас этот "учитель" накуевертит такой хни, что уши на лоб полезут

Будет второй Корабельников. А он то уж знал толк в извращениях.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 07:16:04
Demiurg
Del
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 07:20:46
MLX90640
Это ваше личное эмоциональное мнение, основанное на ваших собственных рамочных шаблонах. Почему вы вдруг решили, что ваш "метод" - единственно верный? Нет, напротив, вариант с инициализацией через switch - это жесть, просто ужос. Ваш шаблон неконструктивен.
И тем более, как же вы обходитесь без тестирования того, чего написали? Это контрпродуктивно.
Вобщем, кажись у господина произошел разрыв шаблона от того, что кто-то не согласен с его "методой"

Ну чтож, бывает, бывает. Виноваты плохие "учителя", типа Корабельникова.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 07:32:53
Demiurg
Это не мое эмоциональное мнение. Я всегда рассматриваю мнения на предмет эмоций, предпочтений, и так далее. Сужу сугубо с точки зрения целесообразности. В ваших последних сообщениях я не увидел ни грамма целесообразности. Только эмоции и самомнение
Просплюсь. Отвечу.

))
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 07:45:07
MLX90640
Да, лучше проспитесь вначале. А то вы вчера такого "эмоционального" наотвечали, что сегодня аж со стыда побежали удалять вчерашние излияния, а то кто бы увидел - закидали тапками и засмеяли бы за такую ересь

Мне то пофик, а вы свои нервы тратите

не, ну если вы и вправду такой "спицыолистъ", то аж страшно становится от таких "учитилей" и "шаблонов". Кажись, вы просто неверно информированы были, вот неверно и понимаете.
Ну а по поводу целесообразности - вы так и не объяснили, какая была целесообразность ставить через switch инит входв-выходов в ту же функцию, которая дешифрует коды кнопок. Это нецелесообразно, неверный шаблон, у вас неверно информировали не очень грамотные учителя.
Нет никакой целесообразности тратить переменную на однократное переключение между инитом и нормальной работой, поскольку эта последовательность закладывается уже в порядке написания самой программы. Доводы о том, что дескать "можно забыть и не написать инит" - несостоятельны в силу того, что программист не должен быть настолько рассеянным и забывчивым, чтобы не контролировать свои действия. Да и элементарные тесты выявят эту "забывчивость". Ну как это можно "забыть написать", ну что за забывчивость такая? Поэтому, ваш шаблон несостоятелен, а зашоренное рамочное мышление неоптимально.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 13:33:50
BOB51
Вот только зачем переменную, только в данной функции используемую, объявлять вне данной функции?
Там и "местного" объявления типа static (локальная) вполне хватит...

Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 19:19:31
Demiurg
proc_inputs.h
Спойлер
Код: Выделить всё
//==================
#ifndef PROC_INPUTS_H
#define PROC_INPUTS_H
#include "proc_inputs.h"
#include "main_def_func.h"
//==================
//==================
#ifdef __PROJECT_MODE_WORK__
#define DEBOUNCE_DELAY 30
//#define DEBOUNCE_DELAY 3
#endif
#ifdef __PROJECT_MODE_DEBUG__
#define DEBOUNCE_DELAY 3
#endif
//==================
//==================
#define IN_1_PIN PINB
#define IN_1 0
#define IN_1_BIT b00000001
#define IN_2_PIN PINB
#define IN_2 1
#define IN_2_BIT b00000010
#define IN_3_PIN PINB
#define IN_3 2
#define IN_3_BIT b00000100
//==================
//==================
#define check_in_1() (check_bit (IN_1_PIN, IN_1)) // High level.
#define check_in_2() (check_bit (IN_2_PIN, IN_2)) // High level.
#define check_in_3() (check_bit (IN_3_PIN, IN_3)) // High level.
//==================
//==================
typedef enum _proc_inputs
{
PROC_INPUTS_INIT = 0,
PROC_INPUTS_NO_CHANGE,
PROC_INPUTS_CHANGE,
} proc_inputs_t;
//==================
//==================
void scan_inputs (void);
void proc_inputs (void);
u08 get_inputs (void);
//==================
#endif
proc_inputs.c
Спойлер
Код: Выделить всё
//==================
#include "proc_inputs.h"
//==================
//==================
static u08 prev_inputs;
static u08 curr_inputs;
//==================
//==================
void scan_inputs (void)
{
curr_inputs = 0;
if (check_in_1())
set_bit (curr_inputs, 0);
if (check_in_2())
set_bit (curr_inputs, 1);
if (check_in_3())
set_bit (curr_inputs, 2);
}
//==================
//==================
void proc_inputs (void)
{
static proc_inputs_t _proc_inputs;
static soft_timer_t ST_PROC_INPUTS;
scan_inputs ();
switch (_proc_inputs)
{
case PROC_INPUTS_INIT:
_proc_inputs = PROC_INPUTS_NO_CHANGE;
break;
case PROC_INPUTS_NO_CHANGE:
if (curr_inputs != prev_inputs)
{
prev_inputs = curr_inputs;
set_soft_timer (ST_PROC_INPUTS, DEBOUNCE_DELAY);
_proc_inputs = PROC_INPUTS_CHANGE;
}
break;
case PROC_INPUTS_CHANGE:
if (handle_soft_timer (ST_PROC_INPUTS)) // Таймер подавления дребезга.
{
if (curr_inputs == prev_inputs)
Set_Event (EV_ID_INPUTS_CHANGE, USER_EVENT);
prev_inputs = curr_inputs;
_proc_inputs = PROC_INPUTS_NO_CHANGE;
}
break;
default:
break;
}
}
//==================
//==================
u08 get_inputs (void)
{
return curr_inputs;
}
//==================
proc_device.h
Спойлер
Код: Выделить всё
//==================
#ifndef PROC_DEVICE_H
#define PROC_DEVICE_H
#include "proc_device.h"
#include "main_def_func.h"
//==================
//==================
#define OUT_1_DDR DDRD
#define OUT_1_PORT PORTD
#define OUT_2_DDR DDRD
#define OUT_2_PORT PORTD
#define OUT_3_DDR DDRD
#define OUT_3_PORT PORTD
#define OUT_1 0
#define OUT_2 1
#define OUT_3 2
//==================
//==================
void proc_device (void);
//==================
//==================
void io_init (void);
//==================
//==================
#define __out_1_on() set_bit(OUT_1_PORT, OUT_1)
#define __out_2_on() set_bit(OUT_2_PORT, OUT_2)
#define __out_3_on() set_bit(OUT_3_PORT, OUT_3)
#define __out_1_off() clr_bit(OUT_1_PORT, OUT_1)
#define __out_2_off() clr_bit(OUT_2_PORT, OUT_2)
#define __out_3_off() clr_bit(OUT_3_PORT, OUT_3)
#define __out_1_switch() switch_bit (OUT_1_PORT, OUT_1)
#define __out_2_switch() switch_bit (OUT_2_PORT, OUT_2)
#define __out_3_switch() switch_bit (OUT_3_PORT, OUT_3)
//==================
//==================
void out_1_on (void);
void out_2_on (void);
void out_3_on (void);
//------------------------------------------------------------------------
void out_1_off (void);
void out_2_off (void);
void out_3_off (void);
//------------------------------------------------------------------------
void out_1_switch (void);
void out_2_switch (void);
void out_3_switch (void);
//------------------------------------------------------------------------
void all_outs_off (void);
//==================
#endif
proc_device.c
Спойлер
Код: Выделить всё
//==================
#include "proc_device.h"
//==================
//==================
void proc_device (void)
{
static u08 _proc_device;
switch (_proc_device)
{
case 0: // Init IO
io_init ();
all_outs_off ();
_proc_device = 1;
break;
case 1:
if (Get_Event (EV_ID_INPUTS_CHANGE))
{
switch (get_inputs ())
{
case (IN_1_BIT):
all_outs_off ();
out_1_switch ();
break;
case (IN_2_BIT):
all_outs_off ();
out_2_switch ();
break;
case (IN_3_BIT):
all_outs_off ();
out_3_switch ();
break;
}
}
break;
default:
break;
}
}
//==================
//==================
void io_init (void)
{
set_bit (OUT_1_DDR, OUT_1); // Пин OUT_1 - выход
set_bit (OUT_2_DDR, OUT_2); // Пин OUT_2 - выход
set_bit (OUT_3_DDR, OUT_3); // Пин OUT_3 - выход
}
//==================
//==================
void out_1_on (void)
{
__out_1_on ();
}
void out_2_on (void)
{
__out_2_on ();
}
void out_3_on (void)
{
__out_3_on ();
}
//------------------------------------------------------------------------
void out_1_off (void)
{
__out_1_off ();
}
void out_2_off (void)
{
__out_2_off ();
}
void out_3_off (void)
{
__out_3_off ();
}
//------------------------------------------------------------------------
void out_1_switch (void)
{
__out_1_switch ();
}
void out_2_switch (void)
{
__out_2_switch ();
}
void out_3_switch (void)
{
__out_3_switch ();
}
//------------------------------------------------------------------------
void all_outs_off (void)
{
out_1_off ();
out_2_off ();
out_3_off ();
}
//==================
В проекте была ошибка, поправил. Файл перезалил.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 19:44:22
MLX90640
[uquote="BOB51",url="/forum/viewtopic.php?p=4301485#p4301485"]Там и "местного" объявления типа static (локальная) вполне хватит...[/uquote]
А догадываетесь, где в памяти ОЗУ хранится локальная статическая переменная? А вот там же, где и все глобально-объявленные переменные, то есть постоянно висит в ОЗУ, бессмысленно занимая память. А если таких переменных наберется поболее? Вот так и получается бесполезный мусор.
Demiurg, код - жээээсть

Шаблонное зашоренное рамочное мышление. Шаблон. Да, для вас он приятен. Но неоптимален и нелогичен. Это "школа" Корабельниково-подобных "учителей".
Понятно, что вы зашорились и привыкли к таким шаблонам. Но это - жэээсть

Никакой логики, просто нагромоздили кое-как, в меру своих разумений. Дааа, шаблоны, шаблоны... Жэсть. Теперь я понимаю, почему отечественная промышленность такая топорно-палочная. Чай, не DMG MORI, обычные палки.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 19:56:02
Demiurg
Я смотрел на твой код и алгоритмы и тоже плевался.
Мою работу оценивают мои клиенты. Так что это твое личное мнение, на которое мне плевать. Потому что в твоих сообщениях нет конструктива. Я посмотрел на твой код, алгоритмы, и сделал свои выводы.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 20:02:43
MLX90640
Ну тогда мы в расчете

"Не плюй в колодец - пригодится воды напиться". И "замечаешь соринку в чужом глазу, а в своем - и бревна не видишь". Народная мудрость, нашедшая еще одно подтверждение

А подобные вашей работы доводилось видеть - ЖЭЭЭЭСТЬ. Серьезно. Ужос и жесть. И у вас так же. Оно видно уже по написанному.
Кстати, взаимно - мне на вас тож как бы наплевать

Так что в расчете, сударь. Не трудитесь более. Идите спать, утро вечера мудреннее. А то завтра опять начнете удалять свои посты.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 20:05:09
Demiurg
Ты меня больше не зацепишь. Как выше написал, я сделал выводы. Ты мне не интересен.
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 20:07:45
MLX90640
Просто вы, сударь, ничего не поняли, потому как это выше вашего уровня знаний

Графы МДКА умеете строить то? Ась? Вот то-то же! А всё туда же - "автоматное проектирование", туда-сюда. Ну-ну. Даже прочитать графы то - и то никак. Типичный ученик Корабельникова. Жэээсть

Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 20:12:28
Demiurg
Ты мелочен. Твое поведение - типичное поведение мелкого тролля. Мелочный и гадкий. Провокатор. Нет ни малейшего желания продолжать с тобой диалог. Может в дальнейшем ты изменишь свое поведение, на данный момент наш с тобой диалог закончен. Ты мне не интересен на данном этапе
Re: Как поместить цикл в case оператора switch
Добавлено: Сб окт 08, 2022 20:42:01
MLX90640
А вот касательно вашего написанного текста...
Вот например, общепринято в языке Си имена функций писать с заглавной буквы, дабы визуально оное отличалось от имен переменных. Это мелочь. Но определяет грамотность и внимание программиста к мелочам. Своего рода "встречаем по одежке".
Далее, в заголовочный файл (*.h) выносится только то, что распространяется вовне модуля. Используемое только внутри модуля не выносится в заголовочный файл, то есть в интерфейс модуля. Это тоже мелочь, хоть и более высокого уровня. Так же по ней судят об опыте и аккуратности программиста.
Затем, чрезвычайно мелкое, без необходимости, дробление на отдельные функции говорит о том, что программист не заботится об оптимальности кода.
О неоптимальности кода говорит так же и дубликаты действий:
при том что:
Код: Выделить всё
void all_outs_off (void)
{
out_1_off ();
out_2_off ();
out_3_off ();
}
В общем, очень сильно всё задублировано. Ну и плюс обсуждавшееся ранее нелогичное помещение инициализации входов/выходов, непонимание логики работы программы.
Ну а по какому принципу в файл device.h помещены #define __out_1_on() set_bit(OUT_1_PORT, OUT_1) и #define OUT_1_DDR DDRD.
И совсем непонятно, зачем в ЭТОМ же файле
proc_device.h вставлено
#include "proc_device.h"? Что это и кто вас так научил делать? Это же ужос!Хорошо, что написан "предохранитель" от повторного включения, а то бы "сам в себя". Вы хоть можете объяснить, ЗАЧЕМ вы ЭТО написали ВТАМ? Или вы делаете по шаблону, не задумываясь, что пишите?
Да, шаблонное зашоренное мышление, полученное от неудачных учителей.
Да, код - жэсть, просто ужос. Неаккуратность, нелогичность, непоследовательность. Вот такой вот итог. Печально конечно это, печально. Потому у нас и промышленность на 30-40 лет отстает от мировых производителей. Потому что вот такая нелогичность и зашоренность, помноженная на упертость и ЧСВ. Вот и итог нынче наблюдается.