BASCOM AVR в вопросах и ответах
Совершенно верно.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
- Реклама
ага заработало ))))) спасибо.
Пожалуйста. Обращайтесь. 
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
а вот ещё задачка, добавил к предыдущему коду, обработку кнопок, в результате при нажатии на любую кнопку всё зависает, до нажатия RESET. так то вроде всё как по учебнику.
https://yadi.sk/i/wmsMzHIFnWSoJ
https://yadi.sk/i/wmsMzHIFnWSoJ
- Реклама
Дополню.Moto_v3x писал(а):6П3С уберите Do Loop в обработке прерывания
В конце обработчика waitms не есть хорошо.
Вообще обработчик желательно делать по кол-ву команд меньше. К примеру устанавливать байтовую переменную в 1. В основном цикле отслеживать изменение, обрабатывать и сбрасывать эту переменную в 0 и добавить GIFR 128 и задержку от дребезга.
To Moto_v3x спасибо, заработало, не могу только понять почему Do Loop не работало?
To Tankor спасибо за информацию, )))))) пока не совсем понятно но попытаюсь осмыслить, с МК первую неделю только
To Tankor спасибо за информацию, )))))) пока не совсем понятно но попытаюсь осмыслить, с МК первую неделю только
Do Loop бесконечный цикл, это тоже что и GOTO метка. Обработчик намертво зацикливается.6П3С писал(а):To Moto_v3x спасибо, заработало, не могу только понять почему Do Loop не работало?
К вашему примеру. Я бы так реализовал (Кратко, только основа):
Dim T0 as byte
Do
..
If T0=1 Then
Что-то делаем
T0=0
Waitms 70
GIFR 64
End If
..
Loop
Knopki:
T0=1
Return
Таким образом прерывание только выставляет флаг T0, а в основном цикле обрабатывайте сколько угодно. Так быстрее и практичнее по-моему.
Последний раз редактировалось Tankor Сб янв 23, 2016 00:00:02, всего редактировалось 1 раз.
ага, понял , Спасибо. GIFR-не понял.
читаю книжку
читаю книжку
т.е. мы устанавливаем в единичку 7 бит регистра GIFR, для устранения срабатывания прерываний при дребезге. Я правильно понимаю?
6П3С писал(а):ага, понял , Спасибо. GIFR-не понял.
читаю книжку
- Вложения
-
- Снимок.PNG
- (10.06 КБ) 404 скачивания
Абсолютно верно. ТОлько не 7-ой, а 6-ой бит. Именно он отвечает за INT0.6П3С писал(а):т.е. мы устанавливаем в единичку 7 бит регистра GIFR, для устранения срабатывания прерываний при дребезге. Я правильно понимаю?
Дабы в битах не путаться, лучше писать не
а
Так и нагляднее и все же правильнее.
Немного теории для начинающих: Из-за "неидеальности" контактов кнопки они не замкнутся (и не разомкнутся) моментально. Нажатие будет выглядеть как многократное срабатывание. Это неизбежно, и с этим нужно бороться. Прерывание от части решает проблему, но остается один момент: любое прерывание при факте срабатывания выставляет соответствующий флаг в 1, и уходит обрабатываться. В обработчике этот флаг сбрасывается, подтверждая выполнение. При этом, когда программа находится в обработчике, все прерывания запрещаются глобально (что бы не прерывать самого себя). Но это вовсе не значит, что пока мы в обработчике, то мы пропустим все остальные прерывания. Если же сработает кто-то еще, пока мы обрабатываем прерывание, то будет выставлен соответствующий флаг. И как только мы покинем обработчик, мы тут же уйдем обрабатывать остальные прерывания. Да, остальные, их может быть несколько. И выполняться они будут в том порядке, в котором расположены по векторам (а не в том, в котором срабатывали). И вот здесь и возникает проблема дребезга: первое срабатывание кнопки уведет программу в обработчик, а последующие вызовут установку флага INTF в регистре GIFR (General Interrupt Flag Register - в этом регистре хранятся флаги внешних прерываний. У таймеров это TIFR, например). И как только мы уйдем из обработчика, мы... тут же попадем туда снова! А это грустно. Потому самое верное, прямо в обработчике перед выходом сбросить этот флаг.
Почему записью единицы, а не нуля (что было бы логично, ведь сработавший флаг выставляется в 1)? А это уже к даташиту:
Вкратце: Флаг сбрасывается при выполнении прерывания, может быть сброшен принудительно записью 1, и всегда сброшен если прерывание настроено на срабатывание по изменению уровня. На этом все.
Код: Выделить всё
GIFR = 64Код: Выделить всё
GIFR.6 = 1
' или
GIFR.INTF0 = 1
Немного теории для начинающих: Из-за "неидеальности" контактов кнопки они не замкнутся (и не разомкнутся) моментально. Нажатие будет выглядеть как многократное срабатывание. Это неизбежно, и с этим нужно бороться. Прерывание от части решает проблему, но остается один момент: любое прерывание при факте срабатывания выставляет соответствующий флаг в 1, и уходит обрабатываться. В обработчике этот флаг сбрасывается, подтверждая выполнение. При этом, когда программа находится в обработчике, все прерывания запрещаются глобально (что бы не прерывать самого себя). Но это вовсе не значит, что пока мы в обработчике, то мы пропустим все остальные прерывания. Если же сработает кто-то еще, пока мы обрабатываем прерывание, то будет выставлен соответствующий флаг. И как только мы покинем обработчик, мы тут же уйдем обрабатывать остальные прерывания. Да, остальные, их может быть несколько. И выполняться они будут в том порядке, в котором расположены по векторам (а не в том, в котором срабатывали). И вот здесь и возникает проблема дребезга: первое срабатывание кнопки уведет программу в обработчик, а последующие вызовут установку флага INTF в регистре GIFR (General Interrupt Flag Register - в этом регистре хранятся флаги внешних прерываний. У таймеров это TIFR, например). И как только мы уйдем из обработчика, мы... тут же попадем туда снова! А это грустно. Потому самое верное, прямо в обработчике перед выходом сбросить этот флаг.
Почему записью единицы, а не нуля (что было бы логично, ведь сработавший флаг выставляется в 1)? А это уже к даташиту:
The flag is cleared when the interrupt routine is executed. Alternatively, the flag
can be cleared by writing a logical one to it. This flag is always cleared when INT1 is configured
as a level interrupt.
Вкратце: Флаг сбрасывается при выполнении прерывания, может быть сброшен принудительно записью 1, и всегда сброшен если прерывание настроено на срабатывание по изменению уровня. На этом все.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Вот теперь вааще понятно. Спасибо большое.
Сижу дальше схемку развиваю, подключаю сервоприводы. Пока вроде вопросов нет.
Сижу дальше схемку развиваю, подключаю сервоприводы. Пока вроде вопросов нет.
делаю счетчик нажатий, точнее счетчик импульсов на энкодере, почему на экран выводится цифра 65535 и отсчет начинается с этого числа а не с 0??? как сделать чтобы считать начинал от 0 -1-2-3-4 ит.п.
вот код,
спасибо
вот код,
Код: Выделить всё
$regfile = "m8def.dat"
$crystal = 800000
Config Lcdpin = Pin , Rs = Portc.0 , E = Portb.5 , Db4 = Portb.4 , Db5 = Portb.3 , Db6 = Portb.2 , Db7 = Portb.0
Config Lcd = 16 * 4
Dim W As Word
Config Int0 = Falling
On Int0 Encod
Enable Interrupts
Enable Int0
Cls
Cursor Off Noblink
Do
Locate 1 , 2
Lcd "N" ; W
Loop
End
Encod:
Waitms 2
If Pind.5 = 1 Then
Incr W
Else
Decr W
End If
Gifr = 64
Return
Видимо при запуске, МК сразу уходит на прерывание и вычитает единицу. Попробуйте перед включение прерывания сбросить все флаги.(GIFR=64) Да, и частота мк наврятли 800кГц
Все делают ошибки, только мудрецы - новые, а дураки - старые.
Пины энкодера подтянуты к питанию? Очевидно же, что при включении программа сразу уходит в прерывание, и считает что на втором пине тоже 0. Потому и декремент переменной. И это именно срабатывание прерывания, дело не во флагах.
P.S. Что бы нормально отображались русские комментарии, перед копированием кода убедитесь, что у Вас русский язык в селекторе операционки...
P.S. Что бы нормально отображались русские комментарии, перед копированием кода убедитесь, что у Вас русский язык в селекторе операционки...
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Очень красиво всё объяснено.edm2007 писал(а):Пины энкодера подтянуты к питанию? Очевидно же, что при включении программа сразу уходит в прерывание, и считает что на втором пине тоже 0. Потому и декремент переменной. И это именно срабатывание прерывания, дело не во флагах.
P.S. Что бы нормально отображались русские комментарии, перед копированием кода убедитесь, что у Вас русский язык в селекторе операционки...
МК уходит на прерывание, потому-что флаг поднят, и ни какой другой причины нет. А почему он поднят , это уже дело второе. Тем более, что другого решения нет, как сбросить флаги.edm2007 писал(а):И это именно срабатывание прерывания, дело не во флагах.
Все делают ошибки, только мудрецы - новые, а дураки - старые.


