Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/72: Рейтинг темы: голосов - 72, средняя оценка - 4.78
x0rOS

STM32 Алгоритм

20.03.2013, 18:48. Показов 14194. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет.
Суть: имеется бесконечный цикл в котором непрерывно выполняется Задача1.
По прерыванию(от нажатия кнопки) в бесконечном цикле должна выполняться Задача2.
При следующем нажатии - снова запуск Задачи1 и т.д.
В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)

Пока остановился на двух вариантах решения:
1. Каждый раз переписывать тело цикла. Очевидно, не самое рациональное решение и насколько я понимаю, трудно осуществимо в микроконтроллерах.
2. Создать две функции с циклами для Задачи1 и Задачи2. И по прерыванию завершать одну функцию и вызывать другую.
Но проблема в том, как именно это осуществить. Точнее, не понятно как завершать предыдущую функцию из прерывания. А если не завершать то в стеке будет копиться мусор и ничем хорошим это не закончится.

-----
Контроллер STM32, Си.

Спасибо!
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.03.2013, 18:48
Ответы с готовыми решениями:

Чем связать STM32 + STM32 в одном корпусе?
Есть 2 платы: (1) - STM32 (Вывод на LCD + запись SD) и (2) - STM32F4 (обработка сигналов + коммуникация с датчиками). Чем связать данные...

Общение с барометром MS5540 на STM32 (Arduino to STM32)
Получил от китайца сей аппарат, пошел тут же гуглить что нибудь готовое, но не тут то было. Информации по нем очень мало, даже на Arduino...

stm32 + FSMC + stm32
Доброе времени суток. Возможно ли к Ftosh памяти подцепить два Stm32F4. Один МК будет записывать данные на флеш, второй забирать и...

26
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
20.03.2013, 20:48
а какое время реакции нужно на кнопку? если не критично, то можно в прерывании в бесконечном цикле софтверно проверять не нажата ли кнопка. Если нажата - выход из прерывания.
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
20.03.2013, 21:11
Цитата Сообщение от x0rOS
Привет.
Суть: имеется бесконечный цикл в котором непрерывно выполняется Задача1.
По прерыванию(от нажатия кнопки) в бесконечном цикле должна выполняться Задача2.
При следующем нажатии - снова запуск Задачи1 и т.д.
В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)
Какая то странная хотелка .
В основном цикле не должно быть проверок - какой режим включен.
Это чем навредит ? Почему не должно быть проверок ?
Думается проблема надуманная и из за непонимания.
В основном цикле автомат состояний на два состояния , кои меняются в прерывании от нажатия .

А вообщем или описаны не все хотелки или ТС просто не понимает чего хочет.
0
x0rOS
20.03.2013, 21:36
itysiy, нет смысла, или я не так понял. Можно же просто проверять состояние ножки и из цикла. И чем это поможет поставленной задаче?
dosykus_2, возможно можно обойтись и без "оригинальных" решений. И вы правы, задач будет намного больше чем две. Обходить эти условия, каждую итерацию цикла очень накладно, т.к. каждый такт на счету(это когда уже задача запущена).

Непонимания чего? Просветите же меня.
----
itysiy, перепрочел и понял=) т.е. идея - задачи делать в программных прерываниях?
1 / 1 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
20.03.2013, 21:43
2x0rOS
Нажатие кнопки ловится по прерыванию. Если мы были в главном цикле - поймали прерывание, перешли в него и там делаем Задачу 2. Попутно проверяем кнопку на повторное нажатие. Если она была опять нажата - выходим из прерывания и выполняем задачу 1. Все повторяется снова.
Но какие требования к времени реакции на нажатие?
Если это обычные кнопки, то эти свистопляски вообще не нужны. И без прерываний флаговый или конечный автомат будет работать нормально.
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
20.03.2013, 21:48
Цитата Сообщение от x0rOS
Обходить эти условия, каждую итерацию цикла очень накладно, т.к. каждый такт на счету(это когда уже задача запущена).

Непонимания чего? Просветите же меня.
----
itysiy, перепрочел и понял=) т.е. идея - задачи делать в программных прерываниях?
Вы представляете сам автомат ? Крутимся в суперлупе без каких либо задержек проверяя на ходу одну пременную , значение которой и есть состояние автомата .

Code
1
2
3
4
5
6
while (1)
{
if(state == STATE1) do_operation1();
if(state == STATE2)do_operation2();
... и .д.
}
Состояние (значение) state меняем в прерывании.
Естественно в функциях do_operationx не должно быть каких либо задержек , выполнили что то и съе.....сь.
И далее если состояний куча меняем ifы на switch-case .
0
x0rOS
20.03.2013, 21:49
itysiy, в принципе, для двух задач и одной кнопки вполне приемлемое решение. Только тоже не совсем понятно. Не завершившийся обработчик прерывания не составит трудностей при повторном нажатии?
----
Понял, можно же просто запретить прерывание на ноге и в ручную опрашивать.
Хотя это тоже не совсем рационально, мало того задач будет больше. И еще проблема с обработкой дребезга контактов.
x0rOS
20.03.2013, 21:56
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?

Куда логичнее бы выглядела программа вида:
//бесконечный цикл первой задачи
метка1:
задача1;
jmp метка1;
-------------
//цикл второй задачи
метка2:
задача2;
jmp метка2;
-------------
Прерывание:
Если(включить выполнение второй задачи) тогда
Перезаписать "jmp метка1" на "jmp метка2";
Иначе
Перезаписать "jmp метка2" на "jmp метка1";

Все. В основном цикле никаких лишних проверок.
Простите за идиотский псевдокод, если смысл остался не ясен могу проиллюстрировать=)
(в коде ошибка, править надо и предыдущую метку и метку текущей задачи, но не суть)
Kimyus
20.03.2013, 22:23
Может попробовать приспособить что-то типа событийного диспетчера?
К примеру, задачи пишутся в виде функций. В основном цикле крутится диспетчер и вызывает функцию, находящуюся в данный момент в очереди задач. В прерывании, соответственно, записывать в очередь другую задачу.
Kimyus
20.03.2013, 22:27
Цитата Сообщение от x0rOS
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?

Куда логичнее бы выглядела программа вида:
//бесконечный цикл первой задачи
метка1:
задача1;
jmp метка1;
-------------
//цикл второй задачи
метка2:
задача2;
jmp метка2;
-------------
Прерывание:
Если(включить выполнение второй задачи) тогда
Перезаписать "jmp метка1" на "jmp метка2";
Иначе
Перезаписать "jmp метка2" на "jmp метка1";

Все. В основном цикле никаких лишних проверок.
Простите за идиотский псевдокод, если смысл остался не ясен могу проиллюстрировать=)
(в коде ошибка, править надо и предыдущую метку и метку текущей задачи, но не суть)
Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю
x0rOS
20.03.2013, 22:31
Kimius, можно. Только проблема одна, эти задачки зациклены. И прерывание будет возвращаться в этот цикл, до диспетчера не дойдет. А если вы предлагаете диспетчеру выделять время для оценки состояния - то это ничем не лучше чем просто if.
Вся проблема в том как корректно выйти из уже работающей задачи.
---
>Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
>В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю

Именно, но проблема в том, что каждый раз когда я буду нажимать на кнопку, прерванная предыдущая функция не завершается и мусорит стек.
Как уже говорил, это может кончиться плохо.
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
20.03.2013, 22:37
Цитата Сообщение от x0rOS
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?
Согласитесь подобные вводные надо было озвучивать сразу же.
Выше вам решение Kimius предложил . Но и мой вариант так же жизни_способен ибо все проверки будут иметь заранее известную длительность и так уж много, как вы думаете, не займут .
Ваш же вариант с самомодфицирующемся кодом это что то из области вирусописательства и фантастики , а точней просто от непонимания МК .
0
Kimyus
20.03.2013, 22:40
Цитата Сообщение от x0rOS
Kimius, можно. Только проблема одна, эти задачки зациклены. И прерывание будет возвращаться в этот цикл, до диспетчера не дойдет. А если вы предлагаете диспетчеру выделять время для оценки состояния - то это ничем не лучше чем просто if.
Вся проблема в том как корректно выйти из уже работающей задачи.
---
>Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
>В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю

Именно, но проблема в том, что каждый раз когда я буду нажимать на кнопку, прерванная предыдущая функция не завершается и мусорит стек.
Как уже говорил, это может кончиться плохо.
Разве после обработки прерывания не произойдет возврат на то место в котором оно произошло?
Т.е. во время выполнения задачи 1 происходит прерывание, обработчик делает свое дело и возвращается в то место, в котором и была прервана задача 1. И лишь по ее окончании в следующем проходе главного цикла будет вызвана задача 2.
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
20.03.2013, 22:40
x0rOS, обычно подобные задачи легко решаются когда ТС озвучит саму задачу , а не видимый ему вариант реализации.
И так же обычно все выливается в "изобретение велосипеда"...
0
x0rOS
20.03.2013, 22:47
Не хочу вступать в полемику, мой первый пост
>В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)
И ваши
>точней просто от непонимания МК
И в чем же заключается мое непонимание? Конкретнее пожалуйста!
Давайте не будем переходить на личности, а просто выскажите мнение по поводу способов решения данной задачи.
x0rOS
20.03.2013, 22:59
Kimius, да произойдет. Но до начала выполнения новой задачи время не жалко!
>И лишь по ее окончании в следующем проходе главного цикла будет вызвана задача 2.
И как это сделать?
-------------------
dosykus_2, хотите пойти простым путём? Ладно!
Задача1 - реализует КИХ фильтр, приличного порядка(около 200го, разумеется используется циклический буфер). Частота поступления нового отсчета 48кГц(при частоте мк72мгц). Т.е. за это время значение уже должно быть подсчитано и передано. Согласитесь, критично по времени.

Имеется блок переключателей - напрмер один вызывает Задачу2(которая например реализует другой вид демодуляции и фильтрацию другого порядка) и т.д.

Не отрицаю, что такой автомат может и справиться(а может и нет), но на мой взгляд возможно было бы найти и более рациональное решение.
Kimyus
20.03.2013, 23:08
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void (*pf)(void) = &task_1;   // Инициализируем указатель первой задачей
 
void task1(void)
{
}
 
void task2(void)
{
}
 
void interrupt()
{
if(pf == &task1){pf = &task2;}    // Вот тут выбирать следующую задачу
else{pf = &task1;}
}
 
main()
{
while(1)
{
(*pf)();
}
}
Но! Это собственно и есть диспетчер, то есть тот самый велосипед)

P.S. Кстати, если функций много и порядок их следования известен, то можно сделать массив из указателей на эти функции, а в прерывании менять только индекс. = тоже диспетчер

P.P.S. А по классике развития таких тем Вам кто-то рано или поздно должен сказать, что если каждый такт на счету, то МК выбран неверно) Хотя, конечно, жизнь она такая жизнь...
x0rOS
20.03.2013, 23:12
Kimius, спасибо. Это то что я имел ввиду. Но! Разве, выйдя из прерывания мы не окажемся по среди нашей задачи и вызов по новому указателю не произойдет?
И если я правильно понимаю, задача не должна быть зациклена. Но тогда каждый раз в цикле идет call и ret. А это еще грузнее чем условия.
----
Благодарю за последней PS. Вы правы, по хорошему надо было бы мощный DSP ставить. Но ведь обсуждаем конкретную задачу. Если вариантов нет - значит нет, если есть идеи - пожалуйста.
0 / 0 / 0
Регистрация: 13.01.2013
Сообщений: 140
20.03.2013, 23:26
На самом деле никто не заставляет выходить из прерывания. Считайте, что прерывание - это завершение текущей задачи.
Т.е. в прерывании инициализируем указатель стека и прыгаем в диспетчер задач.
Но это если можно прервать любую задачу в любом месте.
0
x0rOS
20.03.2013, 23:33
>Т.е. в прерывании инициализируем указатель стека и прыгаем в диспетчер задач.
Зачем в диспетчер? Я могу сразу в стек адрес нужной задачи кинуть. Но снова же. Стек предыдущей незавершенной функции будет мусорить. Или нет?
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.03.2013, 23:33
Помогаю со студенческими работами здесь

STM32 - STM32 I2C
*****ПРОБЛЕМА ИСПРАВЛЕНА****ОТВЕТ НИЖЕ , НЕ ВЧИТЫВАЙТЕСЬ В КОД ПРОГРАММЫ,УТОНЕТЕ)), НУ ЕСЛИ ТОЛЬКО ИНТЕРЕС ЕСТЬ. Всем добрый вечер....

Алгоритм ГОСТ ( простой) для STM32
//таблица замены static const char Table={ {0x04,0x0a,0x09,0x02,0x0d,0x08,0x00,0x0e,0x06,0x0B,0x01,0x0c,0x07,0x0f,0x05,0x03},...

Нужен алгоритм поиска пути в этом лабиринте (будь то волновой алгоритм или алгоритм правой/левой руки )
#include "stdafx.h" #include <iostream> #include <conio.h> using namespace std; void lab () { int s1 = 0; int s2 =...

Волновой алгоритм поиска (Алгоритм A* / Алгоритм А стар)
Хочу разработать алгоритм для решения головоломки с подвижными дисками (перестановочная головоломка). Определение. Перестано́вочные...

Линейный алгоритм, Алгоритм с ветвлениями, Циклический алгоритм Линейный алгоритм
Линейный алгоритм, Алгоритм с ветвлениями, Циклический алгоритм Линейный алгоритм 1. Объясни, что будет напечатано программой Program...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru