DelayuUS, подвисает контроллер.
|
|
sosiska |
Дата: Пт, 30.03.2012, 12:27 | Сообщение # 1 |
Группа:
Проверенные
Ранг:
Новенький
Сообщений:
1
Замечания:
±
На сайте с 20.06.2011
Статус:
Offline
|
Здраствуйте, написал код фазоимульсного управления двигателем. При помощи оптопары детектирую ноль сети и вхожу в прерывание, там задаю определленную задержку перед включением симистора посредством команды DelayUS, далее выхожу из программы, и идет цикл определиния нажатия кнопок. Все работает прекрасно в железе. '-------------------------- Опции компилятора --------------------------------
Declare SHOW_SYSTEM_VARIABLES = OFF ' При симуляции в Proteus не показывать внутренние переменные Declare Optimiser_Level 3 ' Включить оптимизацию программы
;-------------------------- Общие настройки------------------------------------
Device = 16F628A ' Используемый микроконтроллер Xtal = 16 ' Частота осциллятора 16 МГц
'-------------------------- Настройки портов ---------------------------------
PortB_Pullups = 0 ' Включить подтягивающие резисторы на PORTB Declare All_Digital = On ' Установить все порты цифровыми входами/выходами TRISA = %11111011 TRISB = %01110001 PORTA = %00000000 OPTION_REG.6 = 1 'прерывание по переднему фронту rbo '-------------------------- INTCON --------------------------------------------
Symbol RBIF = INTCON.0 ' Флаг внешнего прерывания по PORTB.4-PORTB.7 Symbol INTF = INTCON.1 ' Флаг внешнего прерывания по PORTB.0(INT) Symbol T0IF = INTCON.2 ' Флаг переполнения TMR0 Symbol RBIE = INTCON.3 ' Бит разрешения прерывания по PORTB.4-PORTB.7 Symbol INTE = INTCON.4 ' Бит разрешения прерывания по PORTB.0(INT) Symbol T0IE = INTCON.5 ' Бит разрешения прерывания по переполнению TMR0 Symbol PEIE = INTCON.6 ' Бит разрешения прерывания от периферийных устройств Symbol GIE = INTCON.7 ' Бит глобального разрешения прерываний GIE = 1 ' Разрешение глобального прерывания INTE = 0 'вначале запрет на прерывание по RB0
'-------------------------- Определение переменных --------------------------- Dim y As Word Dim v As Bit Dim c As Bit Dim x As Word
v=1 c=0 y=5000 '10000 микросекунд US полупериод при частоте сети в 50 Гц
'-------------------------- Определение символов -----------------------------
Symbol simistor = PORTA.2 Symbol simistor1= PORTB.1 Symbol optopara = PORTB.0 Symbol key1 = PORTA.0 Symbol key2 = PORTB.6 Symbol key3 = PORTB.4 Symbol key4 = PORTB.5 Symbol key5 = PORTA.1
'-------------------------- Прерывания-------------------------- simistor=1 simistor1=1
On_Interrupt GoTo ACdetect
GoTo Main
Disable Context Save ACdetect: '----------------------------Работа двигателя------------------ If v=0 And c=0 Then DelayUS y simistor=0 DelayUS 100 simistor=1 EndIf INTF = 0 Enable Context Restore ' Возврат из обработчика прерывания
'-------------------------- Главная программа -------------------------
Main: If key1=0 Then GoTo keyy1 If key2=0 Then GoTo keyy2 If key3=0 Then GoTo keyy3 If key4=0 Then GoTo OnnOff If key5=0 Then GoTo maximum GoTo Main
OnnOff: While key3=0 DelayUS 10 Wend If v=0 Then INTE=0: simistor=1: v=1: GoTo Main v=0 INTE=1 GoTo Main
keyy1: While key1=0 DelayUS 10 Wend If v=1 Then GoTo Main INTE=1 y=y-250 If y<=1500 Then y=1500 GoTo Main
keyy2: While key2=0 DelayUS 10 Wend If v=1 Then GoTo Main INTE=1 y=y+250 If y>=9000 Then y=9000 GoTo Main
keyy3: '---работа лампы------
While key3=0 DelayUS 100 Wend
Toggle simistor1 GoTo Main
maximum: While key5=0 DelayUS 100 Wend If c=1 And v=0 Then INTE=1: c=0: GoTo Main If v=0 Then c=1 INTE=0 simistor=0 EndIf GoTo Main
Далее встал вопрос борьбы с дребезгом контактов))). Вот например кусок программы отвечающий за переключение другого симистора.
keyy3: '---работа лампы------
While key3=0 DelayUS 100 Wend
Toggle simistor1 GoTo Main
При установелнии значения DelayUS больше 20 контроллер подвисает, при принудительной подаче на RB0 единици –отвисает. Догадываюсь что в этой команде ассембелр использует прерывание по какому-то таймеру и прерывания конфликтуют. Подскажите как можно избавится от деребезга. Или как задействовать таймер для опроса кнопок при аппаратном прерывании от оптопары.
Сообщение отредактировал
sosiska - Пт, 30.03.2012, 12:28
|
|
|
|
mikhail09p |
Дата: Пт, 30.03.2012, 13:33 | Сообщение # 2 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
Quote (sosiska) вхожу в прерывание, там задаю определленную задержку перед включением симистора посредством команды DelayUS Так делать нельзя! Это неоднократно обсуждалось. Задействуйте ещё один таймер для отсчёта времени выдержки.
|
|
|
|
retas |
Дата: Пт, 30.03.2012, 17:37 | Сообщение # 3 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
Да и в основном теле прогры оператор "Delay" лучше не применять - он сработав, пока своего не сосчитает, не позволит сработать в это время прерыванию. Лучше сделать переменную_счетчик и велеть ей по кругу заполнятся до нужного значения. Delay хорош на первых шагах, лампочками поморгать.
|
|
|
|
ADMIN |
Дата: Пт, 30.03.2012, 18:14 | Сообщение # 4 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Не вводите в заблуждение человека. Это не PBP. В протоне, если написать on_interrupt, а не on interrupt, то не имеет значения, где находится программа. А если бы у программы были комментарии, то было бы понятно, чем можно помочь
|
|
|
|
retas |
Дата: Вс, 01.04.2012, 00:27 | Сообщение # 5 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
1. После того как где то здесь была затронута эта проблема, я взял за правило не применять Delay, совсем не поинтересовавшись было ли дело в PBP в Протоне или в бобине. Если Протон способен "не испортится" от Delay, то приятно слышать. 2. Однако, отказ от Delay может быть полезен в случае необходимости "паралельного" выполнения кода. Например несколько ЛЕД с разными интервалами горения, зумер должен в свое время прокукарекать... 3. Отказавшись от Delay не пострадаешь и мой совет незаблуждение а предупреждение и таким является даже если в конкретном случае я ошибся. 4. Что значит "не имеет значения, где находится программа" ?
|
|
|
|
ADMIN |
Дата: Вс, 01.04.2012, 08:56 | Сообщение # 6 |
Администратор
Группа:
Администраторы
Ранг:
Специалист
Сообщений:
1086
Замечания:
±
На сайте с 20.08.2007
Статус:
Offline
|
Quote (retas) он сработав, пока своего не сосчитает, не позволит сработать в это время прерыванию Это называется вводить в заблуждение, поскольку если при выполнении оператора Delay произойдет прерывание, то программа перейдет на обработку его, прервав выполнение оператора Delay/ После обработчика программа вернется на выполнение оператора. Это все при условии, что в начале программы написано не ON INTERRUPT, а ON_INTERRUPT. Это аналогично директиве ассемблера ORG 0X004, которая указывает на адрес ПП обработчика прерывания. Не имеет значения, где находится программа - это значит, что аналогично вышеописанному, программа прервется в любом случае и в любом месте, где бы ни находилась рабочая точка программы. Я не говорю, что использование Delay оправдано в любом случае, можно обходиться и без него, как и без многих других операторов, а использовать ассемблер, где нет таких операторов. Каждый сам определяет степень необходимости использования того или иного метода для решения своей задачи. Я лишь внес поправку. Всем - почитайте в справке назначение операторов ON INTERRUPT и ON_INTERRUPT[color=red].
|
|
|
|
retas |
Дата: Пн, 02.04.2012, 15:31 | Сообщение # 7 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
445
Замечания:
±
На сайте с 10.09.2007
Статус:
Offline
|
--Я лишь внес поправку-- Спасибо за неё, но сперва вы внесли "заблуждение".
|
|
|
|