Запустите несколько функций одновременно с pic16f877a, используя C

Я использую microC для программирования pic16f877a для управления двигателями и соленоидами. У меня есть некоторые функции, заставляющие двигатели двигаться в разное время в пространстве, например. двигатель 1 перемещается на 100 мс, останавливается, снова перемещается на 100 мс и т. д. для 4 циклов, двигатель 2 на 200 мс и т. д. Я хочу, чтобы эти функции запускались одновременно.

Подумайте о роботе, когда вы хотите перемещать его правую руку вверх и вниз каждые 200 мс в общей сложности 2 минуты, а левую руку вверх и вниз каждые 400 мс, всего снова 2 минуты. Этот процесс должен начаться одновременно.

Итак, в основном я хочу начать что-то вроде:

start:
solenoid1 runs functionQuarter(moves up-down every x time) total like 2 mins
solenoid2 runs functionHalf(moves up-down every 2x time) total like 2 mins
stop

Можно ли сделать это с помощью micro c для этой картинки и как я могу вызвать 2 или более функций для одновременного запуска?


person GiorgosM    schedule 19.07.2015    source источник


Ответы (2)


Как вы думаете, зачем нужны треды? Вы точно знаете, когда должна произойти операция, поэтому выполняйте эту операцию именно в это время. Все, что вам нужно, — это соответствующая система планирования, которая поможет вам отслеживать операции. По сравнению с потоками у вас нет проблем с неожиданным планированием, возможно, меньшей задержкой, нет необходимости в синхронизации между потоками.

Рассмотрим этот эскиз:

// this task structure says at what time to set 
// an output to a certain value
struct task {
    time_type when;
    output_type output;
    value_type value;
};

struct task_queue {
    struct task** tasks;
    size_t count;
};
void task_queue_push(struct task_queue* q, struct task* t);
struct task* task_queue_front(struct task_queue* q);
struct task* task_queue_pop(struct task_queue* q);

Теперь в цикле вы продолжаете смотреть на первый элемент в очереди и просто sleep() до начала следующей задачи. Конечно, это означает, что вам нужно отсортировать эти задачи по времени их начала! Если несколько задач запускаются одновременно, вам нужно запустить их обе, единственное ограничение «одновременно» — время выполнения каждой задачи. При необходимости в рамках обработки одной задачи вы можете создать одну или несколько других задач. В качестве варианта вы также можете использовать обратный вызов вместо информации output и value, которые предполагают, что вы хотите установить только некоторые цифровые выходы.

person Ulrich Eckhardt    schedule 19.07.2015
comment
Пожалуйста, проверьте мое редактирование, публикующее мои функции, и, возможно, помогите мне, какой код добавить в main для достижения этого. - person GiorgosM; 19.07.2015
comment
Всего несколько комментариев к вашему редактированию: во-первых, вы отменили некоторые другие изменения, внесенные другими, что сделало ваш вопрос намного легче для чтения и понимания. Затем этот код, который вы разместили, едва читается, пожалуйста, отформатируйте и задокументируйте его. Наконец, ваш вопрос теперь сводится к тому, чтобы написать мне код, на который есть только один ответ: нет. - person Ulrich Eckhardt; 19.07.2015
comment
Хорошо, я попробую, но я не отменял другие правки других. - person GiorgosM; 19.07.2015
comment
Ну, я запутался в том, что произошло. Я даже не осознавал, что другие редактировали мой пост. Я просто хотел добавить код, как будто он здесь, а не в истории. В истории код выглядит иначе с красными метками. - person GiorgosM; 19.07.2015
comment
Да, это правильный способ сделать это. Вы можете иметь таблицу событий со временем, если хотите. У вас может быть таблица вещей (например, соленоидов) со статусами. Ваш основной фрагмент кода в основном определяет, сколько времени осталось до следующей вещи, которую он должен сделать, а затем ждет, пока пройдет столько времени или что-то произойдет. Если время проходит, он запускает событие, запланированное на это время, и снова ждет. Если что-то происходит, он реагирует на это событие (создавая и уничтожая другие события по мере необходимости), а затем снова ждет. - person David Schwartz; 24.07.2015

Нет никакого решения для серии pic16 (она слишком мала), но есть FreeRtos, созданная специально для микроконтроллеров, и есть порт для PIC18 (и некоторых других), проверьте список поддерживаемых устройств

Хотя freeRTOS является «бесплатной» для получения и использования в личных проектах, я бы порекомендовал вам приобрести одну из их книг, чтобы помочь с реализацией. На их сайте есть бесплатный API, а также демо-код. С книгой было бы проще разобраться (обратите внимание, я никоим образом не привязан к freeRTOS, я использовал ее в проектах с контроллерами atmel и нашел ее очень простой в использовании)

с freeRTOS вы создаете задачу (вы определяете свою функцию управления соленоидом), а затем устанавливаете приоритет, задержку и запускаете ядро. Это на самом деле очень просто.

Опять же, это не будет работать с вашим конкретным чипом pic16, но если вы можете попробовать другой, freeRTOS — очень известное и довольно простое решение.

person andrew    schedule 24.07.2015