Приветствую всех форумчан! Начинающий в программировании. Пишу программу на ассемблере в AVR Studio для ATmega16. И что-то не сходятся вектора прерываний. В документации указано, что прерывание по переполнению T1 находится на векторе 8. А в программе - по факту на 15-м. Может кто подскажет, что это. Может особенность какая-то.
И ещё вопрос: для перехода в подпрограмму обработки прерываний какую команду обычно используют? RJMP или RCALL? И для выхода из подпрограммы прерывания применяют RETI только для того, чтобы глобально разрешить прерывания? А если это не нужно - пойдет и RET?
у ATmega16 на каждое прерывание идет по 2 адреса, чтобы применять команду JMP. 9 - это номер прерывания, а не адрес. а адрес равен 0х10. а команда reti - это 1 адрес. поэтому нельзя просто делать для вектора "затычку" в 1 адрес. и нельзя просто делать одноадресный rjmp. а чтобы "потратить" на один вектор 2 адреса, для reti и для rjmp нужно добавлять nop.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.
start: jmp init reti reti reti reti reti reti reti reti reti reti reti reti reti reti rjmp T1; reti reti reti reti reti reti
Адресация в 16-й меге 16-ти битная. Т.е. jmp init - это 0x0000 а ваше T1 - это 0x0010 (16-е место, но с 0x0000 17-е место, но никак не 15-е, и в коде вашем походу ошибка)
Если остальные прерывания не нужны, то можете записать:
Код:
.cseg .org 0x0000 jmp init .org 0x0010 jmp T1
Вместо T1 пишите лучше T1_OVF, потом самому понятнее будет.
Добавлено after 1 minute 9 seconds: T1 на 16-м месте в вашем коде.. вообще ни там ни сям
Просто надо использовать то, что в соответствующем *.inc файле описания ресурсов МК указано... Ищем ДИСК:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes и там для меги 16 m16def.inc или m16Adef.inc на всякий случай копируем в отдельное место (дабы исходный не убить) и читаем содержимое (а далее им пользуемся). Естественно этот файлик всегда надо в проект подключать Спойлер
Код:
.nolist .include "m16def.inc" .list
К примеру тот же m16def.inc: Спойлер
Код:
;***** THIS IS A MACHINE GENERATED FILE - DO NOT EDIT ******************** ;***** Created: 2011-08-25 20:59 ******* Source: ATmega16.xml ************ ;************************************************************************* ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number : AVR000 ;* File Name : "m16def.inc" ;* Title : Register/Bit Definitions for the ATmega16 ;* Date : 2011-08-25 ;* Version : 2.35 ;* Support E-mail : avr@atmel.com ;* Target MCU : ATmega16 ;* ;* DESCRIPTION ;* When including this file in the assembly program file, all I/O register ;* names and I/O register bit names appearing in the data book can be used. ;* In addition, the six registers forming the three data pointers X, Y and ;* Z have been assigned names XL - ZH. Highest RAM address for Internal ;* SRAM is also defined ;* ;* The Register names are represented by their hexadecimal address. ;* ;* The Register Bit names are represented by their bit number (0-7). ;* ;* Please observe the difference in using the bit names with instructions ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" ;* (skip if bit in register set/cleared). The following example illustrates ;* this: ;* ;* in r16,PORTB ;read PORTB latch ;* sbr r16,(1<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#) ;* out PORTB,r16 ;output to PORTB ;* ;* in r16,TIFR ;read the Timer Interrupt Flag Register ;* sbrc r16,TOV0 ;test the overflow flag (use bit#) ;* rjmp TOV0_is_set ;jump if set ;* ... ;otherwise do something else ;*************************************************************************
; GIFR - General Interrupt Flag Register .equ INTF2 = 5 ; External Interrupt Flag 2 .equ INTF0 = 6 ; External Interrupt Flag 0 .equ INTF1 = 7 ; External Interrupt Flag 1
; MCUCR - General Interrupt Control Register .equ ISC00 = 0 ; Interrupt Sense Control 0 Bit 0 .equ ISC01 = 1 ; Interrupt Sense Control 0 Bit 1 .equ ISC10 = 2 ; Interrupt Sense Control 1 Bit 0 .equ ISC11 = 3 ; Interrupt Sense Control 1 Bit 1
; MCUCSR - MCU Control And Status Register .equ ISC2 = 6 ; Interrupt Sense Control 2
; ***** EEPROM *********************** ; EEDR - EEPROM Data Register .equ EEDR0 = 0 ; EEPROM Data Register bit 0 .equ EEDR1 = 1 ; EEPROM Data Register bit 1 .equ EEDR2 = 2 ; EEPROM Data Register bit 2 .equ EEDR3 = 3 ; EEPROM Data Register bit 3 .equ EEDR4 = 4 ; EEPROM Data Register bit 4 .equ EEDR5 = 5 ; EEPROM Data Register bit 5 .equ EEDR6 = 6 ; EEPROM Data Register bit 6 .equ EEDR7 = 7 ; EEPROM Data Register bit 7
; ***** ANALOG_COMPARATOR ************ ; SFIOR - Special Function IO Register .equ ACME = 3 ; Analog Comparator Multiplexer Enable
; ACSR - Analog Comparator Control And Status Register .equ ACIS0 = 0 ; Analog Comparator Interrupt Mode Select bit 0 .equ ACIS1 = 1 ; Analog Comparator Interrupt Mode Select bit 1 .equ ACIC = 2 ; Analog Comparator Input Capture Enable .equ ACIE = 3 ; Analog Comparator Interrupt Enable .equ ACI = 4 ; Analog Comparator Interrupt Flag .equ ACO = 5 ; Analog Compare Output .equ ACBG = 6 ; Analog Comparator Bandgap Select .equ ACD = 7 ; Analog Comparator Disable
; ***** AD_CONVERTER ***************** ; ADMUX - The ADC multiplexer Selection Register .equ MUX0 = 0 ; Analog Channel and Gain Selection Bits .equ MUX1 = 1 ; Analog Channel and Gain Selection Bits .equ MUX2 = 2 ; Analog Channel and Gain Selection Bits .equ MUX3 = 3 ; Analog Channel and Gain Selection Bits .equ MUX4 = 4 ; Analog Channel and Gain Selection Bits .equ ADLAR = 5 ; Left Adjust Result .equ REFS0 = 6 ; Reference Selection Bit 0 .equ REFS1 = 7 ; Reference Selection Bit 1
; ADCSRA - The ADC Control and Status register .equ ADCSR = ADCSRA ; For compatibility .equ ADPS0 = 0 ; ADC Prescaler Select Bits .equ ADPS1 = 1 ; ADC Prescaler Select Bits .equ ADPS2 = 2 ; ADC Prescaler Select Bits .equ ADIE = 3 ; ADC Interrupt Enable .equ ADIF = 4 ; ADC Interrupt Flag .equ ADATE = 5 ; When this bit is written to one,the Timer/Counter2 prescaler will be reset.The bit will be cleared by hardware after the operation is performed.Writing a zero to this bit will have no effect.This bit will always be read as zero if Timer/Counter2 is clocked by the internal CPU clock.If this bit is written when Timer/Counter2 is operating in asynchronous mode,the bit will remain one until the prescaler has been reset. .equ ADFR = ADATE ; For compatibility .equ ADSC = 6 ; ADC Start Conversion .equ ADEN = 7 ; ADC Enable
; ADCH - ADC Data Register High Byte .equ ADCH0 = 0 ; ADC Data Register High Byte Bit 0 .equ ADCH1 = 1 ; ADC Data Register High Byte Bit 1 .equ ADCH2 = 2 ; ADC Data Register High Byte Bit 2 .equ ADCH3 = 3 ; ADC Data Register High Byte Bit 3 .equ ADCH4 = 4 ; ADC Data Register High Byte Bit 4 .equ ADCH5 = 5 ; ADC Data Register High Byte Bit 5 .equ ADCH6 = 6 ; ADC Data Register High Byte Bit 6 .equ ADCH7 = 7 ; ADC Data Register High Byte Bit 7
; ADCL - ADC Data Register Low Byte .equ ADCL0 = 0 ; ADC Data Register Low Byte Bit 0 .equ ADCL1 = 1 ; ADC Data Register Low Byte Bit 1 .equ ADCL2 = 2 ; ADC Data Register Low Byte Bit 2 .equ ADCL3 = 3 ; ADC Data Register Low Byte Bit 3 .equ ADCL4 = 4 ; ADC Data Register Low Byte Bit 4 .equ ADCL5 = 5 ; ADC Data Register Low Byte Bit 5 .equ ADCL6 = 6 ; ADC Data Register Low Byte Bit 6 .equ ADCL7 = 7 ; ADC Data Register Low Byte Bit 7
; SFIOR - Special Function IO Register .equ ADTS0 = 5 ; ADC Auto Trigger Source 0 .equ ADTS1 = 6 ; ADC Auto Trigger Source 1 .equ ADTS2 = 7 ; ADC Auto Trigger Source 2
; ***** JTAG ************************* ; OCDR - On-Chip Debug Related Register in I/O Memory .equ OCDR0 = 0 ; On-Chip Debug Register Bit 0 .equ OCDR1 = 1 ; On-Chip Debug Register Bit 1 .equ OCDR2 = 2 ; On-Chip Debug Register Bit 2 .equ OCDR3 = 3 ; On-Chip Debug Register Bit 3 .equ OCDR4 = 4 ; On-Chip Debug Register Bit 4 .equ OCDR5 = 5 ; On-Chip Debug Register Bit 5 .equ OCDR6 = 6 ; On-Chip Debug Register Bit 6 .equ OCDR7 = 7 ; On-Chip Debug Register Bit 7 .equ IDRD = OCDR7 ; For compatibility
; MCUCSR - MCU Control And Status Register ;.equ JTRF = 4 ; JTAG Reset Flag ;.equ JTD = 7 ; JTAG Interface Disable
; ***** BOOT_LOAD ******************** ; SPMCSR - Store Program Memory Control Register .equ SPMCR = SPMCSR ; For compatibility .equ SPMEN = 0 ; Store Program Memory Enable .equ PGERS = 1 ; Page Erase .equ PGWRT = 2 ; Page Write .equ BLBSET = 3 ; Boot Lock Bit Set .equ RWWSRE = 4 ; Read While Write section read enable .equ ASRE = RWWSRE ; For compatibility .equ RWWSB = 6 ; Read While Write Section Busy .equ ASB = RWWSB ; For compatibility .equ SPMIE = 7 ; SPM Interrupt Enable
; ***** PORTA ************************ ; PORTA - Port A Data Register .equ PORTA0 = 0 ; Port A Data Register bit 0 .equ PA0 = 0 ; For compatibility .equ PORTA1 = 1 ; Port A Data Register bit 1 .equ PA1 = 1 ; For compatibility .equ PORTA2 = 2 ; Port A Data Register bit 2 .equ PA2 = 2 ; For compatibility .equ PORTA3 = 3 ; Port A Data Register bit 3 .equ PA3 = 3 ; For compatibility .equ PORTA4 = 4 ; Port A Data Register bit 4 .equ PA4 = 4 ; For compatibility .equ PORTA5 = 5 ; Port A Data Register bit 5 .equ PA5 = 5 ; For compatibility .equ PORTA6 = 6 ; Port A Data Register bit 6 .equ PA6 = 6 ; For compatibility .equ PORTA7 = 7 ; Port A Data Register bit 7 .equ PA7 = 7 ; For compatibility
; DDRA - Port A Data Direction Register .equ DDA0 = 0 ; Data Direction Register, Port A, bit 0 .equ DDA1 = 1 ; Data Direction Register, Port A, bit 1 .equ DDA2 = 2 ; Data Direction Register, Port A, bit 2 .equ DDA3 = 3 ; Data Direction Register, Port A, bit 3 .equ DDA4 = 4 ; Data Direction Register, Port A, bit 4 .equ DDA5 = 5 ; Data Direction Register, Port A, bit 5 .equ DDA6 = 6 ; Data Direction Register, Port A, bit 6 .equ DDA7 = 7 ; Data Direction Register, Port A, bit 7
; PINA - Port A Input Pins .equ PINA0 = 0 ; Input Pins, Port A bit 0 .equ PINA1 = 1 ; Input Pins, Port A bit 1 .equ PINA2 = 2 ; Input Pins, Port A bit 2 .equ PINA3 = 3 ; Input Pins, Port A bit 3 .equ PINA4 = 4 ; Input Pins, Port A bit 4 .equ PINA5 = 5 ; Input Pins, Port A bit 5 .equ PINA6 = 6 ; Input Pins, Port A bit 6 .equ PINA7 = 7 ; Input Pins, Port A bit 7
; ***** PORTB ************************ ; PORTB - Port B Data Register .equ PORTB0 = 0 ; Port B Data Register bit 0 .equ PB0 = 0 ; For compatibility .equ PORTB1 = 1 ; Port B Data Register bit 1 .equ PB1 = 1 ; For compatibility .equ PORTB2 = 2 ; Port B Data Register bit 2 .equ PB2 = 2 ; For compatibility .equ PORTB3 = 3 ; Port B Data Register bit 3 .equ PB3 = 3 ; For compatibility .equ PORTB4 = 4 ; Port B Data Register bit 4 .equ PB4 = 4 ; For compatibility .equ PORTB5 = 5 ; Port B Data Register bit 5 .equ PB5 = 5 ; For compatibility .equ PORTB6 = 6 ; Port B Data Register bit 6 .equ PB6 = 6 ; For compatibility .equ PORTB7 = 7 ; Port B Data Register bit 7 .equ PB7 = 7 ; For compatibility
; DDRB - Port B Data Direction Register .equ DDB0 = 0 ; Port B Data Direction Register bit 0 .equ DDB1 = 1 ; Port B Data Direction Register bit 1 .equ DDB2 = 2 ; Port B Data Direction Register bit 2 .equ DDB3 = 3 ; Port B Data Direction Register bit 3 .equ DDB4 = 4 ; Port B Data Direction Register bit 4 .equ DDB5 = 5 ; Port B Data Direction Register bit 5 .equ DDB6 = 6 ; Port B Data Direction Register bit 6 .equ DDB7 = 7 ; Port B Data Direction Register bit 7
; PINB - Port B Input Pins .equ PINB0 = 0 ; Port B Input Pins bit 0 .equ PINB1 = 1 ; Port B Input Pins bit 1 .equ PINB2 = 2 ; Port B Input Pins bit 2 .equ PINB3 = 3 ; Port B Input Pins bit 3 .equ PINB4 = 4 ; Port B Input Pins bit 4 .equ PINB5 = 5 ; Port B Input Pins bit 5 .equ PINB6 = 6 ; Port B Input Pins bit 6 .equ PINB7 = 7 ; Port B Input Pins bit 7
; ***** PORTC ************************ ; PORTC - Port C Data Register .equ PORTC0 = 0 ; Port C Data Register bit 0 .equ PC0 = 0 ; For compatibility .equ PORTC1 = 1 ; Port C Data Register bit 1 .equ PC1 = 1 ; For compatibility .equ PORTC2 = 2 ; Port C Data Register bit 2 .equ PC2 = 2 ; For compatibility .equ PORTC3 = 3 ; Port C Data Register bit 3 .equ PC3 = 3 ; For compatibility .equ PORTC4 = 4 ; Port C Data Register bit 4 .equ PC4 = 4 ; For compatibility .equ PORTC5 = 5 ; Port C Data Register bit 5 .equ PC5 = 5 ; For compatibility .equ PORTC6 = 6 ; Port C Data Register bit 6 .equ PC6 = 6 ; For compatibility .equ PORTC7 = 7 ; Port C Data Register bit 7 .equ PC7 = 7 ; For compatibility
; DDRC - Port C Data Direction Register .equ DDC0 = 0 ; Port C Data Direction Register bit 0 .equ DDC1 = 1 ; Port C Data Direction Register bit 1 .equ DDC2 = 2 ; Port C Data Direction Register bit 2 .equ DDC3 = 3 ; Port C Data Direction Register bit 3 .equ DDC4 = 4 ; Port C Data Direction Register bit 4 .equ DDC5 = 5 ; Port C Data Direction Register bit 5 .equ DDC6 = 6 ; Port C Data Direction Register bit 6 .equ DDC7 = 7 ; Port C Data Direction Register bit 7
; PINC - Port C Input Pins .equ PINC0 = 0 ; Port C Input Pins bit 0 .equ PINC1 = 1 ; Port C Input Pins bit 1 .equ PINC2 = 2 ; Port C Input Pins bit 2 .equ PINC3 = 3 ; Port C Input Pins bit 3 .equ PINC4 = 4 ; Port C Input Pins bit 4 .equ PINC5 = 5 ; Port C Input Pins bit 5 .equ PINC6 = 6 ; Port C Input Pins bit 6 .equ PINC7 = 7 ; Port C Input Pins bit 7
; ***** PORTD ************************ ; PORTD - Port D Data Register .equ PORTD0 = 0 ; Port D Data Register bit 0 .equ PD0 = 0 ; For compatibility .equ PORTD1 = 1 ; Port D Data Register bit 1 .equ PD1 = 1 ; For compatibility .equ PORTD2 = 2 ; Port D Data Register bit 2 .equ PD2 = 2 ; For compatibility .equ PORTD3 = 3 ; Port D Data Register bit 3 .equ PD3 = 3 ; For compatibility .equ PORTD4 = 4 ; Port D Data Register bit 4 .equ PD4 = 4 ; For compatibility .equ PORTD5 = 5 ; Port D Data Register bit 5 .equ PD5 = 5 ; For compatibility .equ PORTD6 = 6 ; Port D Data Register bit 6 .equ PD6 = 6 ; For compatibility .equ PORTD7 = 7 ; Port D Data Register bit 7 .equ PD7 = 7 ; For compatibility
; DDRD - Port D Data Direction Register .equ DDD0 = 0 ; Port D Data Direction Register bit 0 .equ DDD1 = 1 ; Port D Data Direction Register bit 1 .equ DDD2 = 2 ; Port D Data Direction Register bit 2 .equ DDD3 = 3 ; Port D Data Direction Register bit 3 .equ DDD4 = 4 ; Port D Data Direction Register bit 4 .equ DDD5 = 5 ; Port D Data Direction Register bit 5 .equ DDD6 = 6 ; Port D Data Direction Register bit 6 .equ DDD7 = 7 ; Port D Data Direction Register bit 7
; PIND - Port D Input Pins .equ PIND0 = 0 ; Port D Input Pins bit 0 .equ PIND1 = 1 ; Port D Input Pins bit 1 .equ PIND2 = 2 ; Port D Input Pins bit 2 .equ PIND3 = 3 ; Port D Input Pins bit 3 .equ PIND4 = 4 ; Port D Input Pins bit 4 .equ PIND5 = 5 ; Port D Input Pins bit 5 .equ PIND6 = 6 ; Port D Input Pins bit 6 .equ PIND7 = 7 ; Port D Input Pins bit 7
; ***** WATCHDOG ********************* ; WDTCR - Watchdog Timer Control Register .equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0 .equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1 .equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2 .equ WDE = 3 ; Watch Dog Enable .equ WDTOE = 4 ; RW .equ WDDE = WDTOE ; For compatibility
; ***** LOCKSBITS ******************************************************** .equ LB1 = 0 ; Lock bit .equ LB2 = 1 ; Lock bit .equ BLB01 = 2 ; Boot Lock bit .equ BLB02 = 3 ; Boot Lock bit .equ BLB11 = 4 ; Boot lock bit .equ BLB12 = 5 ; Boot lock bit
и нельзя просто делать одноадресный rjmp. а чтобы "потратить" на один вектор 2 адреса, для reti и для rjmp нужно добавлять nop.
А еще надежнее - для всех прерываний прописать в .org абсолютные адреса.
BOB51 писал(а):
Где даташит, а где и документацию на IDE
Для ТСа: во вкладке help есть в том числе справка по ассемблерным командам. Полезная штука. И странно, что никто не напомнил почитать Евстифеева. Или это я проглядел...
Как по мне, ТС рано с 16-ой меги начал. На 8-й бы потренировался, она попроще. А на 16-ой ещё сюрпризы с in/out/lds/sts/(r)jmp/(r)call будут. Разобраться можно, но не имея более простой базы - сложнее
У меги16 внутрисхемная отладка (если фирменный STK500 иметь)... Да и вероятен корпус DIP40 - такое корпусирование (40-лапка) только у меги8515, 162й и 8535... В остальном - особо ничем не выделяется... Как вариант - просто была под руками.
Асм. То советую книгу. Вольфганг Трамперт. AVR-RISC микроконтроллеры. Очень подробно расписано по МК AVR. Я сейчас не дома. Завтра приеду, постараюсь выложить проект как пример. С векторами прерываний.
Как по мне, Евстифеев - это компиляция даташитов на русском. а разработка более интересна чуток по другим книжкам. Я начинала АВРки с Ревича - Практическое программирование AVR на ассемблере. Еще есть книжки Белова (например, МК AVR в радиолюбительской практике Полный разбор ATTINY2313). Плюс этих книжек - там идет разбор работы периферии на примере каких то практических кейсов. А Евстифеев - да, маст хев, но как справочник.
Моей настольной книгой была книга Вольфганг Трамперт AVR RISC микроконтроллеры. Остальные книги были в качестве примеров программ. Есть ещё книжка Джон Мортон Микроконтроллеры AVR Вводный курс. В примерах нужно быть повнимательнее. В каком то из примеров есть ошибка.
Добавлено after 17 minutes 31 second: Смотри. На каждый камень ты создаешь вот такой файл. Это векторы прерываний. Делай по такому примеру. vectors_m8535.inc: Спойлер
.org OC2addr ; Timer/Counter2 Compare Match reti // rjmp Proc_Int_BAM // reti
.org OVF2addr ; Timer/Counter2 Overflow reti
.org ICP1addr ; Timer/Counter1 Capture Event reti
.org OC1Aaddr ; Timer/Counter1 Compare Match A reti
.org OC1Baddr ; Timer/Counter1 Compare Match B reti
.org OVF1addr ; Timer/Counter1 Overflow reti
.org OVF0addr ; Timer/Counter0 Overflow reti
.org SPIaddr ; SPI Serial Transfer Complete reti ; rjmp SPI_Transfer_Int
.org URXCaddr ; USART, RX Complete reti
.org UDREaddr ; USART Data Register Empty reti
.org UTXCaddr ; USART, TX Complete reti
.org ADCCaddr ; ADC Conversion Complete reti // rjmp ADC_Complete
.org ERDYaddr ; EEPROM Ready reti
.org ACIaddr ; Analog Comparator reti
.org TWIaddr ; Two-wire Serial Interface reti
.org INT2addr ; External Interrupt Request 2 reti
.org OC0addr ; TimerCounter0 Compare Match rjmp Sys_Timer_Comp
.org SPMRaddr ; Store Program Memory Read reti ;---------- .org INT_VECTORS_SIZE ; size in words ;===================
Какой то проект до кучи. просто для примера.
На каждый камень есть даташит. И в нем есть таблица векторов. На каждый камень смотрим эту таблицу. И создаем файл таблицу векторов.
Младшие МК. У них 2 байтные адреса векторов. До 8x можно спокойно применять команду rjmp. Старшие. Типа M16, M32 и выше у них уже 4 байтные адреса векторов. Поэтому нужно использовать оператор .ORG и команду jmp.
Тут уже нужно вникать. Читать внимательно даташиты на мк. Где какую команду правильно применить. rjmp или jmp.
В AVR STUDIO на каждый камень есть заголовочный файл. Заглядываем туда. И на каждый камень есть таблица определений векторов.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения