Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ПТУ-шник »

СКАЗОЧНИК писал(а):
По первому вопросу не могу ниче вразумительного сказать. Вообще-то так не принято. Все делают бесконечный цикл. Может ваш компилятор посчитал, что его надо вставить и сделал это сам. Может так и есть, если дошел до конца памяти, то прыгает на начало (или сбрасывается, что скорее всего). Однако, это сильно криво, так делать. :dont_know:
Компилятор из AVR Studio 4. Кодил в ней, результат тот же.


На кнопку реагирует нормально. Хоть как жмякай. У меня attiny13 работает от встроенного генератора по умолчанию, во фьюзы пока не лазию.
Реклама
<>
Shark-vc
Родился
Сообщения: 6
Зарегистрирован: Сб дек 05, 2015 23:21:05

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Shark-vc »

Народ, помогите пожалуйста, пытаюсь подключить ЖКИ HD44780 к ATmega8535 , вроде собрал правильно, но все равно не работает, мб в коде ошибка? Вроде делаю все по инструкции

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

   #define RS 2							
   #define e  3

;НАСТРОЙКА И ВЫВОД НА ЖКИ----------------------------------------------------------------------
   ser temp
   out DDRA,temp        ;порт РА на вывод
   ldi temp,$0C        ;PC0-PC1,PD4 на ввод
   out PORTC,temp
   rcall delay2ms
   ldi acc,$38      ;8-битовый режим вывода,
   rcall lcdcom      ;2 строки, шрифт 5х7
   ldi acc,$06      ;Направление сдвига курсора вправо, без сдвига дисплея
   rcall lcdcom
   ldi acc,$0C      ;включить дисплей
   rcall lcdcom      ;погасить курсор
   ldi acc,$01      ;Очистить дисплей и установить курсор в нулевую позицию
   rcall lcdcom
   rcall delay2ms
   ldi     acc,0x31   ; загрузить цифру "1" в регистр lcd
   rcall lcddat
 rjmp Loop
 
     ;Подпрограмма вывода на дисплей байта данных
lcddat:
   out PORTA,acc      ;вывод символа
   ldi temp,0x04      ;установка режима записи данных E=1
   out PORTC,temp
   cbi PORTC,e      ;фронт 1/0 строба
   rcall delay40us
   ret
 
     ;Подпрограмма вывода на дисплей байта команды
lcdcom:
   out PORTA,acc      ;вывод команды
   ldi temp,0x08      ;установка режима записи команд 
   out PORTC,temp
   ldi temp,0x04      ;установка режима записи команд E=1
   out PORTC,temp
   cbi PORTC,e      ;фронт 1/0 строба
   rcall delay40us
   ret
Вложения
Безымянный.png
СХЕМА
(84.68 КБ) 435 скачиваний
Реклама
гостевая2
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Поправил. Не хотел писать пп DELAY, поэтому закомментировал их.
Спойлер

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

	.include "m8535def.inc"

.equ	RS=2                     
.equ	E=3
;   #define RS 2                     
;   #define E  3
.def	TEMP=R16
.def	ACC=R17

	LDI	ZH,HIGH(RAMEND)
	LDI	ZL,LOW(RAMEND)
	OUT	SPH,ZH
	OUT	SPL,ZL



;НАСТРОЙКА И ВЫВОД НА ЖКИ----------------------------------------------------------------------
   ser temp
   out DDRA,temp        ;порт РА на вывод
   LDI	R22,1<<RS|1<<E
   OUT	DDRC,R22

;   ldi temp,$0C        ;PC0-PC1,PD4 на ввод???
;   out PORTC,temp ;PC0-PC1,PD4 на вЫвод???

;   rcall delay2ms
   ldi acc,$38      ;8-битовый режим вывода,
   rcall lcdcom      ;2 строки, шрифт 5х7
   ldi acc,$06      ;Направление сдвига курсора вправо, без сдвига дисплея
   rcall lcdcom
   ldi acc,$0C      ;включить дисплей
   rcall lcdcom      ;погасить курсор
   ldi acc,$01      ;Очистить дисплей и установить курсор в нулевую позицию
   rcall lcdcom
;   rcall delay2ms
   ldi     acc,0x31   ; загрузить цифру "1" в регистр lcd
   rcall lcddat
LOOP:
 rjmp Loop
 
     ;Подпрограмма вывода на дисплей байта команды
lcdcom:
	CBI	PORTC,RS      ;установка режима записи команд
	RJMP	LCDDAT+1

     ;Подпрограмма вывода на дисплей байта данных
lcddat:
	SBI	PORTC,RS      ;установка режима записи данных
	RCALL	PAUSE_RET
	SBI	PORTC,E
	RCALL	PAUSE_RET
	out PORTA,acc      ;вывод символа
	RCALL	PAUSE_RET
	CBI	PORTC,E
;   ldi temp,0x04      ;установка режима записи данных E=1
;   out PORTC,temp
;   cbi PORTC,e      ;фронт 1/0 строба
;   rcall delay40us
PAUSE_RET:
	ret
 
Инициировать дисплей желательно без отступлений от DS
Аватара пользователя
Flash.#13
Держит паяльник хвостом
Сообщения: 965
Зарегистрирован: Сб апр 12, 2014 23:46:03
Откуда: Киев

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Flash.#13 »

Здравствуйте товарищи, возникла накладка с АЦП. Настроил ADCSRA, настроил ADMUX, Ref прописал питание +5В, замер делается нормально. Затем следующий замер Ref прописываю внутренний 2.56В, делаю два замера с задержкой для отсева переключения, а на выходе бяка. Щупаю тестером ножку Aref а там и близко не пахнет 2.56В, как быть?

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

...
ldi R16, 0b01000000	;РС0, +5VCC
out ADMUX, R16
sbi ADCSRA,6		;старт замера АЦП
rcall delay40mks
rcall delay40mks
rcall delay40mks
rcall delay40mks
sbi ADCSRA,6		;старт замера АЦП, х2 для точности, все ок
...
ldi R16, 0b11000000	;РС0, +2.56V internal source
out ADMUX, R16
sbi ADCSRA,6		;старт замера АЦП
rcall delay40mks
rcall delay40mks
rcall delay40mks
rcall delay40mks
sbi ADCSRA,6		;старт замера АЦП, х2
//и ничего, нету 2.56 на ноге Aref, и замер чего-попало
Немного файлов по зажиганию: ФУОЗ 2.2 + программа правки таблиц 0.987, монтажка
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ПТУ-шник »

Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя
temp это переменная R16 в РОН.

Такая программа даже не компилируется. Примерно понял почему она не работает - регистр TIMSK однобитный, остальные 7 бит к шине не подключены поэтому туда никакие значения запихнуть нельзя. И как быть?

Видел такой пример:

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

ldi temp,(1<<TOIE0) ;разр. прерывания Timer0
out TIMSK,temp
Но не очень понимаю как это работает. Вроде тоже самое что и у меня. Вот эту скобку (1<<TOIE0) я вообще не понимаю. Зачем то сдвиг числа сюда запихнули. Я знаю что TOIE0 это тот бит который нужно установить в «1» но как тут к нему обратились?
Реклама
гостеваая 3
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Такая программа даже не компилируется.
На что ругается?
Примерно понял почему она не работает - регистр TIMSK однобитный
Не угадали, в AVR все регистры 8-битные. Может, кроме совсем уж внутренних, к которым нет прямого доступа.
Вот эту скобку (1<<TOIE0) я вообще не понимаю.
Это хороший тон форматирования - не использовать магических чисел, а использовать именованные константы. Совсем хорошо, когда константы поименованы разработчиком системы, как здесь. Суть всего лишь в установке бита номер TOIE0, то есть с точки зрения компилятора не отличается от вашей записи.
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jack_A »

ПТУ-шник писал(а):Видел такой пример:

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

ldi temp,(1<<TOIE0) ;разр. прерывания Timer0
out TIMSK,temp
Но не очень понимаю как это работает. Вроде тоже самое что и у меня. Вот эту скобку (1<<TOIE0) я вообще не понимаю. Зачем то сдвиг числа сюда запихнули. Я знаю что TOIE0 это тот бит который нужно установить в «1» но как тут к нему обратились?
TOIE0 - это просто номер бита в регистре. Ничего там на самом деле не двигается, просто такая запись говорит компилятору : " Установи в temp бит номер такой-то в 1" . А не компилироваться может вот почему: в разных поколениях АВРок регистры могут быть в разных диапазонах адресов, что, конечно, нехорошо. Поэтому то, что в одном МК проходит как OUT, в другом выглядие как STS, потому что не входит в диапазон адресов, к которым допустима команда OUT. Конкретно мы ничего не знаем о типе обсуждаемого тут МК, да и по ДШ шарить - мне лениво. Но это одна из версий.
Изображение
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

ПТУ-шник писал(а):Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя
Такая программа даже не компилируется.
Естественно, не должна, т.к. TOIE0 у ATtiny13 стоит в другом месте. А когда командуете (1<<TOIE0), то ассемблер сам определяет положение этого бита.
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ПТУ-шник »

akl писал(а):
ПТУ-шник писал(а):Как настроить таймер в Attiny13 в ассемблере? Я пытаюсь сделать так:

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

LDI temp, 0b00000001
OUT TIMSK, temp ;  Разрешение прерывания от таймер TIM0
LDI temp, 0b00000101
OUT TCCR0, temp ; установка пред. делителя
Такая программа даже не компилируется.
Естественно, не должна, т.к. TOIE0 у ATtiny13 стоит в другом месте. А когда командуете (1<<TOIE0), то ассемблер сам определяет положение этого бита.
Хм. Именно в этом случае ему оказывается без разницы. Ошибка: TIMSK это неверное название, надо TIMSK0. Пробывал устанавливать нулевой бит, компилятор молчит.

А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял.

По совету поставил за место out, sts и ошибок вылезло ещё больше :o

Всё равно не понял эту (1<<TOIE0) команду. Можете объяснить по подробней? Хочу более глубинно понять что происходит внутри, а то этот << арифметический сдвиг меня смущает. И почему эта команда в скобках? Это макрос какой то? Хочу видеть исходник если это макрос.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение СКАЗОЧНИК »

Как-то так работал с таймером на ТИНИ13... Не помню уже чего там понакалякал... :))) Но что-то даже работало.
Спойлер

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

; ******************************************************
; * Автор: СКАЗОЧНИК 								   *                           
; * Дата: 10.10.2014                                   *                                              
; * Версия: 140831                                     *                                            
; * Имя файла: ИК управление    					   *                                      
; * Для AVR: ATTiny13                                  *                                                    
; * Тактовая частота: 9,6 MHz	            		   *
; * Среда разработки: AVR Studio 4.12				   *
; *													   *
; * Выполняемые функции: 					           *
; *    											       *
; * 									               *
; ******************************************************

; ================
; ПОДКЛЮЧАЕМЫЕ БИБЛИОТЕКИ (.include)
; ================

	.include "tn13def.inc"	

; ============
; ТИП МИКРОКОНТРОЛЛЕРА (.device)
; ============

	.device ATtiny13
 
; =================
; ОБЪЯВЛЕНИЯ И КОНСТАНТЫ (.def, .equ)
; =================
 
	.def	temp = R16
	.def	TIME = R17	
	.def	FLAG = R18
	.def	LADR = R19
	.def	HADR = R20
	.def	LCMD = R21
	.def	HCMD = R22
	.def	CNT = R23
	.def 	RUN = R24
	.def	SCREEN = R25
	.def 	YYY	= R26
			
; ====
; МАССИВЫ И Т.Д. (.eseg) EEPROM (.db, .dw)
; ====
	
	.eseg

; =================
; МАКРОСЫ (.MACRO)
; =================

	.MACRO PUSHF	; Положить СРЕГ в стек
		push r16
		in r16, SREG
		push r16
	.ENDM

	.MACRO POPF		; Достать СРЕГ из стека
		pop r16
		out SREG, r16
		pop r16
	.ENDM

; ******************************
; НАЧАЛО ПРОГРАММЫ (.cseg) FLASH
; ******************************
	
	.cseg

; ------------------
; ВЕКТОРЫ ПРЕРЫВАНИЙ
; ------------------
	
	rjmp RESET 			; Reset Handler
 	rjmp INT0add 		; External Interrupt0 Handler
 	rjmp PCI0add 		
 	rjmp OVF0add 	
 	rjmp ERDYadd 	
	rjmp ACIadd		
	rjmp OC0Aadd 	
	rjmp OC0Badd 	
	rjmp WDTadd	
	rjmp ADCCadd 	
	
		;RESET: 		; Reset Handler
		;INT0add: 		; External Interrupt0 Handler
		PCI0add: 		
		OVF0add: 	
		ERDYadd: 	
		ACIadd: 		
		OC0Aadd: 	
		OC0Badd: 	
		WDTadd: 	
		ADCCadd: 	
	
	reti			; Выход из прерываний, которые не используются

; ----------------------
; ОБРАБОТЧИКИ ПРЕРЫВАНИЙ
; ----------------------
		
	INT0add:

		PUSHF
			
			in TIME, TCNT0		; Закидываем в Тайм значение счетчика, будем использовать его позже
			clr temp
			out TCNT0, temp		; Первоначально очищаем счетный регистр раймера 
			inc CNT	
			ldi YYY, 1
		
		POPF
		
	reti						; Выходим из прерывания

;	OVF0add:

;		inc CNT

;	reti

; **************************************************************************************************
; ИНИЦИАЛИЗАЦИЯ МК (логическое начало основной программы) ******************************************
; **************************************************************************************************

;           --------- конфигурация портов -----------------------------------------------           

	Reset:	ldi temp, (1<<PB4)|(1<<PB3)|(0<<PB2)|(0<<PB1)|(0<<PB0)			; Конфигурация порта
			out DDRB, temp	

			ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
			out PORTB, temp

			ldi temp, (1<<INT0)		; Разрешить прерывание 
			out GIMSK, temp

			ldi temp, (1<<ISC01)|(0<<ISC00)			; Настраиваем прерывание по низкому уровню (на ИНТ0)
			out MCUCR, temp
			
			ldi temp, low(RAMEND)	; Загрузка указателя стека
			out SPL, temp
			
			ldi temp, 0x00			; Конфигурация таймера
			out TCCR0A, temp
			ldi temp, (1<<CS02)|(0<<CS01)|(1<<CS00)	; Тактовый сигнал = CK/1024 (ЗАПУСКАЕМ ТАЙМЕР)
        	out TCCR0B, temp

			clr FLAG				; Просто очищаем 
			clr TIME
			clr CNT
			clr RUN
			clr SCREEN
			clr YYY
		 	
;           ---------- разрешение прерываний --------------------------------------------			

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

; *******************************************************************************************************************
; ОСНОВНАЯ ПРОГРАММА (основной цикл) ********************************************************************************
; *******************************************************************************************************************

	Start:	
		
		cpi YYY, 1
		brbs SREG_Z, KOD
		rjmp Start

		KOD: rcall NULONE

		cpi RUN, 1
		brbs SREG_Z, KOD1

		rjmp Start

		KOD1: rcall DRIWER

	rjmp	Start	; Конец программы, переход на начало

; *******************************************************************************************************************
; ПОДПРОГРАММЫ ******************************************************************************************************
; *******************************************************************************************************************

	NULONE:					; Заполнение 4 переменных нулями и единицами с послыл
		
			cpi FLAG, 0
			brbc SREG_Z, A1	; 
			inc FLAG
			clr YYY
			ret

	A1:		cpi FLAG, 1
			brbc SREG_Z, A2
		
				cpi TIME, 120		; Проверка 122 < T < 130
				brlo END
				cpi TIME, 132
				brsh END

						N:	ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(0<<PB1)|(1<<PB0)	; Стоп мотор
							out PORTB, temp	
							rjmp N


			inc FLAG
			clr CNT
			clr YYY
			ret

	A2: 	cpi FLAG, 2
			brbc SREG_Z, END

				cpi TIME, 8			; Проверка 8 < T < 12
				brbs SREG_C, END
				cpi TIME, 12
				brbc SREG_C, ONE
			
					clc				; Убираем флаг С
					rol LCMD		; Задвигаем ноль в самый правый разряд
					rol HCMD		; и по очереди сдвигаем все байты влево
					rol LADR		; В итогде, вся цепочка переместилась влево на один бит, а старший вывалился... 
					rol HADR
					rjmp TT			; Все, вышли .

		ONE: 	cpi TIME, 18		; Проверка 18 < T < 22
				brbs SREG_C, END
				cpi TIME, 22
				brbc SREG_C, END
		
					sec				; 
					rol LCMD		; 
					rol HCMD		; 
					rol LADR		; 
					rol HADR
									
		TT: 	cpi CNT, 32
				brbs SREG_Z, PROVERKA

					clr YYY
					ret

		PROVERKA: 	cpi HADR, 0b00010000
					brbc SREG_Z, END
					cpi LADR, 0b11001000
					brbc SREG_Z, END
					cpi HCMD, 0b11100001
					brbc SREG_Z, END
					cpi LCMD, 0b00011110
					brbc SREG_Z, END

					clr FLAG
					clr CNT
					clr YYY
					ldi RUN, 1

					ret
		
		END:
			
			clr FLAG
			clr CNT
			clr YYY
			clr RUN
		
	ret

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

	DRIWER:

		clr temp	; Запретить прерывание 
		out GIMSK, temp

		cpi SCREEN, 0b00000000		; Проверяем флаг, опущен экран или поднят
		brbc SREG_Z, UP

			ldi temp, (0<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)	; Запускаем мотор вниз, а на остальных оставляем поддтяжку
			out PORTB, temp

		TUDA:	ldi temp, (1<<TOIE0) ; Разрешить прерывание по переполнению таймера
				out TIMSK0, temp
				clr temp
				out TCNT0, temp							; счетный регистр раймера
			;	ldi temp, (1<<CS02)|(0<<CS01)|(1<<CS00)	; Тактовый сигнал = CK/1024 (ЗАПУСКАЕМ ТАЙМЕР)
        	;	out TCCR0B, temp

		NEXT:	cpi CNT, 2			; ждем, пока таймер проткает 3 раза примерно 100 мсек
				brbc SREG_Z, NEXT	; Тупо задержка по таймеру

				clr temp 			;Запретить прерывание по переполнению таймера
				out TIMSK0, temp				
	    		out TCCR0B, temp
				
		NEXT1:	sbic PINB, 0		; Пропускаем следующую, если бит очищен (датчик сработал, прижал вывод к земле)
				rjmp NEXT1			; а если не очищен, то продолажем крутиться и ждать, пока датчик не сработает

				ldi temp, (0<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)	; Стоп мотор
				out PORTB, temp

				com SCREEN			; переворачиваем флаг положения экрана

				rjmp EX 			; Выходим

		UP: 	ldi temp, (1<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)	; Запускаем мотор вверх
				out PORTB, temp

				rjmp TUDA

	EX:		
			clr FLAG				; Просто очищаем 
			clr TIME
			clr CNT
			clr RUN
			clr YYY
				
		ldi temp, (1<<INT0)		; Разрешить прерывание 
		out GIMSK, temp
		ldi temp, (1<<ISC01)|(0<<ISC00)			; Настраиваем прерывание по низкому уровню (на ИНТ0)
		out MCUCR, temp

	ret

							
Всё равно не понял эту (1<<TOIE0) команду. Можете объяснить по подробней? Хочу более глубинно понять что происходит внутри, а то этот << арифметический сдвиг меня смущает. И почему эта команда в скобках? Это макрос какой то? Хочу видеть исходник если это макрос.
Для начала надо разобраться, подключена ли у вас библиотека с определениями всех этих названий????

.include "tn13def.inc"

А потом все просто. Запись (1<<TOIE0) говорит запихать единицу в бит ТОIE0 в регистре. А бит TOIE0 определен в подключенной библиотеке (см. выше), если ее открыть, то можно его там найти и понять что ему присвоено. Сделано это для "удобочитаемости", как вам уже и ответили выше. В скобках, потому что так и читать удобнее. А по поводу вообще команды <<, читайте инструкции к ассемблеру. В гугле их очень много.
Можно было вместо (1<<TOIE0) написать (1<<3), что означало бы, задвинуть (сделать так, чтобы было) единицу в позицию третьего бита.

Вот пример:

ldi temp, (1<<INT0) ; Разрешить прерывание
out GIMSK, temp

Запихиваем единицу в бит INT0 регистра temp, т.е. бит INT0 у нас объявлен в подключенной библиотеке (без нее работать не будет), а там он может записан быть непосредственно для этого микроконтроллера как 0. Т.е. INT0=0. Значит,
ldi temp, (1<<0)

что означает запихать единицу в нулевой бит регистра temp, а по сути, сделать это:

ldi temp,0b00000001

но читается верхнее лучше.

После этого мы просто копируем темп в нужный нам регистр.
Последний раз редактировалось СКАЗОЧНИК Чт дек 17, 2015 18:34:05, всего редактировалось 1 раз.
Станислав
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Demiurg »

ПТУ-шник писал(а):...
Вложения
jhytfcyf.jpg
(64.53 КБ) 449 скачиваний
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Z_h_e »

ПТУ-шник писал(а):эту (1<<TOIE0) команду
Это не команда. TOIE0 - это константа и ее значение может быть разным. И еще зависит от среды программирования. В AVR STUDIO надо было в исходник включать специальный файл, в котором были прописаны константы именного того контроллера, для которого пишется код. Другая среда может сама подключить все файлы для нужного контроллера.
Во включаемом файле может быть, например, такая строка:

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

TOIE0 equ 0x03
Это означает что компилятор встретив TOIE0 заменит ее на 0x03.

Запись (1<<TOIE0) скажет компилятору, что надо 1 сдвинуть влево 0x03 раз. И компилятор заменит (1<<TOIE0) на 0b00001000 (0x08).
Следующие две команды будут скомпилированы в один и тот же код.

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

ldi R16,(1<<TOIE0)
ldi R16,0x08
Последний раз редактировалось Z_h_e Чт дек 17, 2015 19:41:45, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение СКАЗОЧНИК »

Да. ))) Выше дорисовал тоже самое, может и не так понятно..
Станислав
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Jack_A »

Глянул в ДЩ на тини13 - регистры таймера в "нормальной области", так что своим STSом я чуть не ввел в заблуждение, как Сусанин. Но для других МК, напр. мега48, вышеописанное имеет место.
Изображение
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Z_h_e »

СКАЗОЧНИК писал(а): Запись (1<<TOIE0) говорит запихать единицу в бит ТОIE0 в регистре.
Очень некорректное объяснение. Тогда Запись 2<<TOIE0 будет говорит запихать двойку в бит ТОIE0 в регистре? :).

Кстати скобки совсем не обязательно ставить в данном случае.

Следующие команды будут скопмилированы в один и тот же код.

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

ldi R16,0x06
ldi R16,(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0)
ldi R16,(1<<ADPS2)+(1<<ADPS1)+(0<<ADPS0)
ldi R16,(1<<ADPS2)+(1<<ADPS1)
ldi R16,0x03<<1
ldi R16,0x0C>>1
ldi R16,3+3

Это биты регистра ADCSRA для тиньки13. Но собственно это не имеет значения сейчас.

Запись (0<<ADPS0) тоже имеет смысл. Потом, например в процессе отладки, если будет необходимость, Вы легко замените значение бита на 1 не заглядывая даташит, кроме того она указывает что такой бит существует, просто Вы в данном случае сбросили его.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Demiurg »

ПТУ-шник писал(а):А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял
Вложения
jhytfcyf.jpg
(64.53 КБ) 511 скачиваний
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение СКАЗОЧНИК »

Z_h_e писал(а):Тогда Запись 2<<TOIE0 будет говорит запихать двойку в бит ТОIE0 в регистре?
:))) :facepalm:
Да, правильно будет так:
"Возвращает левое выражение, сдвинутое влево на число бит указанное справа"

Только хотел еще и вот это показать, а вы уже написали.

ldi temp, (1<<PB4)|(0<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0) ; Запускаем мотор вверх
out PORTB, temp
Станислав
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ILYAUL »

Demiurg писал(а):
ПТУ-шник писал(а):А вот с TCCR0 всё равно ругаеться, пишет что и раньше: Undefined variable referenced. Тобишь недопустимый адрес как я понял
Мне тоже стало интересно, сколько ты ещё сделаешь попыток донести правду TC. Знаешь , после пятой попытки , выложи чуть другое изо, может сравнительный анализ поможет
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Demiurg »

ILYAUL писал(а):...
Думаю, ник ПТУ-шник все за себя говорит...
ПТУ-шник
Нашел транзистор. Понюхал.
Сообщения: 167
Зарегистрирован: Чт янв 01, 2015 16:34:55

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ПТУ-шник »

Спасибо, вроде с программой разобрались. Компилятор не ругается :)

По поводу команды. Со скобками понятно, это приоритет операции или просто оформление. С символом << разобрался это сдвиг числа влево. Получаеться команда

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

LDI temp, (1<<2)
Дано число 0b00000001 оно по команде сдвига << сдвинет его так 0b00000100 и запишет в temp. Тоже самое делает с TOIE0.

Всё спасибо, стало понятно.
Ответить

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