|
Проблема с VMLAB.Помогите..., Прерывания. |
|
|
|
Jan 28 2008, 07:57
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Уважаемый форум! Изучал прерывания на мегах и столкнулся с проблемой, а пока не решу дальше не иду. Задал свой вопрос на forum.roboclub.ru, но видно сильно подробно описал или вопрос сильно до- школьный, но в ответ -- тишина. Надеюсь, что вы будете более снисходительны. При пошаговой отладке прерывания Таймер0 обратил внимание: 1.Предделитель таймера-биты CS03-CS00 регистра ТССR0B не устанавливаются. 2.При ручном вводе этого значения в поле TCCRn окна ‘Peripherals’ и при пошаговом выполнении программы, происходит затирание предварительно введенного значения в поле TCCRn окна ‘Peripherals’ инструкцией “TCCR0A=0х00;”. Если же остановить запущенную программу и вручную ввести значение в поле TCCRn окна ‘Peripherals’, то после запуска программы прерывание происходит, но при этом флаг прерываня в регистре TIFR0 устанавливается не TOV0(бit0), а OCF0A(bit1). При рассмотрение файла m48def.inc, из папки include VMLABa, имена битов и адр. регистров соответствуют Д.Ш. Но если просматривать побитно поле TCCRn окна ‘Peripherals’ то получаешь ахинею из имен битов, которых в ДШ нет. Вопрос, что означают имена битов в окне TCCRn окна ‘Peripherals’? В ДШ. есть TCCR0А и ТCCR0В и имена битов совсем другие.
Далее про PCINT. Выводы PORTB.1-3 сделал входами с подтяжкой. В VMLAB повешал на них кнопки ‘control panel’. При нажатии на любую кнопку флаг прерывания устанавливается (бит0 в регистре PCIFR), но сам обработчик не выполняется и флаг не обнуляется. Листинги для обоих пакетов привожу. Проверял работу прерывания таймер0 на 90S2313 все работает. Кто сталкивался с этим - пожалуйста объясните и если можно то подробней. Если проверки делаю в цикле While то все работает.
""МЫ ВСЕ КОГДА-ТО УЧИЛИСЬ ХОДИТЬ.""
Chip type : ATmega48 Clock frequency : 0,015625 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/
#include <mega48.h>
// Pin change 0-7 interrupt service routine interrupt [PCINT0] void pin_change_isr0(void) { // Place your code here PORTD.2=~PIND.2;//если произошло прерывание, то сигнал на выходе порта инверти-я. }
// Timer 0 overflow interrupt service routine /*interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=0xF0;//предварительная загрузка числа в счетный регистр таймера // Place your code here #asm("cli"); TIFR0=0x01;//стираю принудительно флаг, хотя по даташиту не нужно. PORTD.3=~PIND.3;//по прерыванию сигнал на выходе порта инвертируется. #asm("sei"); } */
// Declare your global variables here
void main(void) {
// Crystal Oscillator division factor: 256 #pragma optsize- CLKPR=0x80; CLKPR=0x08; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif
// Port B initialization PORTB=0x0Е; DDRB=0x00;
// Port D initialization PORTD=0x1Е; DDRD=0x1E;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 15,625 kHz // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x05; TCNT0=0xF0;//предварительная загрузка таймера0 OCR0A=0x00; OCR0B=0x00;
// Interrupt on any change on pins PCINT0-7: On
EICRA=0x00; EIMSK=0x00; PCICR=0x01;//включение прерывания на выводы порта РВ PCMSK0=0x0E;//разрешение прерывания на линиях РВ3-1 PCIFR=0x00;
// Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01;
// Global enable interrupts #asm("sei")
while (1) {
} }
Для VMLAB: .MICRO "ATmega48" .TOOLCHAIN "GENERIC" .TARGET "1.hex" ; Proshivka na MK .COFF "1.cof" ; .SOURCE "1__.c" .CLOCK 4meg .POWER VDD = 5 VSS = 0 .STORE 2000m
; SW2-SW0 === K2-K0 on ControlPanal
K1 PB1 VSS ; кнопки с выхода порта на gnd. K2 PB2 VSS ; K3 PB3 VSS ;
; =================================================== ; Signals that will be ploted in SCOPE window
.plot V(PB1) V(PB2) V(PB3) V(PD2) V(PD3)
|
|
|
|
|
Jan 29 2008, 06:54
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Спасибо, что хоть кто-то решил пообщаться. Но я не согласен с таким утверждением. Ведь до основного цикла while идет инициализация всех регистров и как таковая программа еще не выполняется. Значит и разрешать прерывания не имеет смысла. Как начинающий, я все таки опробовал этот совет, но "воз" иныне там. Я вставил аналогично pcint прерывание int0 и оно прекрасно работает. Создается впечатление, что vmlab по прерываниям timer0 и pcint не корректно работает. Неужели никто в начале своей карьеры не юзал ее? Или она такая кривая, что об этом и говорить не стоит? УВАЖАЕМЫЕ AVRщики ДАВАЙТЕ ПООБЩАЕМСЯ, ВЫСКАЖИТЕ СВОЕ МНЕНИЕ. P.S. Как начиныющий, не знал на каком пакете останавиться. С CodeVision и VMLAB начал как с самых простых в освоении. Судя по форумам, в Proteus тоже куча багов.
|
|
|
|
|
Jan 29 2008, 10:08
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(mdmitry @ Jan 29 2008, 10:08)  Проверьте функции прерывания по таймеру. Зачем флаг ставите? Посмотрите документацию по используемому контроллеру в плане организации прерываний: инициализация, установка разрешения конкретного прерывания, СБРОС прерывания и т.д. Извиняюсь, был процесс отладки и код перенес не убрав коментарии с обработчика прерывания по таймеру0. Но это не суть важно. Первоначальную инициализацию всех регистров производил с помощью CodeWizardAVR, да и потом разобравшись с ДШ. перепроверил не раз. Так-что здесь ошибки не должно быть. По поводу флага. Если я правильно понял, то вы имеете в виду строчку с кодом TIFR0=0x01 в обработчике прерывания по таймеру0? Но я наоборот сбрасываю флаг записывая туда единицу(неприятная особенность у AVR, пока не запомнишь). По ДШ. этот флаг сбрасывается аппаратно, если выполняется обработчик. Была отладка. Ладно, пока мне хватит и INTx, а PCINTx-это так учеба. В дальнейшем наберусь опыта и сам пойму, если конечно кто-нибудь не подскажет конкретно. Но главный вопрос из-за которого я обратился на форум повис в воздухе. ЧТО ОЗНАЧАЮТ ИМЕНА БИТОВ РЕГИСТРА TCCRn В ОКНЕ Peripherals - в ДШ-те. совсем другое? И еще вопрос по AVRSstudio. Отладка программы идет по состоянию регистров или есть возможность как в протеусе посмотреть реальный сигнал на виртуальном оссцилографе?
|
|
|
|
|
Jan 29 2008, 10:12
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(j_serg @ Jan 29 2008, 06:54)  Но я не согласен с таким утверждением. Ведь до основного цикла while идет инициализация всех регистров и как таковая программа еще не выполняется. Значит и разрешать прерывания не имеет смысла Пишите более внятно, что у вас не так. Или поясните, что вы имели в виду Цитата(j_serg @ Jan 28 2008, 07:57)  При нажатии на любую кнопку флаг прерывания устанавливается (бит0 в регистре PCIFR), но сам обработчик не выполняется и флаг не обнуляется. Если проверки делаю в цикле While то все работает 1) Непонятно, что у вас работает в цикле while? 2) Если флаг прерывания устанавливается при нажатии на кнопки, а прерывания нет - значит, это прерывание не разрешено, или адрес не тот, чудес не бывает. 3) Какие проверки вы делаете в цикле while? 4) Какие ещё и ГДЕ вы делали проверки, если у вас вся программа состоит из команды перехода на саму себя (инструкция while(1){})?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jan 30 2008, 10:32
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(=GM= @ Jan 29 2008, 13:12)  Пишите более внятно, что у вас не так. Или поясните, что вы имели в виду
1) Непонятно, что у вас работает в цикле while?
2) Если флаг прерывания устанавливается при нажатии на кнопки, а прерывания нет - значит, это прерывание не разрешено, или адрес не тот, чудес не бывает.
3) Какие проверки вы делаете в цикле while?
4) Какие ещё и ГДЕ вы делали проверки, если у вас вся программа состоит из команды перехода на саму себя (инструкция while(1){})? Уточню сразу, программа учебная. Про цикл while вспомнил к слову. Первоначально изучал работу регистров флагов и проверки делал в цикле. while (<проверка установки флага>) { <исполняемый код> TIFR0=0x01;// сброс флага } Когда перешел на обработчики прерывания то цикл while сделал пустой. Далее про прерывание PCINT0. РС2-0 сделал входами с подтяжкой и вешаю на них кнопки с земли. Флаг прерывания устанавливается. ВОПРОС ПЕРВЫЙ- ПОЧЕМУ НЕТ ЗАХОДА В ОБРАБОТЧИК ПРЕРЫВАНИЯ? ВОПРОС ВТОРОЙ (для тех кто юзал или юзает VMLAB).ЧТО ОЗНАЧАЮТ ИМЕНА БИТ РЕГИСТРА TCCRn В ОКНЕ Peripherals ДЛЯ ТАЙМЕРА0? По ДШ. есть рег. TCCR0A и TCCR0B и другие имена бит. Прикрепляю листинги.
|
|
|
|
|
Jan 30 2008, 16:44
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(j_serg @ Jan 30 2008, 10:32)  Далее про прерывание PCINT0. РС2-0 сделал входами с подтяжкой и вешаю на них кнопки с земли. Флаг прерывания устанавливается. ВОПРОС ПЕРВЫЙ- ПОЧЕМУ НЕТ ЗАХОДА В ОБРАБОТЧИК ПРЕРЫВАНИЯ? Прикрепляю листинги Ну и где они? И не надо так кричать... Если захода в прерывание нет, то 1) Проверьте, разрешено ли глобальное прерывание. 2) Проверьте по листингу, тот ли адрес вектора прерывания установлен.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jan 31 2008, 04:05
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(=GM= @ Jan 30 2008, 19:44)  Ну и где они? И не надо так кричать...
Если захода в прерывание нет, то
1) Проверьте, разрешено ли глобальное прерывание.
2) Проверьте по листингу, тот ли адрес вектора прерывания установлен. Мои извинения. Отправить отправил, а прикрепились ли .... Закоментировал надеюсь понятно. "Костяк" создавал на Кодевизарде. Ниже Си-шника дизасм по PCINT0. Chip type : ATmega48 Clock frequency : 0,015625 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega48.h> // прерывание INT0 interrupt [EXT_INT0] void ext_int0_isr(void) { PORTD.4=~PORTD.4; } // прерывание PCINT interrupt [PCINT0] void pin_change_isr0(void) { PORTD.5=~PORTD.5; } //прерывание таймер0 по переполнению interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xF0;//предварительная загрузка таймера PORTD.6=~PORTD.6; } void main(void) { // Crystal Oscillator division factor: 256 #pragma optsize- CLKPR=0x80; CLKPR=0x08; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Port B initialization PORTB=0x07;//установка РВ2-0 на вход с подтяжкой DDRB=0x00; // Port D initialization PORTD=0xFF;//установка РD3-0 на вход с подтяжкой, а остальные выводы на выход DDRD=0xF0; // Timer/Counter 0 initialization TCCR0A=0x00; TCCR0B=0x01;//коэффициент делителя для таймера0 TCNT0=0xF0;// предварительная загрузка таймера0 OCR0A=0x00; OCR0B=0x00; // External Interrupt(s) initialization EICRA=0x00;//прерыван. по низкому уровню на INT0 EIMSK=0x01;//разрешение прерыван. на INT0 EIFR=0x01;//обнуление флага прерывания INT0(зачем-то поставил сам компилятор) PCICR=0x01;//выбор выводов РС7-0 для прерываний PCMSK0=0x07;//разрешение прерыван. для РС2-0 PCIFR=0x01;//обнуление флага прерывания // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01; // Timer/Counter 1 Interrupt(s) initialization TIMSK1=0x00; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x00; // Analog Comparator initialization ACSR=0x80; ADCSRB=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here }; } По вашему совету проверить, а есть ли вектор и правильно ли сделан переход, засел за асм. Коментариев нет, т.к. код простой. Но на мой не искушенный взгляд все правильно. Есть вектор перехода и подпрограмма которая меняет бит в РD, но переход не выполняется. Может быть где-то стоит запрет, хотя тотже INT0 работает???? 0001 rjamp ext_int0_isr . . 0003 rjamp pin_change_isr0 . . 0054 ext_into_isr rcall 1_00b8 . clt . sbis $05, 4 . set . in r26, $0b . bld r26, 4 . rcall 1_00bc 005b reti 005c pin_change_isr0 rcall 1_00b8 . clt . sbis $0b, 5 . set . in r26, $0b . bld r26, 5 . rcall 1_00bc 0063 reti . . 00b8 1_00b8 st -Y, r26 . st-Y, r30 . in r30, $3f 00bb ret 00bc 1_00bc out $0b, r26 . out $3f, r30 . ld r30, Y+ . ld r26, Y+ . ret Я нахожусь в другом часовом поясе и отвечаю как-бы с "утра". PS. Не знаю почему, но дизасм отправляешь в нормальном виде, а он форматится и получается все в куче. По колонкам такая информация: | Addrr.. | Label | Disassemble |
Сообщение отредактировал j_serg - Jan 31 2008, 04:27
|
|
|
|
|
Jan 31 2008, 08:26
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата Не знаю почему, но дизасм отправляешь в нормальном виде, а он форматится и получается все в куче Потому что надо использовать тэги Код [code] [/code]
--------------------
|
|
|
|
|
Jan 31 2008, 08:50
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(GDI @ Jan 31 2008, 11:26)  Потому что надо использовать тэги Код [code] [/code] Cейчас разбераюсь с С, асмом, с ПО для AVR. Нахожу кучу сообщений о "багах" в протеусе, студии... И сразу становиться так тосклиВОО... Но все равно за совет огромное спасибо. Если не лопнет голова от пятилетки за два года, то по возможности залезу и в HTML.
Сообщение отредактировал j_serg - Jan 31 2008, 08:51
|
|
|
|
|
Jan 31 2008, 10:33
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(GDI @ Jan 31 2008, 13:05)  Я больше скажу - баги даже в железе есть  что уж тут говорить о симуляторах. Мое имхо - не стоит увлекаться всякими симуляторами, а в особенности тем как они симулируют различную периферию, с периферией надо работать в железе. В симуляторе надо искать собственные баги(неверная инициализация, неправильный обработчик прерывания и т.п.) и никогда не полагаться на 100%-ную правильность симулятора. Полностью согласен. Пока сижу в симуляторе, чтобы изучить наглядно внутренности AVRов. Но уже столкнулся с тем, что работа таймеров по прерыванию не правильно симулируется. Если бы был уверен на 100% послал бы письмо с большим вопросом в тех. поддержку разработчикам. Но пока на форуме мне толком не помогли. Затыки из-за невнимательности у всех бывают, особенно когда "учишся ходить".
|
|
|
|
|
Feb 1 2008, 10:56
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(j_serg @ Jan 31 2008, 04:05)  По вашему совету проверить, а есть ли вектор и правильно ли сделан переход, засел за асм. Коментариев нет, т.к. код простой. Но на мой не искушенный взгляд все правильно. Есть вектор перехода и подпрограмма которая меняет бит в РD, но переход не выполняется. Может быть где-то стоит запрет, хотя тотже INT0 работает????
0001 rjamp ext_int0_isr . . 0003 rjamp pin_change_isr0 . . 0054 ext_into_isr rcall 1_00b8 . clt . sbis $05, 4 . set . in r26, $0b . bld r26, 4 . rcall 1_00bc 005b reti 005c pin_change_isr0 rcall 1_00b8 . clt . sbis $0b, 5 . set . in r26, $0b . bld r26, 5 . rcall 1_00bc 0063 reti . . 00b8 1_00b8 st -Y, r26 . st-Y, r30 . in r30, $3f 00bb ret 00bc 1_00bc out $0b, r26 . out $3f, r30 . ld r30, Y+ . ld r26, Y+ . ret Какие-то у вас команды перехода поддельные(:-), таких команд перехода (rjamp) не бывает. В остальном, вроде бы здесь всё на месте, не вижу только глобального разрешения прерываний.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Feb 4 2008, 09:27
|
Группа: Новичок
Сообщений: 14
Регистрация: 28-01-08
Пользователь №: 34 483

|
Цитата(=GM= @ Feb 1 2008, 13:56)  Какие-то у вас команды перехода поддельные(:-), таких команд перехода (rjamp) не бывает.
В остальном, вроде бы здесь всё на месте, не вижу только глобального разрешения прерываний. Действительно такой команды нет. Листинг дизасма у меня был как-бы виртуальный--только на экране. Через буфер я его вставить не смог. Поэтому я его набил тупо в ручную(чего не зделаешь ради истины) и естественно с ошибкой. Команда sei у меня есть, если посмотреть выше приведенный Си листинг то она стоит аккурат перед циклом while(1), в асме, для краткости, я привел только строчки векторов перехода и самих обработчиков. С таймерами я уже разобрался, всем спасибо за советы, кое в чем видимо они меня надоумили, а с прерыванием PCINT пока большой вопрос.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|