Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Порядок прерываний в AT90S2313
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
SAU
Написал код для диммера на Bascom
$regfile = "2313DEF.dat"
$crystal = 4000000
Config Portb = Output

Config Portd.0 = Output ' Out for triac
Config Portd.1 = Output ' Out for triac

Config Portd.2 = Input ' Input INT0

Config Portd.6 = Input ' Input manage lamp
Config Portb.0 = Input ' Input manage lamp

Config Lcd = 16 * 2 'control LCD
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6


Config Int0 = Falling

Config Timer0 = Timer , Prescale = 256
On Timer0 Timer0_isr

On Int0 Ind
Enable Int0
Enable Timer0
Enable Interrupts


Dim Count As Byte
Dim P7 As Bit , P0 As Bit
Count = 75
Cls


Start Timer0
'
'
'156 - min , 2- max light

Do

Loop

Ind:

P7 = Pinb.0
P0 = Pind.6

If P7 = 0 And P0 = 0 Then
Count = 156
End If

If P7 = 0 And P0 = 1 Then ' reduction of brightness

If Count < 156 Then
Incr Count
End If

End If

If P7 = 1 And P0 = 0 Then 'increase to brightness
If Count > 2 Then
Decr Count
End If
End If

Cls
Lcd "In timer0" ; Count

Load Timer0,Count
Start Timer0

Return

Timer0_isr:
Stop Timer0

Set Portd.1
Set Portd.0
Waitms 20
Reset Portd.0
Reset Portd.1

Return

End

На общую шину и вывод пина 2 порта D через резистор заведены 6В.
При переходе через ноль срабатывает прерывание по спаду - это видно на индикаторе (прилепил для контроля на макетке)
Но не срабатывает таймер - на осциллографе не видны импульсы, хотя инкремент и декремент счетчика есть - это видно на том же индикаторе.
Если в обработчике прерывания таймера поставить
Load Timer0,Count
Start Timer0
а в прерывании INT0 убрать запуск таймера, то возникает такая ситуация:
Пока прерывание INT0 есть - нет прерывания по таймеру.Как только его убираешь - появляются импульсы, т.е начинает срабатывать прерывание по таймеру.Причем длительность импульсов пропорциональна Count. (Для справки Bascom инструкцией Load загружает требуемое значение в регистр таймера.Т.е. если написать Load Timer0,156 то в таймере окажется 100 (256-156) )

У меня вопрос.По таблице векторов INT0 имеет самый высокий приоритет.Означает ли это, что при входе в обработчик этого прерывания все остальные уже запрещаются?
vet
Прерывания в AVR запрещаются при входе в обработчик любого прерывания. Но в обработчике можно разрешить их явно, хотя обычно незачем.
impuls-v
В микроконтроллерах AVR отсутствуют вложенные прерывания. Но как правильно написал VET их можно организовать.
Laksus
Цитата
Config Int0 = Falling
...
Пока прерывание INT0 есть - нет прерывания по таймеру.Как только его убираешь - появляются импульсы, т.е начинает срабатывать прерывание по таймеру.
...
Означает ли это, что при входе в обработчик этого прерывания все остальные уже запрещаются?

_________
Falling - это прерывание по спаду.
Пока идет обработка прерывания - остальные запрещены,
но обработка такого прерывания занимает микросекунды,
(тем более, что счетчик запускается под самый конец подпрограммы.)
а после окончания обработки прерывания вновь разрешаются.


Поэтому наличие прерывания INT0(Falling) не должно влиять
на прерывания по таймеру, минимальное время которого
(при Count=2) составляет 128 мксек.

_________
Timer0_isr:
...
Waitms 20
...

Непонятно зачем здесь 20 миллисекунд?
Это ж целый период при 50 Гц.
_________
Александр
2006 16
SAU
С прерываниями разобрался - поставил 20 мкс вместо 20 мс и все заработало. Поменял прерывание INT0 со спада на прерывание по низкому уровню - заметно было мерцание.
Но яркость регулируется как-то криво.
Пробовал играть с задержкой между нажатием кнопки.Довел до 5 мкс но все без толку.
Дребезг я не учитывал.
Как добиться плавной регулировки учитывая нелинейный характер.
Может алгоритм есть какой.Не вычислять же значения интеграла
DS
Если Вы стаивте прерывание по уровню, то как только Вы выходите из обработчика, (а сигнал на входе еще не успел изменится - на входе у Вас 50 гц), прерывание срабатывает снова. Это вряд ли то, чего, Вы добиваетесь.

Для коррекции нелинейности сделайте табличку соотвествия яркости и вашего управляющего параметра и зашейте ее в МК. 100 точек,я думаю, более чем достаточно для управления лампчкой.
SAU
Цитата(DS_ @ Mar 18 2006, 19:06) *
Если Вы стаивте прерывание по уровню, то как только Вы выходите из обработчика, (а сигнал на входе еще не успел изменится - на входе у Вас 50 гц), прерывание срабатывает снова. Это вряд ли то, чего, Вы добиваетесь.

Вообще-то я руководствовался апнотом Zero Cross Detector - там показано, как через резистор 1Мом на INT0 заведена фаза.Правда там была Мега.
А такой вариант подключения и обработка прерывания компаратора поможет?
DS
Да он поточнее, конечно будет. Но проблема то не в этом - прерывание должно срабатывать по изменению состояния (компаратора или int0, не важно). Если Вы устанавливаете прерывание по уровню, оно срабатывает непрерывно, пока уровень держится. А Вам надо два раза за период.

Посмотрите внимательно на Ваши манипуляции с таймером, ошибка наверное была там.
defunct
Цитата(SAU @ Mar 18 2006, 21:13) *
А такой вариант подключения и обработка прерывания компаратора поможет?

Imho такой вариант тоже имеет право на существование, но пример расписаный в appnote должен работь. Важно только правильно настроить условие возбуждения прерывания.
С аналоговым компаратором это биты регистра ACSR
Table 34. ACIS1/ACIS0 Settings
01 = Falling Edge
11 = Rising Edge

С Int0 это соответственно биты регистра MCUCR:
Table 24. Interrupt 0 Sense Control
ICS01/ICS00
10 The falling edge of INT0 generates an interrupt request.
11 The rising edge of INT0 generates an interrupt request.

И разрешить генерацию соответствующего прерывания. В случае с аналоговым компаратором - бит ACIE регистра ACSR, в случае с INT0 - бит INTF0 регистра GIMSK.

И обязательно уберите из обработчка таймера громадную задержку, строчка Waitms 20.
Для корректной работы:
1. настройте таймер на длительность отсчета (между запуском таймера и генерацией прерывания) 20ms.
2. по прерыванию от внешнего источника - устанавливайте бит порта, и запускайте таймер.
3. по прерыванию от таймера останавливайте таймер и очищайте содержимое счетчика таймера TCNT.
Laksus
Цитата
Но яркость регулируется как-то криво....

_______________
Пара вопросов:
1. В чем выражена кривизна регулировки?

2. А гальваническая развязка микроконтроллера от сети есть?
(Как подается управление на симистор?)
_______________
Александр
2006 03 19
SAU
Цитата(defunct @ Mar 18 2006, 23:23) *
10 The falling edge of INT0 generates an interrupt request.
11 The rising edge of INT0 generates an interrupt request.

Я пробовал генерировать по falling - лампа мерцает. Я так понимаю, что раз срабатывает по спаду - то обрабатывается только 1 полупериод

Цитата(defunct @ Mar 18 2006, 23:23) *
И обязательно уберите из обработчка таймера громадную задержку, строчка Waitms 20.
Для корректной работы:
1. настройте таймер на длительность отсчета (между запуском таймера и генерацией прерывания) 20ms.
2. по прерыванию от внешнего источника - устанавливайте бит порта, и запускайте таймер.
3. по прерыванию от таймера останавливайте таймер и очищайте содержимое счетчика таймера TCNT.

Я так теперь и делаю.Только импульс генерируется длительностью 20мкс. А время сработки таймера высчитываю как 256- счетчик, где счетчик - инкремент или декремент при нажатии кнопки "+" или "-"
Т.е.Число в диапазоне 2-156.


Цитата(defunct @ Mar 18 2006, 23:23) *
10 The falling edge of INT0 generates an interrupt request.
11 The rising edge of INT0 generates an interrupt request.

Я пробовал генерировать по falling - лампа мерцает. Я так понимаю, что раз срабатывает по спаду - то обрабатывается только 1 полупериод. А в AT90S2313 в INT0 отсутствует прерывание по изменению состояния, поэтому стал склоняться к мысли о компараторе.

Цитата(defunct @ Mar 18 2006, 23:23) *
И обязательно уберите из обработчка таймера громадную задержку, строчка Waitms 20.
Для корректной работы:
1. настройте таймер на длительность отсчета (между запуском таймера и генерацией прерывания) 20ms.
2. по прерыванию от внешнего источника - устанавливайте бит порта, и запускайте таймер.
3. по прерыванию от таймера останавливайте таймер и очищайте содержимое счетчика таймера TCNT.

Я так теперь и делаю.Только импульс генерируется длительностью 20мкс. А время сработки таймера высчитываю как 256- счетчик, где счетчик - инкремент или декремент при нажатии кнопки "+" или "-"
Т.е.Число в диапазоне 2-156.
defunct
Цитата(SAU @ Mar 19 2006, 12:23) *
Я пробовал генерировать по falling - лампа мерцает. Я так понимаю, что раз срабатывает по спаду - то обрабатывается только 1 полупериод. А в AT90S2313 в INT0 отсутствует прерывание по изменению состояния, поэтому стал склоняться к мысли о компараторе.

Ну а разве этого недостаточно? Захватывается не полупериод, а начало периода, просто учитывайте это при задании задержки в таймере!
Если уж не судьба работать с периодом и сильно нужно ловить каждый полупериод то поставте 2 диода анодами к сети 220, катодами через резистор 10 Мом к входу int0. И желательно резистор ~220k между Int0 и землей. Диодный мостик-то знаете как работает?
DS
А Вы в обработчике прерываний переставляйте каждый раз регистр режима - сработало по спаду, ставите на фронт, и наоборот. Вот и получите на каждый 0
defunct
Phase Correct PWM можно применить.. (с захватом только начала периода)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.