Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Собственно вопрос вот в чем.... Тело вектора прерывания: .org ovf0addr rjmp Timer0 Timer0: cli ldi r16, 0x94 ; 148 out TCNT0, r16 sei reti Почему после того как выполнилось все тело прерывания по команде "reti" щетчик переходит по нулевому адресу? И почему после следующих операций: ldi r16, 0x94 ; 148 out TCNT0, r16 Число 0x94 не заносится в регистр TCNT0? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Почему после того как выполнилось все тело прерывания по команде "reti" щетчик переходит по нулевому адресу? Смахивает на переполнение стека. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Смахивает на переполнение стека. Что значит переполнение стека? Может я не правильно выполняю следующую операцию? .cseg .org 300 ??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Блин... Ну подскажите... Я в тупике.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dopler 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба На самом деле даже в приведенном коде много что не правильно. Во первых - при переходе на вектор прерывания запрещать/разрешать оные не надо. На досуге посмотрите разницу между командами ret и reti. (Ладно, скажу reti = ret+sei). Также вы от нас кое что утаиваете - какой контроллер, чему равно ovf0addr (судя по всему оно равно у вас 0, а это вектор RESET), и где в коде у вас .org 300? Вопросами стека можете пока не забивать себе голову, главное, чтобы он был проинициализирован. А вообще любая программа на asm должна начинаться примерно так: ;************************************************* .cseg ;************************************************* rjmp RESET ; Reset Handler reti; rjmp EXT_INT0 ; IRQ0 Handler reti; rjmp EXT_INT1 ; IRQ1 Handler reti; rjmp PCINT0 ; PCINT0 Handler reti; rjmp PCINT1 ; PCINT1 Handler reti; rjmp PCINT2 ; PCINT2 Handler reti; rjmp WDT ; Watchdog Timer Handler rjmp TIM2_COMPA; Timer2 CompareA Handler reti; rjmp TIM2_COMPB; Timer2 CompareB Handler reti; rjmp TIM2_OVF ; Timer2 Overflow Handler reti; rjmp TIM1_CAPT ; Timer1 Capture Handler rjmp TIM1_COMPA; Timer1 CompareA Handler reti; rjmp TIM1_COMPB; Timer1 CompareB Handler reti; rjmp TIM1_OVF ; Timer1 Overflow Handler reti; rjmp TIM0_COMPA; Timer0 CompareA Handler reti; rjmp TIM0_COMPB; Timer0 CompareB Handler reti; rjmp TIM0_OVF ; Timer0 Overflow Handler reti; rjmp SPI_STC ; SPI Transfer Complete Handler reti; rjmp USART_RXC ; USART RX Complete Handler reti; rjmp USART_UDRE; UDR Empty Handler reti; rjmp USART_TXC ; USART TX Complete Handler reti; rjmp ADC_Conv; ADC Conversion Complete Handler reti; rjmp EE_RDY ; EEPROM Ready Handler reti; rjmp ANA_COMP ; Analog Comparator Handler reti; rjmp TWSI ; Two-wire Serial Interface Handler reti; rjmp SPM_RDY ; Store Program Memory Ready Handler ;---------------------------------------------------------------------------------------------------------------------------- ;---------------------------------------------------------------------------------------------------------------------------- RESET: ldi tmp, high(RAMEND) ; Main program start out SPH, tmp ; Set Stack Pointer to top of RAM ldi tmp, low(RAMEND) out SPL, tmp Этот код берется прямиком из даташит, он приведен в разделе Interrupts. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Вот код всей прогаммы: .include "m128def.inc" .cseg .org 300 .org 0 rjmp RESET .org ovf0addr rjmp Timer0 Timer0: ldi r16, 0x94 ; 148 out TCNT0, r16 nop nop nop reti RESET: cli ;Настройка таймера 0 ldi r16, 0x01 out TCCR0, r16 ldi r16, 0x94 out TCNT0, r16 ldi r16,0x01 out TIMSK, r16 sei MAIN: nop nop nop nop rjmp main Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Что значит переполнение стека? при вызове прерывания/подпрограммы адрес возврата сохраняеться в стеке, по ret(i) возвращается в РС. Если указатель стека указывает куда-то не туда адрес возврата слетает. Обычно в 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dopler 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Ну понятный хрен, стек не проинициализирован. .org 300 можете удалять, она просто игнорируется то такое ovf0adr так и не известно Для 128меги команда rjmp не существует. вот, возьмите это код вместо вашего добра: ;************************************************* .include "m128def.inc" ;************************************************* .def zero = r15 .def tmp = r16 ;************************************************* .cseg ;************************************************* .org $0000 jmp RESET; Reset Handler .org $0002 reti ; jmp EXT_INT0; IRQ0 Handler .org $0004 reti ; jmp EXT_INT1; IRQ1 Handler .org $0006 reti ; jmp psDataFail; IRQ2 Handler .org $0008 reti ; jmp kbClockFall; IRQ3 Handler .org $000A reti ; jmp EXT_INT4; IRQ4 Handler .org $000C reti ; jmp EXT_INT5; IRQ5 Handler .org $000E reti ; jmp EXT_INT6; IRQ6 Handler .org $0010 reti ; jmp EXT_INT7; IRQ7 Handler .org $0012 reti ; jmp TIM2_COMP; Timer2 Compare Handler .org $0014 reti ; jmp TIM2_OVF; Timer2 Overflow Handler .org $0016 reti ; jmp TIM1_CAPT; Timer1 Capture Handler .org $0018 reti ; jmp TIM1_COMPA; Timer1 CompareA Handler .org $001A reti ; jmp TIM1_COMPB; Timer1 CompareB Handler .org $001C reti ; jmp TIM1_OVF; Timer1 Overflow Handler .org $001E ; reti jmp TIM0_COMP; Timer0 Compare Handler .org $0020 reti ; rjmp TIM0_OVF; Timer0 Overflow Handler .org $0022 reti ; jmp SPI_STC; SPI Transfer Complete Handler .org $0024 reti ; jmp USART0_RXC; USART0 RX Complete Handler .org $0026 reti ; jmp USART0_DRE; USART0,UDR Empty Handler .org $0028 reti ; jmp USART0_TXC; USART0 TX Complete Handler .org $002A reti ;jmp ADC; ADC Conversion Complete Handler .org $002C reti ; jmp EE_RDY; EEPROM Ready Handler .org $002E reti ; jmp ANA_COMP; Analog Comparator Handler .org $0030 reti ; jmp TIM1_COMPC; Timer1 CompareC Handler .org $0032 reti ; jmp TIM3_CAPT; Timer3 Capture Handler .org $0034 reti ; jmp TIM3_COMPA; Timer3 CompareA Handler .org $0036 reti ; jmp TIM3_COMPB; Timer3 CompareB Handler .org $0038 reti ; jmp TIM3_COMPC; Timer3 CompareC Handler .org $003A reti ; jmp TIM3_OVF; Timer3 Overflow Handler .org $003C reti ; jmp USART1_RXC; USART1 RX Complete Handler .org $003E reti ; jmp USART1_DRE; USART1,UDR Empty Handler .org $0040 reti ;jmp USART1_TXC; USART1 TX Complete Handler .org $0042 reti ;jmp TWI; Two-wire Serial Interface Interrupt Handler .org $0044 reti ;jmp SPM_RDY; SPM Ready Handler TIM0_COMP: ldi tmp, 0xFB out udr0, tmp reti RESET: ldi tmp, high(RAMEND); Main program start out SPH, tmp; Set stack pointer to top of RAM ldi tmp, low(RAMEND) out SPL, tmp clr zero ldi tmp, (1<<WGM01)|(0b111<<CS00) out TCCR0, tmp ldi tmp, 144 out OCR0, tmp ldi tmp, (1<<OCIE0) out TIMSK, tmp sei begin: rjmp begin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Dopler... Будьте добры... Пожалуйста прокоментируйте хоть в кратце этот код........ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dopler 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Мой код, это тоже самое, что и у вас. 1. Подключаем файл mega128 2. Даем регистрам имена, под которым они будут использоваться в программе ( с помошью .equ ) 3. Директива .org говорит по какому адресу размещать код .org 0 - размещать с нуля 3. Дальше идем в даташит на страницу 61, раздел Interrupts и видим все вектора прерываний и инициализацию стека, как это рекомендует Atmel (видим код). Т.е. видим список всех прерываний меги128. 4. У меги 128 нет команды rjmp, так как она не перекрывает все адресное пространство. Используется команда jmp. 5. В прерываниях, которые нам нужны, раскоментирован jmp, которые не нужны - reti (если вдруг в программе по недосмотру нежелательное прерывание произойдет, то ничего страшного не случится, так как будет сразу reti ). Необходимо помнить, что команда jmp занимает в памяти программ два слова (4 байта), поэтому .org наращивается на 4. 6. После сброса программа прыгает на 0, там видит jmp и переходит на RESET. Программа начинается с инициализации стека. Т.е. в регистр стека SPH:SPL записывается последняя ячейка ОЗУ меги, так как стек у AVR растет сверху вниз. 7. Дальше инициализируется таймер на прерывание по сравнению, вы можете поменять это место на свою инициализацию таймера (лучше не меняйте, а разберитесь с мнемоникой <<). 8. Разрешаются прерывания. 9. Главный бесконечный цикл. 10. При срабатывании прерывания, программа прыгает на вектор 001E, видит там jmp и переходит на обработчик. 11. В обработчике может написать любой тестовый код вместо моего (мой выводит байт в UART, смысла для вас не имеет), например inc tmp. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 21 февраля, 2007 Опубликовано 21 февраля, 2007 · Жалоба Спасибо... ведь не обязательно в программе писать все адреса прерываний если они не испорльзуються? И еще :<< Это просто в РОН устанавливается единица по номеру бита в определенном байте так.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 22 февраля, 2007 Опубликовано 22 февраля, 2007 · Жалоба ведь не обязательно в программе писать все адреса прерываний если они не испорльзуються? В принципе нет. И умные С компиляторы зачастую это обходят. Но ради десятка байт заниматься половыми извращениями ИМХО не стоит. Тем более всегда стоит иметь ввиду будущие модернизации кода, поэтому значительно лучше оставлять заглушки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Qwertty 0 22 февраля, 2007 Опубликовано 22 февраля, 2007 · Жалоба Мой код, это тоже самое, что и у вас. ... 4. У меги 128 нет команды rjmp, так как она не перекрывает все адресное пространство. Используется команда jmp. Правильнее наверно так - векторы прерывания рассчитаны на команду JMP. RJMP у меги тоже есть, и ее можно применять и в этом случае, если определять векторы через их имена - .org OVF0addr ldi tmp, (1<<WGM01)|(0b111<<CS00) Честно говоря загадочная конструкция. Точнее вот эта часть - (0b111<<CS00) Не подскажите, что она значит? Понятно, что работать будет, но <<CS00 зачем??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Potter 0 22 февраля, 2007 Опубликовано 22 февраля, 2007 · Жалоба И последнее... почему все таки у меня не получается записывать в щетный регистр TCNT0 командой out? Может нужно использовать sts? Но разве этот регистр находится не в регистровом пространстве? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 22 февраля, 2007 Опубликовано 22 февраля, 2007 · Жалоба Не подскажите, что она значит? Понятно, что работать будет, но <<CS00 зачем??? Чтобы не думать о совместимости. Сдвинули на позицию N и неважно 5 -й это бит или 0-й. почему все таки у меня не получается записывать в щетный регистр TCNT0 командой out? А как это выглядит? Обращение выше пространства IO ассемблер не пропустит - выдаст ошибку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться