Страница 5 из 7
Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 07:07:24
АндрейАвербах
Решил помучать прерывания по INT0.
В студии собрал такой вот "короче код"
Код: Выделить всё
.dseg
.cseg
.org 0
rjmp RESET ; Reset Handler
.org 0x01
rjmp EXT_INT0 ; IRQ0 Handler
.org 0x02
rjmp PCINT ; PCINT0 Handler
.org 0x03
rjmp TIM0_OVF ; Timer0 Overflow Handler
.org 0x04
rjmp EE_RDY ; EEPROM Ready Handler
.org 0x05
rjmp ANA_COMP ; Analog Comparator Handler
.org 0x06
rjmp TIM0_COMPA ; Timer0 CompareA Handler
.org 0x07
rjmp TIM0_COMPB ; Timer0 CompareB Handler
.org 0x08
rjmp WATCHDOG ; Watchdog Interrupt Handler
.org 0x09
rjmp ADC_
;RESET:
;EXT_INT0:
PCINT:
TIM0_OVF:
EE_RDY:
ANA_COMP:
TIM0_COMPA:
TIM0_COMPB:
WATCHDOG:
ADC_:
RETI
;**************************** Interrupt start
EXT_INT0:
com R17
cpi R17, 0x00
brne led0
ldi R18, 0b000001
out PORTB, R18
rjmp ledend
led0:
ldi R18, 0b000000
out PORTB, R18
ledend:
reti
;**************************** Interrupt end
;**************************** Инициализируем всю фигню
RESET: ldi R16,0b111101 ;настраиваем порты
out DDRB, R16
ldi R16, low(ramend);стэк, куда ж без него родимого
out SPL, R16
ldi R16, 0x40 ;выбираем, какое у нас прерывание
out GIMSK, R16
ldi R16, 0x03 ;ставим в режим срабатывания по нарастающему фронту сигнала
out MCUCR, R16
clr R17
sei
;*****************************Основной цикл :)
start: rjmp start
;*****************************Конец основного цикла
Моделирую в студии, но прерывание почему-то происходит и по нарастающему, и по спадающему фронту сигнала. Как так?
И будет ли такой же глюк в реальном МК (тини13а)?
Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 11:42:52
blackx
На вид все верно. Похоже на глюк в студии

Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 17:26:20
АндрейАвербах
Написал в студии такую прогу, глючит таким образом: на входе INT0 нарастающий фронт сигнала, прерывание есть, все нормально, по программе, на входе INT0 спадающий фронт сигнала(по идее МК на него реагировать не должен), вход в обработчик прерываний, перекос регистров и в результате почему-то в регистровой паре Z, в старшем регистре оказывается то значение, которое должно быть в младшем регистре и... студия весело улетает на ресет
Код: Выделить всё
.org 0
rjmp RESET ; Reset Handler
.org 0x01
rjmp EXT_INT0 ; IRQ0 Handler
.org 0x02
rjmp PCINT ; PCINT0 Handler
.org 0x03
rjmp TIM0_OVF ; Timer0 Overflow Handler
.org 0x04
rjmp EE_RDY ; EEPROM Ready Handler
.org 0x05
rjmp ANA_COMP ; Analog Comparator Handler
.org 0x06
rjmp TIM0_COMPA ; Timer0 CompareA Handler
.org 0x07
rjmp TIM0_COMPB ; Timer0 CompareB Handler
.org 0x08
rjmp WATCHDOG ; Watchdog Interrupt Handler
.org 0x09
rjmp ADC_
;RESET:
;EXT_INT0:
PCINT:
TIM0_OVF:
EE_RDY:
ANA_COMP:
TIM0_COMPA:
TIM0_COMPB:
WATCHDOG:
ADC_:
RETI
;****************************
EXT_INT0:
in R23, SREG
push R23
cpi R19, 0b00000011
brne exit_
clr R19
exit_:
ldi ZL, low(Table*2)
ldi ZH, high(Table*2)
clr R23
add ZL, R19
adc ZH, R23
lpm R24, Z+
lpm R23, Z
mov ZL, R24
mov ZH, R23
icall
inc R19
pop R23
out SREG, R23
reti
;****************************
Table:
.dw led0, led1, led2, led3
;****************************
RESET:
ldi R16, low(ramend)
out SPL, R16
ldi R16, 0b00000011
out MCUCR, R16
ldi R16, 0b01000000
out GIMSK, R16
ldi R16, 0b111101
out DDRB, R16
clr R17
clr R18
clr R19
clr R16
sei
;*************************
start:
nop
nop
nop
nop
nop
dec R17
brne start
dec R18
brne start
rcall delay_led
rjmp start
;*************************
delay_led:
cli
com R19
breq clean_led
ldi R16, 0b000001
mov R21, R20
add R21, R16
out PORTB, R21
rjmp end_led
clean_led:
clr R16
mov R21, R20
add R21, R16
out PORTB, R21
end_led:
sei
ret
;*************************
led0: ldi R20, 0b000000
mov R25, R20
add R25, R16
out PORTB, R25
ret
led1: ldi R20, 0b000100
mov R25, R20
add R25, R16
out PORTB, R25
ret
led2: ldi R20, 0b001000
mov R25, R20
add R25, R16
out PORTB, R25
ret
led3: ldi R20, 0b010000
mov R25, R20
add R25, R16
out PORTB, R25
ret
И будет ли этот глюк в реальном МК(тини13а)?
А все разобрался, виной всему было то, что я не умножил на 2 значение р19, исправил, работает как надо
Код: Выделить всё
EXT_INT0:
in R23, SREG
push R23
cpi R19, 0b00000011
brne exit_
clr R19
exit_:
lsl R19
ldi ZL, low(Table*2)
ldi ZH, high(Table*2)
clr R23
add ZL, R19
adc ZH, R23
lpm R24, Z+
lpm R23, Z
mov ZL, R24
mov ZH, R23
icall
lsr R19
inc R19
pop R23
out SREG, R23
reti
"Ветвления на индексных переходах" надо бы себе на стенку напротив стола повесить.

У студии кажись крышу сносило, когда я посылал ее на середину двубайтного слова.

Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 19:12:06
ChipKiller
АндрейАвербах писал(а):У студии кажись крышу сносило, когда я посылал ее на середину двубайтного слова.
.. не в середину двухбайтного слова, а по адресу вдвое меньшему...
в середину вот так:
Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 20:11:47
ibiza11
И этому ЧЕЛОВЕКУ 12 лет!!!!

молодец! продолжай в том же духе!
Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 20:13:02
Kavka
ChipKiller писал(а):.. не в середину двухбайтного слова, а по адресу вдвое меньшему...
в середину вот так:
Это так же приведёт к загрузке неправильного адреса в Z. А "отправить" (передать управление) на середину слова у AVRок не получиться никак.
Re: Теория и практика AVR ассемблера.
Добавлено: Сб июн 01, 2013 20:24:44
ChipKiller
Kavka писал(а):(передать управление) на середину слова у AVRок не получиться никак.
... тема уже
поднималась - PC у AVR считает слова, а не байты ....
ibiza11 писал(а):И этому ЧЕЛОВЕКУ 12 лет!!!!

молодец!
... согласен - "копает" с энтузиазмом

Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 05:31:52
АндрейАвербах
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 06:49:28
АндрейАвербах
Нацарапал следующую программку
Код: Выделить всё
ldi R16, low(ramend)
out SPL, R16
ldi R16, 0b101111
out DDRB, R16
clr R18
clr R24
clr R25
;******************************
end_: in R17, PINB
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
brne end_
;******************************
d: cpi R18, 0b00000011
brne c
clr R18
c: inc R18
lsl R18
ldi ZL, low(led*2)
ldi ZH, high(led*2)
clr R19
add ZL, R18
adc ZH, R19
lpm R20, Z+
lpm R19, Z
mov ZL, R20
mov ZH, R19
lsr R18
;*******************************
st1: subi ZL, (-1)
lpm R21, Z
rcall delay
out PORTB, R21
subi ZL, (-2)
lpm R21, Z
rcall delay
out PORTB, R21
subi ZL, (-3)
lpm R21, Z
rcall delay
out PORTB, R21
subi ZL, (-4)
lpm R21, Z
rcall delay
out PORTB, R21
rjmp st1
;*****************************************
led: .dw led1, led3
led1: .db 0b000001, 0b000010, 0b000100, 0b001000
led3: .db 0b001000, 0b000100, 0b000010, 0b000001
;*****************************************
delay:
b: in R17, PINB
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
breq d
dec R24
brne b
dec R25
brne b
ret
Суть в следующем: это бегающий огонек, он должен изменять направление своего бега по нажатию кнопки.
Проблема: огонек не бегает (проверка в студии была), а там где он должен бегать, на выходах ВСЕ еденицы
Как это исправить?
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 07:10:02
ChipKiller
АндрейАвербах писал(а):Нацарапал следующую программку
1. привыкай писать комментарии, хотя бы в заголовке функций(процедур) - проще будет понять, что пытаешься сделать
2. посмотри про макросы - писанина уменьшится
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 10:20:13
АндрейАвербах
Похимичил с прогой
ldi R16, low(ramend) ;инициализация всего, что нужно
out SPL, R16
ldi R16, 0b101111
out DDRB, R16
clr R18
ldi R22, 1
clr R23
clr R24
clr R25
;******************************
end_: in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
brne end_ ;да? идем отсюда
;******************************
d: cpi R18, 0b00000011 ;проверяем значение регистра, ответственного за переключение массивов
brne c
clr R18
c: inc R18 ;увеличиваем его значение
lsl R18 ;умножаем на два
ldi ZL, low(led*2)
ldi ZH, high(led*2)
clr R19
add ZL, R18
adc ZH, R19
lpm R20, Z+
lpm R19, Z
mov ZL, R20
mov ZH, R19
lsr R18 ;уменьшаем в два раза
;*******************************
st1:cpi R22, 0x05 ;основной цикл;проверяем значение регистра, ответственного за переключение данных в массиве
brne f
ldi R22, 1
f:
add ZL, R22
adc ZH, R23
lpm
out PORTB, R0 ;выводим значение в порт
rcall delay ; вызываем задержку
inc R22 ;увеличиваем регистр
rjmp st1
;*****************************************
led: .dw led1, led3 ;таблица массивов
led1: .db 0b000001, 0b000010, 0b000100, 0b001000 ;собственно таблицы эффектов
led3: .db 0b001000, 0b000100, 0b000010, 0b000001
;*****************************************
delay:
b: in R17, PINB ;цикл задержки, во время него опрашиваем кнопку, если кнопка нажата - переключаем эффект
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
breq d
dec R24
brne b
dec R25
brne b
ret
Петрушка та же. В порте "б" выдает какую-то хрень.
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 10:43:15
Vov123
За эту неделю,которую ты пытаешься постичь "теорию и практику AVR ассемблера" можно было раза 3 прочитать вот эту брошюрку:
http://obuk.ru/4117-mikrokontrollery-av ... kurs..html
и найти все ответы на свои вопросы.
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 10:48:21
Alexeyslav
Это всегда бывает когда пытаешься решить что-то наскоком.
Ты ведь даже в своей программе теряешься -чего стоит метка "end_" которая вовсе не обозначает какой-либо конец, однобуквенные метки... немудрено потеряться в этой программе!
Стирай все до последнего символа, и начинай сначала. Иногда проще переписать все заново чем пытаться оживить трупик.
Программа должна иметь четкую структуру, каждую часть которой легко проверить сверив вход и выход.
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 11:38:54
АндрейАвербах
Забил я на старую программу, сделал новую, вот
Код: Выделить всё
ldi R16, low(ramend) ;инициализация всего, что нужно
out SPL, R16
ldi R16, 0b101111
out DDRB, R16
clr R18
clr R22
clr R23
clr R24
clr R25
;******************************
end_: in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
brne end_ ;да? идем отсюда
;******************************
d: cpi R18, 0b00000010 ;проверяем значение регистра, ответственного за переключение массивов
brne c
clr R18
c:
lsl R18 ;умножаем на два
ldi ZL, low(led*2)
ldi ZH, high(led*2)
clr R19
add ZL, R18
adc ZH, R19
lpm R20, Z+
lpm R19, Z
mov ZL, R20
mov ZH, R19
lsr R18 ;уменьшаем в два раза
inc R18 ;увеличиваем его значение
icall
rjmp d
;*******************************
led2: cpi R22, 4
brne f
ldi R22, 0
f:
ldi ZL, low(led1*2)
ldi ZH, high(led1*2)
add ZL, R22
adc ZH, R23
lpm
out PORTB, R0
rcall delay
inc R22
rjmp led2
led4: cpi R22, 4
brne t
ldi R22, 0
t:
ldi ZL, low(led3*2)
ldi ZH, high(led3*2)
add ZL, R22
adc ZH, R23
lpm
out PORTB, R0
rcall delay
inc R22
rjmp led4
;*****************************************
led: .dw led2, led4 ;таблица массивов
led1: .db 0b000001, 0b000010, 0b000100, 0b001000 ;собственно таблицы эффектов
led3: .db 0b001000, 0b000100, 0b000010, 0b000001
;*****************************************
delay:
b: in R17, PINB ;цикл задержки, во время него опрашиваем кнопку, если кнопка нажата - переключаем эффект
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
breq d
dec R24
brne b
dec R25
brne b
ret
Alexeyslav, эта программа сделана по базе старой, но так как я во время написания этой программы выпроваживал из дому одного человека, то программа получилась очень темной и корявенькой.
Vov123, не похоже на брошюрку, но почитаю, обучаюсь авр асму по нашей обучалке и курсу на изиэлектроникс.
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 11:54:22
ChipKiller
АндрейАвербах писал(а):Код: Выделить всё
end_: in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
brne end_ ;да? идем отсюда
...слишком "заумно" - есть команда SBIC/SBIS
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 11:58:28
Alexeyslav
Это не новая программа, это старая. В ней ничего принципиально не поменялось. Огромные безымянные нагромождения кода, в которых запутаться очень легко а читать невозможно.
Где структура у программы? Что за странная метка "end_" несущая прямо таки противоположный смысл? что за метки из одной буквы? Немудрено запутаться в таком коде!
Не начинайте сразу писать программу, начните для начала с блок-схемы алгоритма который пытаетесь реализовать.
Такую проверку нажатия кнопки можно было сократить до двух строк кода... есть ведь ЦЕЛАЯ инструкция которая проверяет нужный бит порта!!!
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 12:19:34
АндрейАвербах
Не ругайте сильно, учусь ведь только.
Такую проверку нажатия кнопки можно было сократить до двух строк кода... есть ведь ЦЕЛАЯ инструкция которая проверяет нужный бит порта!!
Ну в начале проги да. А в задержке мне нужно побольше команд и не тупых вроде ноп, ноп, ноп
Что за странная метка "end_" несущая прямо таки противоположный смысл?
Я писал Вам в каких условиях создавалась эта программа, сделал так
Код: Выделить всё
start: in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
lsr R17
lsr R17
lsr R17
lsr R17
cpi R17, 0b000001
brne start ;да? идем отсюда
есть команда SBIC/SBIS
А она проверяет конкретный бит? Просто про нее я не слышал.
Все, поправил.
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 12:24:05
Kavka
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 12:59:21
ChipKiller
АндрейАвербах писал(а):Не ругайте сильно
... никто не ругает - только поправляют
А в задержке мне нужно побольше команд и не тупых вроде ноп, ноп...
.. для длительных программных задержек можно использовать такую конструкцию
Код: Выделить всё
.equ XL_CLOCK = 8000000 ; частота тактирования
.........
.macro _delay_us
.if ((@0*XL_CLOCK/1000000)/4)>0x10000
.error "Overflow r25:r24"
.else
ldi r24,low((@0*XL_CLOCK/1000000)/4)
ldi r25,high((@0*XL_CLOCK/1000000)/4)
sbiw r25:r24,1
brne PC-1
.endif
.endm
............
; вставляем там, где нужна задержка
_delay_us 300 ; задержка 300 мкс
......
Re: Теория и практика AVR ассемблера.
Добавлено: Вс июн 02, 2013 14:16:00
АндрейАвербах
Впервые вижу, но сильно замарачиваться смысла не вижу, идея прикольная!
