Обсуждаем контроллеры компании Atmel.
Ответить

ATtiny861 INT1 не работает

Пт окт 15, 2021 13:22:53

Всем здоровья и удачи.
У меня возникла небольшая проблема.
Я заказал на Али Экспресс ATtiny861, (там минимум 10шт), а пока жду решил попробовать их в протеусе.
В программировании (AVR ASM) я начинающий.Собрал схему счетчика с реверсом на внешних прерываниях
INT0 и INT1 по даташиту они есть, но INT1 в схеме не срабатывает.
Кстати в даташите по INT1 настройки срабатывания( ISC11, ISC10 ) отсутствуют,а по INT0 настройки срабатывания( ISC01, ISC00 ) есть.
Вопрос к Знающим : ошибка в протеусе, или я что-то не правильно делаю.

Я на форуме первый раз как оформлять не умею пока, извините.

пример проверки прерываний INT1 и INT0


Спойлер.include "D:\RABOTA_PROTEUS\AVR_ASM\asm\Appnotes\tn861def.inc"


;==============
; RESET and INTERRUPT VECTORS
;==============
.CSEG
.org 0 ;
rjmp START ; На основную программу

.org INT0addr ;
rjmp Forward ;Oбработкa прерывания по INT0 (инкремент)

.org INT1addr ;
rjmp Back ;Oбработкa прерывания по INT1 (декремент)


START:

ldi r16, low(RAMEND); Main program start
ldi r17, high(RAMEND); Tiny861 have also SPH
out SPL, r16; Set Stack Pointer to top of RAM
out SPH, r17; Tiny861 have also SPH

ldi r16,0b11110000;(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
out DDRA,r16 ;Установка 7,6,5,4 бита в регистре DDRA в "1" (выход)
ldi r16,0b00000100;(1<<PA2) ;
out PORTA,r16 ;Включение подтягивающих резисторов на входах РA2
ldi r16, 0b00011111;(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);"1" (выход)
out DDRB,r16
ldi r16,0b01000000;(1<<PB6) ;
out PORTB,r16 ;Включение подтягивающих резисторов на входах РВ6
ldi r16,(1<<ISC01)|(1<<ISC00) ;
out MCUCR,r16 ;MCUCR режим прерываний INT0-1 по нарастанию
ldi r16,0b11000000;(1<<INT1)|(1<<INT0) ;Разрешение прерываний INT0-1 GIMSK
out GIMSK,r16 ;Разрешение прерываний INT0-1 GIMSK
out GIFR,r16 ;предварительный сброс флагов прерываний






sei ;Разрешение прерываний

;===================


main:


rjmp main;Зацикливаемся

;==================





Forward: ;Начало обработки прерывания INT0
push R2;
in R2,SREG;
push R2 ;

sbi PINB, 4 ;

pop R2
out SREG,R2
pop R2
reti


Back: ;Начало обработки прерывания INT1
push R2;
in R2,SREG;
push R2 ;

sbi PINA, 4 ;

pop R2
out SREG,R2
pop R2
reti


работа программы в протеусе
не могу вставить фото с компа.

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 14:50:25

Table 11-1. Interrupt 0 Sense Control
Код:
ISC01 ISC00 Description
0      0          The low level of INT0 or INT1 generates an interrupt request.
0      1           Any logical change on INT0 or INT1 generates an interrupt request.
1      0           The falling edge of INT0 or INT1 generates an interrupt request.
1      1           The rising edge of INT0 or INT1 generates an interrupt request.

т.е. одинаково и для INT0 и для INT1
Далее....
Зачем дважды гонять SREG - сначала в регистр, затем в стек (и обратно)?
Ведь достаточно поместить его в какой-нибудь из R2-R15 и держать там до завершения прерывания
все равно если не разрешено "вложенное прерывание" никакой иной процесс текущее не прервет.
Отсутствует анализ условий "безопасного выхода" из текущего прерывания - сначала смотрим, завершено ли действие, вызвавшее прерывание, а затем уже из него вываливаемся (касается прерывания по уровню или по смене уровня - там антидребезг контакта надо учитывать).
За настройки не скажу - с 861й дел не имел, однако все выводы, имеющие альтернативу с АЦП/аналоговым компаратором надо проверить на корректность настроек неиспользуемого АЦП/аналогового компаратора.
:roll:

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 16:09:31

Спасибо за ответ.
изменил прогу по Вашему совету.
результат не изменился.

Спойлер.include "D:\RABOTA_PROTEUS\AVR_ASM\asm\Appnotes\tn861def.inc"


;==============
; RESET and INTERRUPT VECTORS
;==============
.CSEG
.org 0 ;
rjmp START ; На основную программу

.org INT0addr ;
rjmp Forward ;Oбработкa прерывания по INT0 (инкремент)

.org INT1addr ;
rjmp Back ;Oбработкa прерывания по INT1 (декремент)


START:

ldi r16, low(RAMEND); Main program start
ldi r17, high(RAMEND); Tiny861 have also SPH
out SPL, r16; Set Stack Pointer to top of RAM
out SPH, r17; Tiny861 have also SPH

ldi r16,0b11110000;(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
out DDRA,r16 ;Установка 7,6,5,4 бита в регистре DDRA в "1" (выход)
ldi r16,0b00000100;(1<<PA2) ;
out PORTA,r16 ;Включение подтягивающих резисторов на входах РA2
ldi r16,0b00011111;(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);"1" (выход)
out DDRB,r16
ldi r16,0b01000000;(1<<PB6) ;
out PORTB,r16 ;Включение подтягивающих резисторов на входах РВ6
ldi r16,(1<<ISC01)|(1<<ISC00) ;
out MCUCR,r16 ;MCUCR режим прерываний INT0-1 по нарастанию
ldi r16,0b11000000;(1<<INT1)|(1<<INT0) ;Разрешение прерываний INT0-1 GIMSK
out GIMSK,r16 ;Разрешение прерываний INT0-1 GIMSK
out GIFR,r16 ;предварительный сброс флагов прерываний






sei ;Разрешение прерываний

;===================


main:


rjmp main;Зацикливаемся

;==================





Forward: ;Начало обработки прерывания INT0

in R2,SREG;

sbi PINB, 4 ;


out SREG,R2;

reti;


Back: ;Начало обработки прерывания INT1

in R2,SREG;


sbi PINA, 4 ;


out SREG,R2;

reti;
Вложения
INT1.png
(153.66 KiB) Скачиваний: 80
INT0.png
(139.51 KiB) Скачиваний: 110

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 16:51:32

Вроде в программе ошибок нет. Уверены, что симулятор адекватен?

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 17:57:34

{sbi PINB, 4}
Может надо
sbi PORTB,4 ?
И не понял, кто гасит этот PORTB,4? Аналогично с другим int.
В прерывании у Вас SREG не изменяется, можно не сохранять.
Какая частота подаётся на sw1?
Последний раз редактировалось dgrett Пт окт 15, 2021 18:10:31, всего редактировалось 1 раз.

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 18:06:25

PIN установить нельзя, он только читается.

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 19:31:45

Можно, если это реальная АВРка.
Это режим
"...
12.2.2 Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a port.
..."
однако надо внимательно смотреть даташиты на вопрос есть ли такой режим в МК. Не у всех такой фокус может быть реализован.
Помимо прочего симулятор - не реальный кристалл и вполне может "не знать" о данной особенности.
Жаль что для старта выбран ATtiny861 - у меня в наличии такого нету, разве что в симуляторе АВР студио 4.19 прогнать можно (он более точно отрабатывает периферию МК)...
:roll:
Пы.Сы.....
Вообще-тов ассемблерный файл подключается или *.inc файл из каталога IDE
(C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes)
или из папки каталога проекта (ёжли я его туда сам скопирую)...
Может в шпротеусе как-то иначе - я тем шпротом стараюсь не пользоваться.
:roll:

Вот так работает по крайней мере в симуляторе avrStudio 4.19
Спойлер
Код:
;.include "D:\RABOTA_PROTEUS\AVR_ASM\asm\Appnotes\tn861def.inc"
 .nolist
 .include "baseinc/tn861def.inc" ; "tn13def.inc"
 .list
;----------
; область определений
 .equ s_int0 = 6 ; входной сигнал int0 порт РВ6
 .equ s_int1 = 2 ; входной сигнал int1 порт РА2
 .equ led_irq0 = 4 ; индикатор int0 порт РВ4
 .equ led_irq1 = 4 ; индикатор int0 порт РА4



;----------
 
;==============
; RESET and INTERRUPT VECTORS
;==============
.CSEG
.org   0 ;
rjmp START   ; На основную программу

.org   INT0addr ;
rjmp Forward   ;Oбработкa прерывания по INT0 (инкремент)

.org   INT1addr ;
rjmp Back   ;Oбработкa прерывания по INT1 (декремент)


START:

ldi r16, low(RAMEND); Main program start
ldi r17, high(RAMEND); Tiny861 have also SPH
out SPL, r16; Set Stack Pointer to top of RAM
out SPH, r17; Tiny861 have also SPH

;ldi r16,0b11110000;(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
ldi r16,(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)
out DDRA,r16 ;Установка 7,6,5,4 бита в регистре DDRA в "1" (выход)
;ldi r16,0b00000100;(1<<PA2) ;
ldi r16,1<<s_int1
out PORTA,r16 ;Включение подтягивающих резисторов на входах РA2
;ldi r16,0b00011111;(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);"1" (выход)
ldi r16,(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
out DDRB,r16
;ldi r16,0b01000000;(1<<PB6) ;
ldi r16,1<<s_int0
out PORTB,r16 ;Включение подтягивающих резисторов на входах РВ6
ldi r16,(1<<ISC01)|(1<<ISC00) ;
out   MCUCR,r16   ;MCUCR режим прерываний INT0-1 по нарастанию
;ldi r16,0b11000000;(1<<INT1)|(1<<INT0) ;Разрешение прерываний INT0-1 GIMSK
ldi r16,(1<<INT1)|(1<<INT0)
out   GIMSK,r16   ;Разрешение прерываний INT0-1 GIMSK
out   GIFR,r16   ;предварительный сброс флагов прерываний ????






sei   ;Разрешение прерываний

;===================


main:

nop
nop

rjmp main;Зацикливаемся

;==================





Forward: ;Начало обработки прерывания INT0

in R2,SREG;

;sbi PINB, 4 ;
sbi PINB,led_irq0

wait_a:
sbic PINB,s_int0
rjmp wait_a

out SREG,R2;

reti;


Back: ;Начало обработки прерывания INT1

in R2,SREG;


;sbi PINA, 4 ;
sbi PINA,led_irq1

wait_b:
sbic PINA,s_int1
rjmp wait_b


out SREG,R2;

reti;


проект со всеми настройками:
ts861.zip
(23.49 KiB) Скачиваний: 104

8)

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 21:49:23

PIN установить нельзя, он только читается.

всё можно. Запись единицы в PIN делает toggle выхода. Иногда очень удобно.

Re: ATtiny861 INT1 не работает

Пт окт 15, 2021 23:59:11

ошибка в протеусе, или я что-то не правильно делаю.

Ради интереса попробовал ваш код в студии и в протеусе. В студии 4.19 INT1 работает, в 8 протеусе - нет. Получается, это глюк протеуса..

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 03:05:29

Спасибо всем ответившим.
Попробовал код из проекта ts861 в протеусе он не пошел, даже INT0.

Добавлено after 26 minutes 22 seconds:
Нашел причину почему не пошел ts861
;ldi r16,0b00011111;(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);"1" (выход)
ldi r16,(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
out DDRB,r16

надо было либо оставить мой вариант 0b00011111
либо добавить (1<<PB4)|-выход INT0

а INT1 так и не пошел.

буду ждать микроконтроллеры что-бы попробовать в реале.

Добавлено after 1 hour 13 minutes 54 seconds:
попробовал свой вариант на ATtiny2313
Прекрасно работает.

Видно с INT1 в ATtiny861 ошибка протеуса, либо есть какие-то заморочки с доп. функциями выводов.

в любом случае придется ждать 861.

Вариант на ATtiny2313.
Спойлер.include "D:\RABOTA_PROTEUS\AVR_ASM\asm\Appnotes\tn2313def.inc"


;==============
; RESET and INTERRUPT VECTORS
;==============
.CSEG
.org 0 ;
rjmp START ; На основную программу

.org INT0addr ;
rjmp Forward ;Oбработкa прерывания по INT0 (инкремент)

.org INT1addr ;
rjmp Back ;Oбработкa прерывания по INT1 (декремент)


START:

ldi r16, low(RAMEND); Main program start
out SPL, r16; Set Stack Pointer to top of RAM



ldi r16,(1<<PD2)|(1<<PD3) ;
out PORTD,r16 ;Включение подтягивающих резисторов на входах РD2,РD3
ldi r16,(1<<PB1)|(1<<PB0);"1" (выход)
out DDRB,r16 ;
ldi r16,(1<<ISC01)|(1<<ISC00)|(1<<ISC11)|(1<<ISC10) ;
out MCUCR,r16 ;MCUCR режим прерываний INT0-1 по нарастанию
ldi r16,(1<<INT1)|(1<<INT0) ;Разрешение прерываний INT0-1 GIMSK
out GIMSK,r16 ;Разрешение прерываний INT0-1 GIMSK
out GIFR,r16 ;предварительный сброс флагов прерываний






sei ;Разрешение прерываний

;===================


main:


rjmp main;Зацикливаемся

;==================





Forward: ;Начало обработки прерывания INT0

in R2,SREG;

sbi PINB, 0 ;


out SREG,R2;

reti;


Back: ;Начало обработки прерывания INT1

in R2,SREG;


sbi PINB, 1 ;


out SREG,R2;

reti;
Вложения
2_INT0+INT1.png
(139.8 KiB) Скачиваний: 64
1_INT0+INT1.png
(136.4 KiB) Скачиваний: 67

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 10:54:18

Тот проектик, что я выложил выше( ts861 ) прекрасно компилируется и полностью тестируется на штатном дебаггер-отладчике avrStudio4.19 (достаточно ПК с win xp x32).
НО... При условии, что исходное состояние шин на INT0/INT1 равно 0.
Поскольку в основу заложено использование линий с подтягивающими резисторами то скорее всего неверный алгоритм для активного уровня прерывания (и генератора).
Переставьте активный переход на противоположный (из 1 в 0 вместо имевшегося ранее из 0 в 1) и соответственно установите выход из прерывания по состоянию 1.
8)
Последний раз редактировалось BOB51 Сб окт 16, 2021 11:50:14, всего редактировалось 1 раз.

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 11:47:35

Проверил сейчас в железе - работает. Тини 861, с Али. Так что протеус, увы, не все правильно эмулирует. Студия + jtag mk2 - тоже все ок.

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 11:53:06

Я уже выше исправил - там получается "инверсный статус" оттого и проблемы.
Исходно подается int0=int1=1 (включена "подтяжка") и затем сигнал меандра на int0
Отрабатывается однократно int0 затем сразу же следует int1, а поскольку сигнальной остается int0 то мы "висим наглухо".
8)
Для корректной работы по скринам топикстартера и его исходным условиям надо сменить активный уровень, вызывающий прерывание на противоположный - ловим спад из 1 в 0 (вместо фронта из 0 в 1) и одновременно заменить условие выхода из прерывания на "обнаружение 1" (вместо "обнаружения 0").
8)
Собственно вот так:
Спойлер
Код:
;.include "D:\RABOTA_PROTEUS\AVR_ASM\asm\Appnotes\tn861def.inc"
 .nolist
 .include "baseinc/tn861def.inc" ; "tn13def.inc"
 .list
;----------
; область определений
 .equ s_int0 = 6 ; входной сигнал int0 порт РВ6
 .equ s_int1 = 2 ; входной сигнал int1 порт РА2
 .equ led_irq0 = 4 ; индикатор int0 порт РВ4
 .equ led_irq1 = 4 ; индикатор int0 порт РА4



;----------
 
;==============
; RESET and INTERRUPT VECTORS
;==============
.CSEG
.org   0 ;
rjmp START   ; На основную программу

.org   INT0addr ;
rjmp Forward   ;Oбработкa прерывания по INT0 (инкремент)

.org   INT1addr ;
rjmp Back   ;Oбработкa прерывания по INT1 (декремент)


START:

ldi r16, low(RAMEND); Main program start
ldi r17, high(RAMEND); Tiny861 have also SPH
out SPL, r16; Set Stack Pointer to top of RAM
out SPH, r17; Tiny861 have also SPH

;ldi r16,0b11110000;(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
ldi r16,(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)
out DDRA,r16 ;Установка 7,6,5,4 бита в регистре DDRA в "1" (выход)
;ldi r16,0b00000100;(1<<PA2) ;
ldi r16,1<<s_int1
out PORTA,r16 ;Включение подтягивающих резисторов на входах РA2
;ldi r16,0b00011111;(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);"1" (выход)
ldi r16,(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
out DDRB,r16
;ldi r16,0b01000000;(1<<PB6) ;
ldi r16,1<<s_int0
out PORTB,r16 ;Включение подтягивающих резисторов на входах РВ6
;ldi r16,(1<<ISC01)|(1<<ISC00) ;
ldi r16,1<<ISC01
out   MCUCR,r16   ;MCUCR режим прерываний INT0-1 по нарастанию
;ldi r16,0b11000000;(1<<INT1)|(1<<INT0) ;Разрешение прерываний INT0-1 GIMSK
ldi r16,(1<<INT1)|(1<<INT0)
out   GIMSK,r16   ;Разрешение прерываний INT0-1 GIMSK
out   GIFR,r16   ;предварительный сброс флагов прерываний ????






sei   ;Разрешение прерываний

;===================


main:

nop
nop

rjmp main;Зацикливаемся

;==================





Forward: ;Начало обработки прерывания INT0

in R2,SREG;

;sbi PINB, 4 ;
sbi PINB,led_irq0

wait_a:
;sbic PINB,s_int0
sbis PINB,s_int0
rjmp wait_a

out SREG,R2;

reti;


Back: ;Начало обработки прерывания INT1

in R2,SREG;


;sbi PINA, 4 ;
sbi PINA,led_irq1

wait_b:
;sbic PINA,s_int1
sbis PINA,s_int1
rjmp wait_b


out SREG,R2;

reti;

ts861.zip
(23.51 KiB) Скачиваний: 88

:wink:

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 14:42:11

Всем Добрый день, Здоровья и Удачи.

Прочитал сообщение что в железе работает.
Значит всё таки протеус мудрит, но странно что я пробовал в 7 протеусе,
что в 8 протеусе программа ведёт себя одинаково.
Было-бы интересно найти вариант при котором в протеусе заработает.

для BOB51 :

условия отлавливания прерываний по восходящему фронту - работа с энкодером,
а там идёт сдвиг импульсов на половину относительно друг друга.
поэтому смена направления легко определяется : при восходящем на одном, на другом будет ноль.

На ATtiny2313 работает, смена направления определяется.

СпойлерForward: ;Начало обработки прерывания INT0

sbic PinD,3 ;если вывод PD3 не 0, то нет инкремента
reti

in R2,SREG;

sbi PINB, 0 ;


out SREG,R2;

reti;


Back: ;Начало обработки прерывания INT1

sbic PinD,2 ;если вывод PD2 не 0, то нет декремента
reti

in R2,SREG;


sbi PINB, 1 ;


out SREG,R2;

reti;

Re: ATtiny861 INT1 не работает

Сб окт 16, 2021 16:03:12

Для энкодеров другой алгоритм используется.
Ёжли уж очень хочется такой вариант - просто поставить инверторы и применить мой второй вариант.
Либо меняем схемотехнику на такой вариант, где пассивным уровнем будет 0.
8)
Ответить