zombi 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Столкнулся с проблемой. Долго мучался и ветаки поборол, но как-то странно! Опишу кратко. Используется два прерывания: 1:0x01A Timer/Counter1 Compare Match A - режим CLC (частота 44100 Hz) 2:0x020 Timer/Counter0 Compare Match - режим CLC ( частота 500 Hz) У второго прерывания приоритет ниже и первая команда его обработчика SEI. Все регистры и флаги сохраняются в каждом обработчике. Проблема в том что во втором прерывании необходимо читать состояние PIND.4 Состояние пина иногда считывается 0-м в то время как он в 1-це. В таком виде глючило: CBI PORTB,7 SBI PORTB,7 ROL RTMP SBIC PIND.4 ANDI RTMP,$01 добавил запрет и разрешение прерываний и глюк ПОЛНОСТЬЮ пропал: CLI CBI PORTB,7 SBI PORTB,7 ROL RTMP SBIC PIND.4 ANDI RTMP,$01 SEI Что это, глюк меги или я чегото не понимаю? Ктонибудь сталкивался с подобным? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба CLI CBI PORTB,7 SBI PORTB,7 ROL RTMP SBIC PIND.4 ANDI RTMP,$01 SEI Что это, глюк меги или я чегото не понимаю? Это глюк автора программы, вероятно, забывшего о необходимости сохранять SREG. :) Впрочем - это чистая телепатия, потому что из того, что Вы написали, вообще понять ничего невозможно. Дайте больше информации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 27 января, 2009 Опубликовано 27 января, 2009 (изменено) · Жалоба Я ж написал что "Все регистры и флаги сохраняются в каждом обработчике. " Дайте больше информации. Попробую. Вся проблема в том что если во время приведенных мою 5-ти команд 2-го обработчика выполняется другое прерывание то состояние 4-го пина порта D командой CBIC интерпретируется не верно. Изменено 27 января, 2009 пользователем zombi Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба У второго прерывания приоритет ниже и первая команда его обработчика SEI. Все регистры и флаги сохраняются в каждом обработчике. В стеке? Код полностью огласите плз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба В стеке? Код полностью огласите плз. Полность очень много! Попробую частями. Настройка и разрешение прерываний: ;-- TIMER1 - SOUND -------------- LDI RTMP,$09 OUT TCCR1B,RTMP LDI RTMP,HIGH(362) OUT OCR1AH,RTMP LDI RTMP,LOW(362) OUT OCR1AL,RTMP ;-- TIMER0 - KEY -------------- LDI RTMP,$0E OUT TCCR2,RTMP LDI RTMP,124 OUT OCR2,RTMP ;----------------- LDI RTMP,$50 OUT TIMSK,RTMP Обработчик timer1: TIM1: PUSH RTMPA IN RTMPA,$3F PUSH RTMPA . . . POP RTMPA OUT $3F,RTMPA POP RTMPA RETI Обработчик timer0: TIM0: SEI PUSH RTMPA IN RTMPA,$3F PUSH RTMPA . . . CLI <---------------------- CBI PORTB,7 SBI PORTB,7 LSL RTMPA SBIC PIND,4 ORI RTMPA,$01 SEI <---------------------- . . . STS $8000,RTMPA RET Проблема в том что даже если на PIND.4 тупо VCC подать, то младший бит в ячейке $8000 не всегда =1 если в обработчике TIM0 нету CLI/SEI во время его опроса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Опускаю Ваши небрежности (код выхода из TIM0, код инициализации TIM0) - я так понял, что в реале там все нормально ? Несогласен раз: TIM0: ;************* CBI PORTB,7 SBI PORTB,7 LSL RTMPA CLI <---------------------- SBIC PIND,4 ORI RTMPA,$01 SEI <---------------------- ;***** Несогласен, часть вторая: пожертвуйте регистром in RTMPC,PIND bst RTMPC,4 bld RTMPA,0 ЗЫ марш несогласных :) Раньше была проблема такая с sbrc/sbic sbrs/sbis но это было давно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Попробую частями. TIM0: SEI PUSH RTMPA IN RTMPA,$3F PUSH RTMPA Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание. Пропробуйте так: TIM0: cbi TIMSK, OCIE0 sei .... sbi TIMSK, OCIE0 reti Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 27 января, 2009 Опубликовано 27 января, 2009 (изменено) · Жалоба Спасибо всем ответившим. пожертвуйте регистром но это было давно Через рег тоже пробывал, не помогло. Опускаю Ваши небрежности (код выхода из TIM0, код инициализации TIM0) - я так понял, что в реале там все нормально ? А что с выходом из TIM0? Если вы имеете ввиду RET а не RETI то я же прерывания разрешаю в теле обратотчика. Ув. _Pasha подскажите что не правильно в инициализации TIM0? Просто я всегда так инициализирую, подскажите где ошибка. Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание Незнаю. Надо попробывать . Спасибо defunct. Но думаю что прерывание должно срабатывать по фронту? Но даже еслиб вход выполнялся несколько раз то в мл.бите регистра RTMPA всеравно должна быть единица ведь состояние PIND.4 стабильно. Может происходит повторный вызов TIM0? Вы же не запрещаете "ЭТО" прерывание. Пропробуйте так: TIM0: cbi TIMSK, OCIE0 sei .... sbi TIMSK, OCIE0 reti Попробывал. Результат отрицательный. Глюки продолжаются. TIM0: ;************* CBI PORTB,7 SBI PORTB,7 LSL RTMPA CLI <---------------------- SBIC PIND,4 ORI RTMPA,$01 SEI <---------------------- ;***** И так пробывал но тоже глючит. Глюки исчезают только если CLI находится перед LSL или еще раньше, но никак не перед SBIC: ;************* CBI PORTB,7 SBI PORTB,7 CLI <---------------------- LSL RTMPA SBIC PIND,4 ORI RTMPA,$01 SEI <---------------------- ;***** Изменено 27 января, 2009 пользователем zombi Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба А что с выходом из TIM0? Ув. _Pasha подскажите что не правильно в инициализации TIM0? 1.Инициализация ;-- TIMER0 - KEY -------------- LDI RTMP,$0E OUT TCCR2,RTMP LDI RTMP,124 OUT OCR2,RTMP Мы говорим о прерывании таймера 0, а здесь и далее у Вас инициализация таймера 2. Если эта небрежность все-же имеет отношение к проблеме, то проверьте таблицу векторов прерываний - вполне возможно, что там бардак. 2. Код входа и выхода SEI PUSH RTMPA IN RTMPA,SREG PUSH RTMPA ; ******* STS $8000,RTMPA pop RTMPA out SREG,RTMPA pop RTMPA reti Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба то проверьте таблицу векторов прерываний - вполне возможно, что там бардак. Конечно с таблицей векторов и POPами PUSHами все впорядке. Это просто апычатки :laughing: sorry. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Значит где-то чистят Ваш RTMPA без сохранения/восстановления. Поставьте условный брекпоинт на запись в регистр и дебажьте до победы. Не думаю что я гдето порчу RTMPA ведь с CLI/SEI нечего не портится!!! Всетаки мне кажется проблема с входом в прерывание в момент выполнения SBIC/S возможно даже именно с PIND.4. В любом случае экспериментировать надоело , запрет/разрешение прерываний спасает и пару лишних тактов не жмет, работает и бог с ним. :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 27 января, 2009 Опубликовано 27 января, 2009 · Жалоба Интересно. Я не сталкивался, но в первых моделях указывали про ошибки возникающие именно при прерывании и именно при исполнении комад sbic/sbis. Правда, если команда следующая за этими командами - двухсловная. При этом про команды BLD/BST никогда ничего не было. Всётаки я думаю, что вам надо исходить из постулата, что это ваша ошибка. И, соответственно, искать её корни. Иначе она вылезет в другом месте и в другом виде. А заплатки ставить - не пацанский метод. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uau 0 28 января, 2009 Опубликовано 28 января, 2009 (изменено) · Жалоба А что с выходом из TIM0? Если вы имеете ввиду RET а не RETI то я же прерывания разрешаю в теле обратотчика. А из стека, кто байт флагов будет вычищать? Изменено 28 января, 2009 пользователем uau Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 28 января, 2009 Опубликовано 28 января, 2009 · Жалоба Прошу прощения за поднятую бучу! Все оказалось гораздо проще. Ко входу D.4 подключен выход сдвигового регистра 74hc157. Опрос пина был сразу после строба SCK и регистр просто не успевал переключится. Частота процессора 16MHz а у регистра время установления выхода большое вот от он то успевал то нет. А команда CLI просто добавляла необходимую задержку :laughing: Но благодаря defunct возможно сразу избежал следующего косяка с прерываниями: Если время выполнения прерывания TIM1 окажется больше чем период TIM2 то возможен повторный вход в в TIM2. Устранил эту ситуацию запретом прерывания по TIM2 путем записи в TIMSK на старте и последующим разрешением на выходе. TIM2: PUSH RTMPA LDI RTMPA,$40 OUT TIMSK,RTMPA SEI IN RTMPA,SREG PUSH RTMPA . . . POP RTMPA OUT SREG,RTMPA LDI RTMPA,$50 CLI OUT TIMSK,RTMPA POP RTMPA RETI Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться