Господа котоводы, помогите с вопросом насущным, кто может...
В бизиборд ребёнку решил сделать светофор на Attiny13A.
Ваял в протеусе на ассемблере. По итогу симуляция работает как нужно.
Пропустил через AVR studio - там отрабатывает нормально.
Залил в контроллер, собрал на макетке - не работает как надо: нажатия отрабатывает не правильно, переключает только красный вкл/выкл, на постоянку светит зелёным.
схема:
Спойлер

asm
Спойлер
Код: Выделить всё
;============================
; Main.asm file generated by New Project wizard
;
; Created: Вс сен 30 2018
; Processor: ATtiny13A
; Compiler: AVRASM (Proteus)
;============================
.nolist ;отключение вывода листинга в файл
;============================
; Макрос вывода битов включаемых светодиодов в порт PORTB
;============================
.macro ledcol ;метка макроса
ldi temp0, @0 ;запись в регистр вывода на светодиоды побитного значения кода цвета по параметру @0
out PortB,temp0 ;вывод значения цвета в порт
.endm ;конец макроса
;============================
; Макрос задержки
;============================
.macro delay ;метка макроса
ldi counter, @1 ;здесь @1- это коэффициент повторения макроса K раз(1-255)
K:
ldi XL,Low (@0) ;Загрузить младший байт константы времени
ldi XH,high(@0) ;Загрузить старший байт константы времени
delay_:
sbrc temp1,0 ;определение срабатывания прерывания PCINT
rjmp start ;в случае, если оно произошло, переходим по метке на основной модуль
sbiw XL,1 ;вычитаем единицу из двухбайтного слова загруженного в регистровую пару ХL-XH
brne delay_ ;повторяем операцию вычитания единицы по метке delay пока XL <> 0
dec counter ;декремент значения счётчика counter
brne K ;повторяем цикл задержки по метке K пока counter <> 0
.endm ;конец макроса
;============================
.include "C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\tn13Adef.inc"
;============================
; Назначения регистров
;============================
.def tr1=r16 ;Регистр для инициализации
.def counter=r17 ;Регистр повторения количества раз *delay* имя - «counter»
.def temp0=r18 ;Регистр вывода на светодиоды
.def temp1=r19 ;Регистр указателя сработки прерывания
.def temp2=r20 ;Регистр счётчика прохода переключения сигнала в автоматическом режиме
.def repite=r21 ;Регистр количества повторений для режима мерцания зелёным
.def bms=r22 ;Регистр счётчика перключений автоматических режимов (button click select) для кнопки SWB1
.def bcc=r23 ;Регистр счётчика перключений ручных режимов (button click counter) для кнопки SWB2
;============================
; Константы
;============================
.equ all=0b00000111 ;все включены
.equ red=0b00000001 ;красный
.equ rey=0b00000011 ;красный+жёлтый
.equ yel=0b00000010 ;жёлтый
.equ gre=0b00000100 ;зелёный
.equ non=0b00000000 ;все выключены
.equ tmp0=0 ;константа с нулём
.equ rpt=3 ;количество повторений в режиме мерцания зелёным
.equ PAUSE=300000 ;константе (~0,25 c.) присвоили имя – «PAUSE»
;============================
; Адресация программного сегмента
;============================
.cseg ;начало програмного сегмента
.org 0x00 ;адрес начальной йчейки памяти
;============================
; Вектора прерываний
;============================
rjmp initial ;service_RESET
reti ;service_INT0
rjmp pcint ;service_PCI0
reti ;service_OVF0
reti ;service_ERDY
reti ;service_ACI
reti ;service_OC0A
reti ;service_OC0B
reti ;service_WDT
reti ;service_ADCC
;============================
; Инициализация: указание стека, настройка регистров, запись значений переменных
;============================
initial:
cli ;запрет прерываний
ldi tr1,low(RAMEND) ;в регистр tr1(R16) записываем адрес конечной ячейки программной области памяти R16<<RAMEND
out SPL,tr1 ;в регистр SPL записываем адрес вершины стека SPL<<R16
ldi tr1, 0b00000111 ; R16<<0X07
out DDRB,tr1 ;настройка порта: PB0-PB2 (выводы 5-7) на вывод, PB3-PB5 (выводы 2,3,1) на ввод - соответственно DDRB<<R16
ldi tr1, 0b00011000 ; R16<<0X18
out PORTB,tr1 ;включение подтягивающих резисторов: PB3, PB4 (выводы 2 и 3 соответственно) PORTB<<R16
ldi tr1,0b00100000 ; R16<<20
out GIMSK,tr1 ;установка бита PCIE (Pin Change Interrupt Enable) в GIMSK (General Interrupt Mask Register) GIMSK<<R16
ldi tr1,0b00011000 ; R16<<0X18
out PCMSK,tr1 ;установка битов PCINT3, PCINT4 в PCMSK (Pin Change Mask Register) PCMSK<<R16
;ldi tr1,0b00000010 ;
;out MCUCR,tr1 ;установка битов ISC01 и ISC00 в MCUCR (MCU Control Register (по-любому))
ldi temp1,tmp0 ;запись значений переменных в регистры данных R19 R19<<0X00
ldi temp2,1 ; R20 R20<<0X01
ldi bms,1 ; R22 R22<<0X01
ldi repite,rpt ; R21 R21<<0X03
sei ;разрешение прерываний
;============================
; Основной программный модуль
;============================
start:
ldi temp1,tmp0 ;обнуление указателя сработки прерывания R19 R19<<0
tst bms ;проверка bms на 0 R22
breq modesel ;если предыдущая операция возвращает 0 то переход по метке modesel (ручное переключение режимов)
tst bcc ;проверка bcc на 0 R23
breq main ;если предыдущая операция возвращает 0 то переход по метке main (задание автоматических режимов)
rjmp start ;зацикливаем
;============================
; Цикл переключения режимов работы
;============================
main:
cpi bms,1 ;сравнение bms=1 возвращает 0 при равенстве R22
breq mainmode ;если предыдущая операция возвращает 0 то переход по метке main (автоматическое переключение режимов)
cpi bms,2 ;сравнение bms=2 возвращает 0 при равенстве R22
breq yelblink ;если предыдущая операция возвращает 0 то переход по метке yelblink (мерцаем жёлтым)
cpi bms,3 ;сравнение bms=3 возвращает 0 при равенстве R22
breq allon ;если предыдущая операция возвращает 0 то переход по метке allon (светят все)
rjmp main
;============================
; Мерцание жёлтым
;============================
yelblink:
ledcol non ;переход к макросу ledcol с параметром non - гасим все диоды
delay PAUSE, 2 ;переход к макросу delay с параметрами PAUSE, 3
ledcol yel ;переход к макросу ledcol с параметром yel - включен жёлтый
delay PAUSE, 2 ;переход к макросу delay с параметрами PAUSE, 3
rjmp start ;возврат к главному циклу
;============================
; Включены все
;============================
allon:
ledcol all ;переход к макросу ledcol с параметром константы all - включены все диоды
delay PAUSE, 8 ;переход к макросу delay с параметрами PAUSELONG, 10
ldi bms,1 ;установка 1 в регистр r22 переменной bms R22
rjmp start ;возврат к главному циклу
;============================
; Цикл ручного выбора отображаемого сигнала
;============================
modesel:
cpi bcc,1 ;сравнение bcc=1 возвращает 0 при равенстве R23
breq redon ;если предыдущая операция возвращает 0 то переход по метке redon (красный)
cpi bcc,2 ;сравнение bcc=1 возвращает 0 при равенстве R23
breq reyon ;если предыдущая операция возвращает 0 то переход по метке redon (красный+жёлтый)
cpi bcc,3 ;сравнение bcc=1 возвращает 0 при равенстве R23
breq greon ;если предыдущая операция возвращает 0 то переход по метке redon (зелёный)
cpi bcc,4 ;сравнение bcc=1 возвращает 0 при равенстве R23
breq yelon ;если предыдущая операция возвращает 0 то переход по метке redon (жёлтый)
ldi bcc,1 ;установка 1 в регистр r23 переменной bcc R23
rjmp start ;возврат к главному циклу
;============================
; Красный
;============================
redon:
ledcol red ;переход к макросу ledcol с параметром red - включен красный
rjmp start ;возврат к главному циклу
;============================
; Красный+жёлтый
;============================
reyon:
ledcol rey ;переход к макросу ledcol с параметром rey - включен красный+жёлтый
rjmp start ;возврат к главному циклу
;============================
; Зелёный
;============================
greon:
ledcol gre ;переход к макросу ledcol с параметром gre - включен зелёный
rjmp start ;возврат к главному циклу
;============================
; Жёлтый
;============================
yelon:
ledcol yel ;переход к макросу ledcol с параметром yel - включен жёлтый
rjmp start ;возврат к главному циклу
;============================
; Автоматическая смена режимов отображаемого сигнала
;============================
mainmode:
cpi temp2,1 ;сравнение temp2=1 возвращает 0 при равенстве R20
breq redled ;если предыдущая операция возвращает 0 то переход к метке redled
cpi temp2,2 ;сравнение temp2=1 возвращает 0 при равенстве R20
breq reyled ;если предыдущая операция возвращает 0 то переход к метке reyled
cpi temp2,3 ;сравнение temp2=1 возвращает 0 при равенстве R20
breq greled ;если предыдущая операция возвращает 0 то переход к метке greled
cpi temp2,4 ;сравнение temp2=1 возвращает 0 при равенстве R20
breq greblink ;если предыдущая операция возвращает 0 то переход к метке greblink
cpi temp2,5 ;сравнение temp2=1 возвращает 0 при равенстве R20
breq yelled ;если предыдущая операция возвращает 0 то переход к метке yelled
rjmp start ;возврат к главному циклу
;============================
; Красный
;============================
redled:
ledcol red ;переход к макросу ledcol с параметром red - включен красный
delay PAUSE, 12 ;переход к макросу delay с параметрами PAUSE, 10
inc temp2 ;инкремент переменной смещения по циклу автоматического переключения режимов R20
rjmp mainmode ;возврат к циклу автоматической смены режимов отображаемого сигнала
;============================
; Красный+жёлтый
;============================
reyled:
ledcol rey ;переход к макросу ledcol с параметром red - включен красный+жёлтый
delay PAUSE, 8 ;переход к макросу delay с параметрами PAUSE, 6
inc temp2 ;инкремент переменной смещения по циклу автоматического переключения режимов R20
rjmp mainmode ;возврат к циклу автоматической смены режимов отображаемого сигнала
;============================
; Зелёный
;============================
greled:
ledcol gre ;переход к макросу ledcol с параметром red - включен зелёный
delay PAUSE, 12 ;переход к макросу delay с параметрами PAUSE, 10
inc temp2 ;инкремент переменной смещения по циклу автоматического переключения режимов R20
rjmp mainmode ;возврат к циклу автоматической смены режимов отображаемого сигнала
;============================
; Жёлтый
;============================
yelled:
ledcol yel ;переход к макросу ledcol с параметром red - включен жёлтый
delay PAUSE, 8 ;переход к макросу delay с параметрами PAUSE, 10
ldi temp2, 1 ;инкремент переменной смещения по циклу автоматического переключения режимов R20
rjmp mainmode ;возврат к циклу автоматической смены режимов отображаемого сигнала
;============================
; Мерцание зелёным
;============================
greblink:
ledcol non ;переход к макросу ledcol с параметром non - гасим все диоды
delay PAUSE, 2 ;переход к макросу delay с параметрами PAUSE, 3
ledcol gre ;переход к макросу ledcol с параметром gre - включен зелёный
delay PAUSE, 2 ;переход к макросу delay с параметрами PAUSE, 3
dec repite ;уменьшаем (декремент) число повторов включения зелёного R21
brne greblink ;если количество оставшихся повторов включения не достигло 0, то начинаем сначала
inc temp2 ;инкремент переменной смещения по циклу автоматического переключения режимов
ldi repite,rpt ;возвращаем переменной количества повторов repite исходное значение константы rpt R21
rjmp mainmode ;возврат к циклу автоматической смены режимов отображаемого сигнала
;============================
; Обработка прерываний
;============================
pcint:
ldi temp1,1 ;запись 1 в переменную temp1 - сигнализатор сработки прерывания PCINT для выхода из подпрограмм R19
sbic PINB,PB3 ;если бит в порту очищен, то пропускаем следующую команду
sbis PINB,PB3 ;если бит в порту установлен, то пропускаем следующую команду
rjmp nxt ;переход к метке nxt
inc bms ;инкремент переменной bms для смещения в программном модуле выбора автоматических режимов R22
ldi bcc,tmp0 ;запись 0 в переменную bcc для однозначного определения в главном программном модуле R23
ldi temp2,1 ;запись 1 в переменную смещения по модулю автоматического переключения режимов temp2 R20
nxt:
sbic PINB,PB4 ;если бит в порту очищен, то пропускаем следующую команду
sbis PINB,PB4 ;если бит в порту установлен, то пропускаем следующую команду
reti ;выход из прерывания
inc bcc ;инкремент переменной bcc для смещения в программном модуле ручного выбора режимов R23
ldi bms,tmp0 ;запись 0 в переменную bms для однозначного определения в главном программном модуле R22
reti ;выход из прерывания
hex:
Спойлер
Код: Выделить всё
:020000020000FC
:1000000009C01895B8C018951895189518951895A1
:1000100018951895F8940FE90DBF07E007BB08E1A4
:1000200008BB00E20BBF08E105BB30E041E061E046
:1000300053E0789430E0662371F1772309F0FACF2A
:100040006130F9F1623019F06330C1F0F9CF20E08E
:1000500028BB12E0A0EEB3E930FDECCF1197E1F739
:100060001A95C1F722E028BB12E0A0EEB3E930FDFB
:10007000E1CF1197E1F71A95C1F7DCCF27E028BB54
:1000800018E0A0EEB3E930FDD5CF1197E1F71A954E
:10009000C1F761E0CFCF713041F0723049F0733079
:1000A00051F0743059F071E0C5CF21E028BBC2CFC8
:1000B00023E028BBBFCF24E028BBBCCF22E028BB75
:1000C000B9CF413049F04230A1F04330F9F044302B
:1000D000B9F1453041F1AECF21E028BB1CE0A0EEE4
:1000E000B3E930FDA7CF1197E1F71A95C1F7439512
:1000F000E8CF23E028BB18E0A0EEB3E930FD9ACFAB
:100100001197E1F71A95C1F74395DBCF24E028BB9F
:100110001CE0A0EEB3E930FD8DCF1197E1F71A9501
:10012000C1F74395CECF22E028BB18E0A0EEB3E99B
:1001300030FD80CF1197E1F71A95C1F741E0C1CFAB
:1001400020E028BB12E0A0EEB3E930FD73CF119799
:10015000E1F71A95C1F724E028BB12E0A0EEB3E95D
:1001600030FD68CF1197E1F71A95C1F75A9541F71D
:10017000439553E0A6CF31E0B399B39B03C0639599
:1001800070E041E0B499B49B1895739560E01895C0
:00000001FF
Помогите разобраться, что не так, может у меня контроллеры подосланные.
Может кто сможет опробовать.

