Регистрация | Вход

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: demanik, ivan_fd  
DelayuUS, подвисает контроллер.
sosiska Дата: Пт, 30.03.2012, 12:27  |                                                                                                                Сообщение # 1
Группа: Проверенные
Ранг:  Новенький
Сообщений: 1
Репутация: 0   ±
Замечания:   ±
На сайте с 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
ЯНДЕКС Дата: 30.03.2012
mikhail09p Дата: Пт, 30.03.2012, 13:33  |                                                                                                                Сообщение # 2
Группа: Проверенные
Ранг:  Помогаю всем
Сообщений: 481
Репутация: 14   ±
Замечания:   ±
На сайте с 04.05.2010

Статус: Offline

Quote (sosiska)
вхожу в прерывание, там задаю определленную задержку перед включением симистора посредством команды DelayUS

Так делать нельзя! Это неоднократно обсуждалось. Задействуйте ещё один таймер для отсчёта времени выдержки.
retas Дата: Пт, 30.03.2012, 17:37  |                                                                                                                Сообщение # 3
Группа: Проверенные
Ранг:  Помогаю всем
Сообщений: 445
Репутация: 11   ±
Замечания:   ±
На сайте с 10.09.2007

Статус: Offline

Да и в основном теле прогры оператор "Delay" лучше не применять - он сработав, пока своего не сосчитает, не позволит
сработать в это время прерыванию. Лучше сделать переменную_счетчик и велеть ей по кругу заполнятся до нужного
значения.
Delay хорош на первых шагах, лампочками поморгать.
ADMIN Дата: Пт, 30.03.2012, 18:14  |                                                                                                                Сообщение # 4
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Не вводите в заблуждение человека. Это не PBP. В протоне, если написать on_interrupt, а не on interrupt, то не имеет значения, где находится программа. А если бы у программы были комментарии, то было бы понятно, чем можно помочь
retas Дата: Вс, 01.04.2012, 00:27  |                                                                                                                Сообщение # 5
Группа: Проверенные
Ранг:  Помогаю всем
Сообщений: 445
Репутация: 11   ±
Замечания:   ±
На сайте с 10.09.2007

Статус: Offline

1. После того как где то здесь была затронута эта проблема, я взял за правило не применять Delay, совсем
не поинтересовавшись было ли дело в PBP в Протоне или в бобине. Если Протон способен "не испортится" от
Delay, то приятно слышать.
2. Однако, отказ от Delay может быть полезен в случае необходимости "паралельного" выполнения кода. Например
несколько ЛЕД с разными интервалами горения, зумер должен в свое время прокукарекать...
3. Отказавшись от Delay не пострадаешь и мой совет незаблуждение а предупреждение и таким является даже
если в конкретном случае я ошибся.
4. Что значит "не имеет значения, где находится программа" ?
ADMIN Дата: Вс, 01.04.2012, 08:56  |                                                                                                                Сообщение # 6
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 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
Репутация: 11   ±
Замечания:   ±
На сайте с 10.09.2007

Статус: Offline

--Я лишь внес поправку--
Спасибо за неё, но сперва вы внесли "заблуждение".
  • Страница 1 из 1
  • 1
Поиск: