Теория и практика AVR ассемблера.

Обсуждаем контроллеры компании Atmel.
Ответить
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Решил помучать прерывания по 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а)?
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

На вид все верно. Похоже на глюк в студии :?
Изображение only pure true norwegian blackx Изображение
Реклама
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Написал в студии такую прогу, глючит таким образом: на входе INT0 нарастающий фронт сигнала, прерывание есть, все нормально, по программе, на входе INT0 спадающий фронт сигнала(по идее МК на него реагировать не должен), вход в обработчик прерываний, перекос регистров и в результате почему-то в регистровой паре Z, в старшем регистре оказывается то значение, которое должно быть в младшем регистре и... студия весело улетает на ресет :cry:

Код: Выделить всё

.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
"Ветвления на индексных переходах" надо бы себе на стенку напротив стола повесить. :))
У студии кажись крышу сносило, когда я посылал ее на середину двубайтного слова. :)
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

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

Код: Выделить всё

ldi ZL, low(Table*2)+1
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

И этому ЧЕЛОВЕКУ 12 лет!!!! :beer: молодец! продолжай в том же духе!
Ставим плюсы: )
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ChipKiller писал(а):.. не в середину двухбайтного слова, а по адресу вдвое меньшему...
в середину вот так:
Это так же приведёт к загрузке неправильного адреса в Z. А "отправить" (передать управление) на середину слова у AVRок не получиться никак.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

Kavka писал(а):(передать управление) на середину слова у AVRок не получиться никак.
... тема уже поднималась - PC у AVR считает слова, а не байты ....
ibiza11 писал(а):И этому ЧЕЛОВЕКУ 12 лет!!!! :beer: молодец!
... согласен - "копает" с энтузиазмом :wink:
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Спасибо, приятно слышать :) :) :)
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Нацарапал следующую программку

Код: Выделить всё

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
Суть в следующем: это бегающий огонек, он должен изменять направление своего бега по нажатию кнопки.
Проблема: огонек не бегает (проверка в студии была), а там где он должен бегать, на выходах ВСЕ еденицы :o :shock:
Как это исправить?
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

АндрейАвербах писал(а):Нацарапал следующую программку
1. привыкай писать комментарии, хотя бы в заголовке функций(процедур) - проще будет понять, что пытаешься сделать
2. посмотри про макросы - писанина уменьшится
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Похимичил с прогой
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


Петрушка та же. В порте "б" выдает какую-то хрень.
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Сообщение Vov123 »

За эту неделю,которую ты пытаешься постичь "теорию и практику AVR ассемблера" можно было раза 3 прочитать вот эту брошюрку:
http://obuk.ru/4117-mikrokontrollery-av ... kurs..html
и найти все ответы на свои вопросы.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Это всегда бывает когда пытаешься решить что-то наскоком.
Ты ведь даже в своей программе теряешься -чего стоит метка "end_" которая вовсе не обозначает какой-либо конец, однобуквенные метки... немудрено потеряться в этой программе!

Стирай все до последнего символа, и начинай сначала. Иногда проще переписать все заново чем пытаться оживить трупик.

Программа должна иметь четкую структуру, каждую часть которой легко проверить сверив вход и выход.
Контактная информация:
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Забил я на старую программу, сделал новую, вот

Код: Выделить всё

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, не похоже на брошюрку, но почитаю, обучаюсь авр асму по нашей обучалке и курсу на изиэлектроникс.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение ChipKiller »

АндрейАвербах писал(а):

Код: Выделить всё

end_:   in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
   lsr R17
   lsr R17
   lsr R17
   lsr R17
   cpi R17, 0b000001
   brne end_ ;да? идем отсюда
...слишком "заумно" - есть команда SBIC/SBIS
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Это не новая программа, это старая. В ней ничего принципиально не поменялось. Огромные безымянные нагромождения кода, в которых запутаться очень легко а читать невозможно.

Где структура у программы? Что за странная метка "end_" несущая прямо таки противоположный смысл? что за метки из одной буквы? Немудрено запутаться в таком коде!

Не начинайте сразу писать программу, начните для начала с блок-схемы алгоритма который пытаетесь реализовать.

Такую проверку нажатия кнопки можно было сократить до двух строк кода... есть ведь ЦЕЛАЯ инструкция которая проверяет нужный бит порта!!!
Контактная информация:
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Не ругайте сильно, учусь ведь только. :(
Такую проверку нажатия кнопки можно было сократить до двух строк кода... есть ведь ЦЕЛАЯ инструкция которая проверяет нужный бит порта!!
Ну в начале проги да. А в задержке мне нужно побольше команд и не тупых вроде ноп, ноп, ноп :)
Что за странная метка "end_" несущая прямо таки противоположный смысл?
Я писал Вам в каких условиях создавалась эта программа, сделал так

Код: Выделить всё

start:	in R17, PINB ;проверяем нажата ли кнопка, нет? крутимся дальше!
	lsr R17
	lsr R17
	lsr R17
	lsr R17
	cpi R17, 0b000001
	brne start ;да? идем отсюда
есть команда SBIC/SBIS
А она проверяет конкретный бит? Просто про нее я не слышал.
Все, поправил.

Код: Выделить всё

start:	SBIS PINB, 4
	rjmp start
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Сообщение 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 мкс
......
Потрогал лапой паяльник
Сообщения: 345
Зарегистрирован: Пт авг 24, 2012 09:45:40
Откуда: Абакан, Хакасия

Сообщение АндрейАвербах »

Впервые вижу, но сильно замарачиваться смысла не вижу, идея прикольная! :)
Ответить

Вернуться в «AVR»