12.08.2020, 21:19
|
|
Гражданин KAZUS.RU
Регистрация: 17.06.2008
Адрес: Украина
Сообщений: 679
Сказал спасибо: 362
Сказали Спасибо 753 раз(а) в 358 сообщении(ях)
|
Вот еще пример, тоже с таймером TMR0.
С таймером TMR1 работа чуток геморнее, но принцип тот же.
Программа может быть организована разными способами, в каждом есть плюсы и минусы. В этом примере - просто циклический вызов фиксированного набора функций/подпрограмм - так называемых задач. Также применяются т. н. программные таймеры/счетчики. Каждая задача при вызове проверяет свой программный таймер/счетчик и предпринимает, когда требуется, соответствующие действия. В этом примере три простых задачи - мигаем тремя светодиодами
В архиве исходник, схема и файл для Proteus 8.3
873.zip
P. S.
Данный пример является скорее одним из (многих) способов решения в ситуации "нужны паузы/задержки, но тупить в задержке неприемлемо".
Кооперативная многозадачность в простейшем виде, так сказать.
Возможно, топикстартера заинтересует такой подход, как "автоматное программирование". Именно подход. Ассемблер или же другой язык - в данном случае не имеет значения.
Последний раз редактировалось mike-y-k; 15.11.2021 в 12:36.
Причина: 6.6
|
|
|
|
12.08.2020, 22:55
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Сообщение от tsb
|
Но я не знаю таких "оптических датчиков".
|
Такой же датчик, только не поперек, а повдоль.
Вообще, с одним только датчиком на участок, проблема нештатных ситуаций нерешаема. Ну и опять же не хватает информации - где установлены датчики (в начале, в конце участка?), каковы размеры коробочек по отношению к проходимому пути, ну кароч всё, что не хватает и приходится домысливать.
Две коробочки, лежащие рядом впритык один фотодатчик не распознает. Можно распознать только косвенно, по времени перекрытия фотопотока, и при условии, что размеры коробочек и скорость движения всегда одинаковы.
|
|
|
|
13.08.2020, 07:29
|
|
Частый гость
Регистрация: 18.09.2005
Сообщений: 26
Сказал спасибо: 72
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Сообщение от tsb
|
если "коробочка" выехала из зоны датчика в начале участка, то куда она успеет доехать за 0,5 сек? :
|
Участок транспортера и в самом деле не большой, примерно 60 см. Датчик стоит вначале участка. За 0,5 сек коробочка как раз успевает доехать до следующего датчика.
С имеющейся программой все прекрасно работает, если не возникают нештатные ситуации. Подобная программа выполнена на OMRON-е. Транспортер отключается следующим датчиком и лишь в случае, когда вдруг коробочку сняли, происходит отключение по таймеру.
|
|
|
|
13.08.2020, 09:27
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Одно из первых правил - "работает? ну и нехай оно работает, незачем вмешиваться".
Если хотите разрулить столкновения коробочек, то логика программы должна запрещать включение участка транспортера, если на следующем участке коробочка не покинула зону датчика. Так же, скорее всего, нужно увеличить время отключения участка транспортера, сделав запас на то, что коробочка может быть сдвинута на ленте и не доедет за полсекунды.
Всё это можно сделать и на существующем Омроне
|
|
|
|
13.08.2020, 09:53
|
|
Частый гость
Регистрация: 18.09.2005
Сообщений: 26
Сказал спасибо: 72
Сказали Спасибо 2 раз(а) в 2 сообщении(ях)
|
Сообщение от sholz
|
пример для 873А.
|
Исправил ошибку в инициализации портов. Может быть и напрасно?
Возникли вопросы:
Что подразумевается под значениями endtimer0, prescale и startcode?
Здесь выполняется инициализация портов. При возвращении в основную программу нужно снова выполнять инициализацию портов?
Как увязать эту программу с основной? Допустим у меня прошла команда на отключение двигателя
Stop0 btfss IN01 ;
return ;
btfsc ST0 ;
call Delay05
bcf ST0 ;
return
Как вместо Delay05 запустить программу таймера и как она должна вернуться для выполнения bcf ST0?
Сообщение от NewWriter
|
Всё это можно сделать и на существующем Омроне
|
Если прикинуть сколько Омронов нужно на хотя бы 10-и метровый транспортер, то сразу станет все понятно. Кроме того Омрон выполняет и другие функции, а транспортеров туева хуча.
А, совсем забыл. Тактовая частота контроллера у меня 4 МГц.
Последний раз редактировалось mike-y-k; 15.11.2021 в 12:37.
Причина: 6.6
|
|
|
|
13.08.2020, 11:58
|
|
Частый гость
Регистрация: 06.08.2005
Сообщений: 32
Сказал спасибо: 0
Сказали Спасибо 19 раз(а) в 16 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
не посуществу. на практике коробочки обычно собираются на более медленный транспортер без промежутков, потом переходят на более скоростной транспортер с гарантированными промежутками.
по существу. в памяти выделяется регистр в котором выделяется бит который выставляете при обработке прерывания. он маркер для основной части программы. выделяете еще регистр в котором в основной части программы по маркеру ведете подчсет, по завершению подсчета получаете нужный вам интервал. после чего маркер сбрасываете. имена регистрам и битам на ваш вкус.
TMR0 при в обработчике прерывания перезапускается при записи нового значения в счетный регистр. тоесть маркер у вас возникает регулярно согласно значению счетного регистра и предделителя если они неменяются. по работе таймера смотрите русскоязычный мануал на 873A
ваш пример не предполагает обработку других задач в процессе подсчета интервала.
после запуска отсчета 0.5сек. следует выйти в основной цикл и вернуться сюда только по завершению счета.
Последний раз редактировалось sholz; 13.08.2020 в 22:41.
|
|
|
|
13.08.2020, 15:49
|
|
Прописка
Регистрация: 25.11.2006
Адрес: Харьков
Сообщений: 295
Сказал спасибо: 25
Сказали Спасибо 71 раз(а) в 60 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Просмотрел примеры sholz. Последний пример (8timers) показался излишне усложненным из-за многоступенчатого счета времени (прерывания по 200 мкс, потом метки по 10 мс, потом по 100 мс, которые тоже нужно будет считать для получения требуемых 500 мс). Я бы предложил использовать прерывания по TMR1, так как он 16-битный и на нем можно сразу получить метки времени по 25 или 50 мс. А уже эти метки времени в основной программе легко посчитать для формирования нужных задержек от десятых долей секунды до нескольких секунд.
Но главное замечание к примерам sholz, о котором он упоминал вначале, но так и не исправил - это отсутствие сохранения регистров W и STATUS при входе в прерывание и восстановление их перед выходом из прерывания. Без этого использовать прерывания практически нельзя, так как это приведет к периодическим трудно предсказуемым ошибкам в работе программы. Эта мнимая экономия на написании нескольких строчек кода программы приведет к гораздо большим потерям времени при отладке и эксплуатации.
|
|
|
|
13.08.2020, 15:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Верно, верно. Сохранять эти регистры при входе и восстанавливать при выходе - крайне важная операция.
Вообще, можно запросто обходиться безо всяких прерываний. Принцип кон.автоматов.
1. Опрашиваем все входы от датчиков:
1а) есть изменения? останавливаем один привод, включаем следующий привод. И не забываем перезапустить таймер на новый цикл отсчета 0,5 с.
1б) нет изменений? переходим к п.2.
2. Читаем счетный регистр таймера.
2а) Значение регистра соответствует истечению времени 0,5 с? Останавливаем привод и перезапускаем таймер на новый интервал.
2б) Значение не соответствует истечению времени? Переходим к п.1.
Опросы происходят постоянно, чередуясь между опросом входов и считыванием значения таймера, поэтому ничего нигде не блокируется на длительное время.
Запуск таймера на ассемблере написать несложно.
Прерывания - нафик тут не нужны, меньше возни с ними.
Да, и в этот алгоритм еще нужно добавить кусок, где при нахождении коробочки в зоне датчика, предыдущий участок транспортера не включался, даже если на предыдущем участке есть коробочка в зоне датчика.
Последний раз редактировалось NewWriter; 13.08.2020 в 16:13.
|
|
|
|
13.08.2020, 16:24
|
|
Гражданин KAZUS.RU
Регистрация: 17.06.2008
Адрес: Украина
Сообщений: 679
Сказал спасибо: 362
Сказали Спасибо 753 раз(а) в 358 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Сообщение от ptrots
|
Как увязать эту программу с основной? Допустим у меня прошла команда на отключение двигателя
Stop0 btfss IN01 ;
return ;
btfsc ST0 ;
call Delay05
bcf ST0 ;
return
Как вместо Delay05 запустить программу таймера
|
ptrots, так просто одно другим не заменить, ибо
Сообщение от sholz
|
ваш пример не предполагает обработку других задач в процессе подсчета интервала.
|
Блокирующие задержки останутся блокирующими задержками, хоть на таймере, хоть на циклах. Тут нужен другой подход. Ниже приведен подход (как вариант), при котором задача Stop0 (если следовать Вашей реализации), ожидающая события, сразу возвращает управление и не стопорит всю систему. Правда, для этого, как уже говорилось в этой ветке, требуется некоторая минимальная инфраструктура, обеспечивающая временн ую базу.
1) Вводим переменную - таймер-счетчик (также в ходу название программный таймер) задачи Stop0; назначение - работа с временными интервалами.
2) Вводим переменную - "состояние участка №0"; назначение - выполнение требуемой ветви кода задачи в зависимости от ситуации.
3) Определяем два состояния для участка №0, например:
PHP код:
|
FSM_PART_0_IN1_CHECK equ 0 ; состояние участка 0 - ожидание сигнала с датчика наличия коробки FSM_PART_0_WAIT_OFF equ 1 ; состояние участка 0 - отработка временного интервала перед выключением привода
|
Ну и сама задача (словесное описание алгоритма), а код уже за Вами.
PHP код:
|
Задача Stop0 //======================== Проверяем переменную "состояние участка №0" Состояние равно FSM_PART_0_IN1_CHECK ? да - идем на метку STOP_0_IN1_CHECK Состояние равно FSM_PART_0_WAIT_OFF ? да - идем на метку STOP_0_WAIT_OFF Выход
//======================== STOP_0_IN1_CHECK: Проверка IN01 Требуется отключение ST0 ? нет - выход Проверка ST0 Требуется задержка? нет - выключаем ST0 и выход // нужна задержка выключения Устанавливаем таймер-счетчик задачи Stop0 на нужный интервал времени Устанавливаем переменную "состояние участка №0" в FSM_PART0_WAIT_OFF, при следующем вызове попадем в тот участок кода Выход
//======================== STOP_0_WAIT_OFF: Проверяем таймер-счетчик задачи Stop0 на окончание счета Счет окончен? нет - выход // счет окончен, задержка отработана Выключаем ST0 Устанавливаем переменную "состояние участка №0" в FSM_PART0_IN1_CHECK, при следующем вызове попадем в тот участок кода Выход
|
Для каждой задачи, где требуется (независимая от других задач) работа с временными интервалами, выделяется как минимум 1 переменная под таймер-счетчик. Про программные таймеры уже было в этой теме.
Это в общем случае ( а случаи, как известно, бывают разные )
Последний раз редактировалось j-Roger; 13.08.2020 в 16:37.
|
|
|
|
13.08.2020, 16:34
|
|
Прописка
Регистрация: 25.11.2006
Адрес: Харьков
Сообщений: 295
Сказал спасибо: 25
Сказали Спасибо 71 раз(а) в 60 сообщении(ях)
|
Re: Помогите с TMR1 на PIC16F873
Сообщение от NewWriter
|
Прерывания - нафик тут не нужны, меньше возни с ними.
|
Согласен, если программа будет выполнять только описанные задачи, то можно обойтись и без прерываний. Но аппаратных таймеров в микроконтроллере мало (например, будет использоваться только TMR1), а объектов управления 8. Поэтому все равно таймер TMR1 нужно будет использовать для формирования меток времени, например по 10 мс, а формирование задержек по 500 мс для каждого объекта управления можно сделать независимо (программными счетчиками меток времени). Если переменные этих счетчиков будут однобайтные (что логично для данного микроконтроллера), то ими можно будет формировать интервалы времени (задержки) до 2,5 сек.
Для этого нужно будет также перезапускать таймер TMR1 на очередной интервал 10 мс, но не в прерывании, а в основном цикле программы, контролируя его флаг переполнения: бит TMR1IF в регистре PIR1.
Последний раз редактировалось tsb; 13.08.2020 в 16:38.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:45.
|
|