Ассемблер (ASM) для AVR в вопросах и ответах
- DJ_Kiridza
- Мучитель микросхем
- Сообщения: 458
- Зарегистрирован: Пн дек 13, 2010 13:01:59
- Откуда: Украина
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
ага, т.е. тупо взять с даташита и подставить свои метки для перехода... ок, поняв... я просто первый раз пишу.. пасиб, буду знать!
мысли мысли штош вы вйотесь
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
DJ_Kiridza писал(а):ага, т.е. тупо взять с даташита и подставить свои метки для перехода... ок, поняв... я просто первый раз пишу.. пасиб, буду знать!
Да, в даташитах описано много готовых примеров (правда, не всегда верно =). Плюс ко всему, много интересного можно посмотреть в АппНотах.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- DJ_Kiridza
- Мучитель микросхем
- Сообщения: 458
- Зарегистрирован: Пн дек 13, 2010 13:01:59
- Откуда: Украина
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
угу, пасиб, буду иметь ввиду... 
мысли мысли штош вы вйотесь
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
над мойейу головойу
вы там мосга нинайдете
нед там мосга! йа тупойе (БОР)
- AndyWorld
- Прорезались зубы
- Сообщения: 209
- Зарегистрирован: Вт сен 30, 2008 09:23:14
- Откуда: Краснодарский край
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Прочитал в ДШ что команды SBIC SBIS влияют на FIFO UART. И рекомендуют использовать эти команды с осторожностью. А у меня как раз случилась проблема. Я проверяю на одной ноге наличие напряжения этими командами. Пихаю байт в порт. Получаю ответ. Это в автомате через 1 сек от таймера. Но вот когда мерию температуру мне нужно передать 4 байта, и после этого все слетает с катушек. Может прийти несколько запросов выдать бит напряжения, или отправится несколько раз температура. Вроде как где то накопились запросы и они обрабатываются несвоевременно. Может буфер ТХ нужно увеличить до 32х бит?
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Помоему проще сделать несколько проверок и записать результаты в ОЗУ. Потом отдельно отправить результаты из ОЗУ по UART и обработать ответы. После этого снова замеры и запись результатов в ОЗУ и снова отправка и обработка ответов. И так по кругу. То есть сначала в ОЗУ и от туда в UART.
I am DX168B and this is my favourite forum on internet!
- Necroteeth
- Потрогал лапой паяльник
- Сообщения: 362
- Зарегистрирован: Вс окт 10, 2010 17:43:48
- Откуда: Воронеж
Re: Ассемблер (ASM) для AVR в вопросах и ответах
подскажите, плиз, как грамотнее всего В КОНКРЕТНОМ МЕСТЕ программы запустить таймер. после задания какого регистра таймер сразу начинает работать?
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Ассемблер (ASM) для AVR в вопросах и ответах
после его включения =) регистр который настраивает частоту тактов (предделитель) таймера. если в регистре 0 - таймер остановлен. если !0 - считает
Ставим плюсы: )
- Switch
- Открыл глаза
- Сообщения: 48
- Зарегистрирован: Пн фев 07, 2011 00:42:25
- Откуда: Из затерянного мира.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Таймер заработает после того, как включится подделитель.
Отключив подделитель, можно поставить таймер на "паузу".
При настройках таймера, подделитель желательно запускать в последнюю очередь.
Отключив подделитель, можно поставить таймер на "паузу".
При настройках таймера, подделитель желательно запускать в последнюю очередь.
-
Ruslan-maniak
- Открыл глаза
- Сообщения: 40
- Зарегистрирован: Вт янв 18, 2011 08:15:32
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Здрасте всем. Изучаю сейчас передачу по уарту и столкнулся с такой проблемой. Не вызывается прерывание по опустошению UDR. Вот небольшой кусочек программы, даже исходя из него и независимо от кода инициализации уарта должно вызываться это прерывание(5-8 строки). Но увы. Подскажите кто-нить что я не так делаю.
main: LDI R17,low(String1*2)
LDI R18,high(String1*2)
STS StringAdres,R17
STS StringAdres+1,R18
LDI R16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE)
OUT UCSRB, R16
LDI R16,0
OUT UDR,R16
JMP main
PS. Проверял код в АВР-студии и Протеусе.
main: LDI R17,low(String1*2)
LDI R18,high(String1*2)
STS StringAdres,R17
STS StringAdres+1,R18
LDI R16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE)
OUT UCSRB, R16
LDI R16,0
OUT UDR,R16
JMP main
PS. Проверял код в АВР-студии и Протеусе.
- Rimsky
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Вт июн 15, 2010 07:16:42
- Откуда: Иркутск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А где инициализация скорости передачи и формата фрейма?
Вот тебе небольшой пример.
А вообще советую чаще заглядывать в доку!
Вот тебе небольшой пример.
Код: Выделить всё
;----------
; инициализация аппартного юарта на прием - передачу
; вход: Y - символьная константа
; ресурс: r16
; 9600 бод
; формат ответа модема ”<\r><\n><response><\r><\n>”
;----------
INIT_HUART:
; Set baud rate
ldi YL, low (51)
ldi YH, high (51)
sts UBRR0L, YL
sts UBRR0H, YH
; Enable receiver and transmitter
; инициализируем прерывания на прием и передау данных
ldi r16, (1<<TXCIE0)|(1<<TXEN0)|(1<<RXCIE0)|(1<<RXEN0)
sts UCSR0B, r16
; Set frame format: 8data, 1stop bit
ldi r16, (3<<UCSZ00)
sts UCSR0C, r16
cbi FLAGS, HU_COM_FLG ; инициализируем прием
retА вообще советую чаще заглядывать в доку!
-
Ruslan-maniak
- Открыл глаза
- Сообщения: 40
- Зарегистрирован: Вт янв 18, 2011 08:15:32
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Да всё это есть. и без использования этого прерывания всё работало и передавалось. Меня интересует какой фактор может повлиять на то что прерывание не вызывается, так как
LDI R16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE)
OUT UCSRB, R16
и даже принудительно обнуляю UDR
LDI R16,0
OUT UDR,R16
Что ещё нужно этому прерыванию для вызова?
LDI R16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE)
OUT UCSRB, R16
и даже принудительно обнуляю UDR
LDI R16,0
OUT UDR,R16
Что ещё нужно этому прерыванию для вызова?
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ruslan-maniak писал(а):и даже принудительно обнуляю UDR
Гы, вы его обнуляете, а прерывание-то по опустошению
Глобально прерывания разрешены? Стэк инициализирован?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Только что хотел про то-же написать, но опередили. 
I am DX168B and this is my favourite forum on internet!
-
Ruslan-maniak
- Открыл глаза
- Сообщения: 40
- Зарегистрирован: Вт янв 18, 2011 08:15:32
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А, точно, разрешение на глоб.прерывания забыл. Большое спасибо. 

- Roman Venom
- Сверлит текстолит когтями
- Сообщения: 1135
- Зарегистрирован: Сб июл 11, 2009 18:42:21
- Откуда: Украина, г.Николаев
Re: Ассемблер (ASM) для AVR в вопросах и ответах
такая проблемка. если код программы относительно небольшой (например как ниже), то с адресацией прерываний проблем нету.
А вот если код увеличивается в объёме... Например, добавляется кода в обработке прерывания таймера 1. То прерывания после установления флага не работают. А некоторые выбрасывает не на свой адрес в таблице прерываний. Как с этим бороться?
Код: Выделить всё
;Прога делает следующее. Управляет скоростью мигания светика(PD6), путём переноса числа из буфера ЮСАРТа в регистры 16-битного таймера№1.
.device ATmega16
.nolist
.include "D:\Program Files\Atmel\AVR Studio\Appnotes\m16def.inc"
.list
;********************************
;определяем переменные
;рабочие:
.def work=r16
.def work1=r17
.def h_part=r19
.def l_part=r20
.def t_count1_L=r21
.def count1_symbol=r22
.def t_count0=r23
.def t_count1_H=r24
.def speed_value=r25
;порты:
;PORTD
.equ UH=PD6
.equ ADC0_ram=0x0 ;0x1
.equ ADC1_ram=0x14;
.equ ADC2_ram=0x28
.equ ADC3_ram=0x3C
.equ ADC4_ram=0x50
.equ ADC_count_ram=0x0;0x2
.equ TMR1_ram=0x2
.equ byte_count=0x4
;********************************
.cseg
.org 0x0010
;*****************************
jmp RESET ; Reset Handler
jmp EXT_INT0 ; IRQ0 Handler
jmp EXT_INT1 ; IRQ1 Handler
jmp TIM2_COMP ; Timer2 Compare Handler
jmp TIM2_OVF ; Timer2 Overflow Handler
jmp TIM1_CAPT ; Timer1 Capture Handler
jmp TIM1_COMPA ; Timer1 CompareA Handler
jmp TIM1_COMPB ; Timer1 CompareB Handler
jmp TIM1_OVF ; Timer1 Overflow Handler
jmp TIM0_OVF ; Timer0 Overflow Handler
jmp SPI_STC ; SPI Transfer Complete Handler
jmp USART_RXC ; USART RX Complete Handler
jmp USART_UDRE ; UDR Empty Handler
jmp USART_TXC ; USART TX Complete Handler
jmp ADC ; ADC Conversion Complete Handler
jmp EE_RDY ; EEPROM Ready Handler
jmp ANA_COMP ; Analog Comparator Handler
jmp TWSI ; Two-wire Serial Interface Handler
jmp EXT_INT2 ; IRQ2 Handler
jmp TIM0_COMP ; Timer0 Compare Handler
jmp SPM_RDY ; Store Program Memory Ready Handler
EXT_INT0:ret
EXT_INT1:ret
TIM2_COMP:ret
TIM2_OVF:ret
TIM1_CAPT:ret
TIM1_COMPA:ret
TIM1_COMPB:ret
;TIM1_OVF:
TIM0_OVF:ret
SPI_STC:ret
;USART_RXC:
USART_UDRE:ret
USART_TXC:
ldi YH,0x2;извлекаем значение счётчика
ldi r28,byte_count
ld work,Y+
cpi work,1
breq USART_TXC_exit
inc work
ldi YH,0x2
ldi r28,byte_count
st Y+, work
;cbi UCSRA,TXC
ldi YH,0x1
ldi r28,ADC0_ram
ld work,Y+
ld work1,Y+
sbi PORTC, PC7
nop
nop
out UDR,work1
nop
nop
nop
nop
out UDR,work
reti
USART_TXC_exit:
cbi PORTC, PC7
;---clear byte_count
clr work
ldi YH,0x2
ldi r28,byte_count
st Y+,work
;---
cbi UCSRA,TXC
cbi UCSRB,TXCIE
reti
;ADC:ret
EE_RDY:ret
ANA_COMP:ret
TWSI:ret
EXT_INT2:ret
TIM0_COMP:ret
SPM_RDY:ret
;****************************
; ///TMR1 OVF///
;****************************
TIM1_OVF:
;запретить прерывания по переполнению
;извлекаем номер периода и продолжаем счёт
clr work
out TCCR1B,work;останов таймера
out TCNT1H,work;сбросить таймер-счётчик
out TCNT1L,work
ser work
out TIFR,work;cбросить флаги таймеров
main:
ldi YH,0x2
ldi r28,TMR1_ram
ld work1,Y+
mov t_count1_H,work1;записать число с компа в реги.
;ldi work1,10
mov t_count1_L,work1
exit_1:
ldi work,0b00000011
out TCCR1B,work;пуск таймера 1 с преддел.
out TCNT1H,t_count1_H;записать число с компа в реги таймера
out TCNT1L,t_count1_L
clr work1
sbis PORTD,UH;светик вкл?
rjmp led_on;
rjmp led_off;тогда вырубить
exit:
;sbi ADCSR,ADSC
;sbi UCSRB,TXCIE
reti
;----------
led_on:
sbi PORTD,UH
rjmp exit
led_off:
cbi PORTD,UH
rjmp exit
;****************************
; ///USATR RXC///
;****************************
USART_RXC:
sbi UCSRB,TXCIE
;cbi UCSRA,TXC
ldi work,0b00000000;stop timer1
out TCCR1B,work;
cbi PORTC, PC7
nop
nop
in work1,UDR;cчитываем байт
ldi YH,0x1
ldi r28,TMR1_ram
st Y,work1
sbi PORTC, PC7
nop
nop
out UDR,work1
nop
nop
ldi work,0b00000011;предделитель
out TCCR1B,work
reti
ADC:
;cbi ADCSR,ADEN
clr work
out TCCR1B,work;останов таймера
;----///извлекаем значение счётчика///
ldi YH,0x2
ldi r28,ADC_count_ram
ld work,Y
;----------
cpi work,0
breq ADC_0
cpi work,1
breq ADC_1
cpi work,2
breq exit_ADC
ADC_0:
ldi YH,0x1
in work,ADCL
in work1,ADCH
ldi r28,ADC0_ram
st Y+,work;ADC0H
st Y+,work1;ADC0L,
rjmp exit_ADC
ADC_1:
in work,ADCL
in work1,ADCH
ldi YH,0x1
ldi r28,ADC1_ram
st Y+,work
st Y+,work1
exit_ADC:
ldi YH,0x2
ldi r28,ADC_count_ram
ld work,Y+
inc work
ldi YH,0x2
ldi r28,ADC_count_ram
st Y+,work
;ldi work,0b00000011
;out TCCR1B,work;останов таймера
cpi work,2
breq clear_ADC_count_ram
rjmp exit_ADC1
exit_ADC1:
ldi work,0b00000011
out TCCR1B,work;останов таймера
reti
clear_ADC_count_ram:
clr work
ldi YH,0x2
ldi r28,ADC_count_ram
st Y,work
rjmp exit_ADC1
RESET:
ldi r16,high(RAMEND) ; Main program start
out SPH,r16 ; Set stack pointer to top
ldi r16,low(RAMEND)
out SPL,r16
sei ; Enable interrupts
; ///PORTA///
ldi work,0b10001111
out DDRA,work
clr work
out PORTA,work
; ///PORTD///
ldi work,0b11111111
out DDRD,work
ldi work,0b01000000;светик на РД6
out PORTD,work
; ///PORTD///
ldi work,0b00011111
out DDRB,work
; ///PORTC///
ldi work,0b10000000
out DDRC,work
;***********************************
; ///настройка таймера 1 на прерывание по переполнению///
ldi work,0b00000000;stop timer1
out TCCR1B,work;
ldi t_count1_H,0x00;
ldi t_count1_L,0x00;
out TCNT1H,t_count1_H;clr TCNT
out TCNT1L,t_count1_L;clr TCNT1
ldi work,0b00000100;разрешить прерывание по переполн. таймера1
out TIMSK,work
;***********************************
; ///настройка USART///
; Set baud rate
ldi work,23;предделитель для 19200бодов при частотe 7.3728МГц
out UBRRL,work
; Enable receiver and transmitter
ldi work,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(0<<UDRIE);разрешить П/П, разрешить прерывание по принятому байту в UDR
out UCSRB,work
; Set frame format: 8data, 1 stop bit, no parity
ldi work,0b10000110;(URSEL, UCSZ1, UCSZ0)
out UCSRC,work
ldi work,0b00001110;(URSEL=0) - доступ к записи UBRRH
out UCSRC,work
clr work;
out UBRRH,work;в книгах не видел, но на форумах читал что надо очищать его.
;out UCSRA,work
cbi UCSRB,RXCIE;запрет на прерывание по принятому байту.
sbi UCSRB,TXCIE
;***********************************
; ///настройка АЦП///
;*настройка опорного напряжения, смещения, выбор кол-ва входов*
ldi work,0b00000000
out ADMUX,work;5 каналов АЦП, смещение вправо, 5 входов
;*вкл/выкл АЦП опорного напряжения, смещения, выбор кол-ва входов*
ldi work,0b11001110
out ADCSR,work
;*****************************
;main loop
;*****************************
main_loop:
ldi work,0b00000011;предделитель
out TCCR1B,work
out TCNT1H,t_count1_H;заряжем таймер первым значением
out TCNT1L,t_count1_L
sbi UCSRB,RXCIE;разрешаем прерывание "байт с компа в буфере"
;---------///clr SRAM///----------
clear_SRAM:
clr work1
clr work
;---------clr ADC0_ram
ldi YH,0x1
ldi r28,ADC0_ram
clear_ADC0_ram:
inc work1
st Y+,work
cpi work1,20
brne clear_ADC0_ram
clr work1
;---------clr ADC1_ram
ldi YH,0x1
ldi r28,ADC1_ram
clear_ADC1_ram:
inc work1
st Y+,work
cpi work1,20
brne clear_ADC1_ram
clr work1
;---------clr ADC2_ram
ldi YH,0x1
ldi r28,ADC2_ram
clear_ADC2_ram:
inc work1
st Y+,work
cpi work1,20
brne clear_ADC2_ram
clr work1
;---------clr ADC3_ram
ldi YH,0x1
ldi r28,ADC3_ram
clear_ADC3_ram:
inc work1
st Y+,work
cpi work1,20
brne clear_ADC3_ram
clr work1
;---------clr ADC4_ram
ldi YH,0x1
ldi r28,ADC4_ram
clear_ADC4_ram:
inc work1
st Y+,work
cpi work1,20
brne clear_ADC4_ram
clr work1
;---------clr ADC_count_ram
clr work
ldi YH,0x2
ldi r28,ADC_count_ram
st Y,work
;---------clr TMR1_ram
ldi YH,0x2
ldi r28,TMR1_ram
st Y,work
main_loop_1:
sbi ADCSR,ADSC
rjmp main_loop_1
А вот если код увеличивается в объёме... Например, добавляется кода в обработке прерывания таймера 1. То прерывания после установления флага не работают. А некоторые выбрасывает не на свой адрес в таблице прерываний. Как с этим бороться?
Успех - императив!
- Pooher
- Мучитель микросхем
- Сообщения: 491
- Зарегистрирован: Вс янв 07, 2007 01:45:48
- Откуда: Российская Федерация, будь она неладна...
Re: Ассемблер (ASM) для AVR в вопросах и ответах
;********************************
.cseg
.org 0x0010
;*****************************
jmp RESET ; Reset Handler
;..................
И что бы это значило...?
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Ахинея у вас с векторами.
У таких МК, как MEGA16, каждый вектор идёт через адрес.
Выход из прерывания делается по команде RETI, а не RET.
Скопируйте из даташита вектора и заменяйте значения $00Х на .org 0x000X так, как я показал выше.
Следующий приём поможет сократить размер писанины:
То есть комментите векторы и сразу там пишете RETI
Если Вам потребуется какой-нибудь вектор, то сотрёте RETI вместе с точкой с запятой и пишете после векторов обработчик со своей меткой.
В конце векторов начинаете писать свои обработчики, например всё можно заменить проще:
У таких МК, как MEGA16, каждый вектор идёт через адрес.
Код: Выделить всё
.org 0x0000
jmp RESET ; Reset Handler
.org 0x0002
jmp EXT_INT0 ; IRQ0 Handler
.org 0x0004
jmp EXT_INT1 ; IRQ1 Handler
.org 0x0006
jmp TIM2_COMP ; Timer2 Compare Handler
.org 0x0008
jmp TIM2_OVF ; Timer2 Overflow Handler
....................
..............................
Выход из прерывания делается по команде RETI, а не RET.
Скопируйте из даташита вектора и заменяйте значения $00Х на .org 0x000X так, как я показал выше.
Следующий приём поможет сократить размер писанины:
Код: Выделить всё
.org 0x0000
jmp RESET ; Reset Handler
.org 0x0002
reti ; jmp EXT_INT0 ; IRQ0 Handler
.org 0x0004
reti ; jmp EXT_INT1 ; IRQ1 Handler
.....................
..............
То есть комментите векторы и сразу там пишете RETI
Если Вам потребуется какой-нибудь вектор, то сотрёте RETI вместе с точкой с запятой и пишете после векторов обработчик со своей меткой.
В конце векторов начинаете писать свои обработчики, например всё можно заменить проще:
Код: Выделить всё
.cseg
.org 0x0000
rjmp RESET
.org 0x001A
rjmp USART_TXC ; USART TX Complete Handler
;***************************************
.org INT_VECTORS_SIZE
USART_TXC:
;Ваш код обработки прерывания USART
reti
;***************************************
RESET:
;Отсуда начинается ваша программа
ldi r16, Low(RAMend)
out SPL, r16
ldi r16, High(RAMend)
out SPH, r16
;Далее настраиваете порты, USART и все остальное.
sei ;Разрешим прерывания и едем далее по своей программе.
I am DX168B and this is my favourite forum on internet!
- Roman Venom
- Сверлит текстолит когтями
- Сообщения: 1135
- Зарегистрирован: Сб июл 11, 2009 18:42:21
- Откуда: Украина, г.Николаев
Re: Ассемблер (ASM) для AVR в вопросах и ответах
DX168B
Спасибо, сделал как вы советовали, но результат остался прежним
.
А потом... Оказалось что я - идиот, и в новом проекте не указал имя устройства, поэтому и не работало.
П.С. В итоге результат положительный, РадиоКот опять помог
Pooher
Уже начинались танцы с бубном, но всё без толку
Спасибо, сделал как вы советовали, но результат остался прежним
А потом... Оказалось что я - идиот, и в новом проекте не указал имя устройства, поэтому и не работало.
П.С. В итоге результат положительный, РадиоКот опять помог
Pooher
И что бы это значило...?
Уже начинались танцы с бубном, но всё без толку
Успех - императив!
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Я как понял, Вы недавно начали осваивать МК?
По поводу векторов: Возьмите и сравните вектора из даташитов на ATTINY2313 и ATMEGA16
А именно обратите внимание на адреса векторов.
У тини2313 они перечисляются по порядку, а вот в меге16 перечисляются через один адрес.
Чтобы правильно их расставить, существует директива .org (address) Каждый вектор располагается в своём порядке. Когда срабатывает прерывание, то рабочую точку программы бросает на соответствующий адрес. Там лежит команда jmp куда-то. Если вектор не нужен, то можно сразу записать туда reti. Или записать только используемые вектора, расположив их директивами .org
Например, из всех векторов нам нужны только прерывание TIM1_OVF , USART_RXC и ADC
Тогда поступим так:
Будут вопросы, выкладывайте суда. Поможем.
По поводу векторов: Возьмите и сравните вектора из даташитов на ATTINY2313 и ATMEGA16
А именно обратите внимание на адреса векторов.
У тини2313 они перечисляются по порядку, а вот в меге16 перечисляются через один адрес.
Чтобы правильно их расставить, существует директива .org (address) Каждый вектор располагается в своём порядке. Когда срабатывает прерывание, то рабочую точку программы бросает на соответствующий адрес. Там лежит команда jmp куда-то. Если вектор не нужен, то можно сразу записать туда reti. Или записать только используемые вектора, расположив их директивами .org
Например, из всех векторов нам нужны только прерывание TIM1_OVF , USART_RXC и ADC
Тогда поступим так:
Код: Выделить всё
.cseg
.org 0x0000
jmp RESET ;От суда мы идем в начало программы, после подачи питания.
.org 0x0010
jmp TIM1_OVF ;От суда мы идём в обработку прерывания по переполнению таймера 1
.org 0x0016
jmp USART_RXC ;От суда мы идём в обработку прерывания приёма данных с USART
.org 0x001C
jmp ADC ;От суда мы идём в обработку прерывания АЦП
.org INT_VECTORS_SIZE ;Это указывает на конец таблицы векторов прерываний
;**********************************************
; Тут наши обработчики прерываний
;**********************************************
TIM1_OVF:
; Код обработчика по переполнению таймера 1
reti
;----------
USART_RXC:
; Код обработчика по приёму данных с USART
reti
;----------
ADC:
; Код обработчика АЦП
reti
;**********************************************
; Тут наша основная программа (начало)
;**********************************************
RESET:
ldi r16, Low(RAMend)
out SPL, r16
ldi r16, High(RAMend)
out SPH, r16
................
.........
.............
Будут вопросы, выкладывайте суда. Поможем.
I am DX168B and this is my favourite forum on internet!
- Roman Venom
- Сверлит текстолит когтями
- Сообщения: 1135
- Зарегистрирован: Сб июл 11, 2009 18:42:21
- Откуда: Украина, г.Николаев
Re: Ассемблер (ASM) для AVR в вопросах и ответах
DX168B
Ага.
Благодарю за совет!
П.С. Написал программу, но в ней были задействованы рег. пары (не хватало регистров; в этом плане с пиками удобнее). Сейчас вот решил обойтись парочкой регистров и ОЗУ (20 тактов мне не решают ничего). Вот и вылезли приколы... Зато ликбез очередной получился, что не может не радовать.
Я как понял, Вы недавно начали осваивать МК?
Ага.
Чтобы правильно их расставить, существует директива .org (address) Каждый вектор располагается в своём порядке. Когда срабатывает прерывание, то рабочую точку программы бросает на соответствующий адрес. Там лежит команда jmp куда-то. Если вектор не нужен, то можно сразу записать туда reti. Или записать только используемые вектора, расположив их директивами .org
Например, из всех векторов нам нужны только прерывание TIM1_OVF , USART_RXC и ADC
Тогда поступим так:
Благодарю за совет!
П.С. Написал программу, но в ней были задействованы рег. пары (не хватало регистров; в этом плане с пиками удобнее). Сейчас вот решил обойтись парочкой регистров и ОЗУ (20 тактов мне не решают ничего). Вот и вылезли приколы... Зато ликбез очередной получился, что не может не радовать.
Успех - императив!