Наверно странная у меня просьба и немного необычная. Но тем не менее хотелось бы спросить, может ли кто нибудь мне обьяснить в чем моя ошибка или даже не ошибка. Вобщем мне нужно было написать учебную программу для микроконтроллера PIC18F452 (Отладочная плата PICDEM2PLUS, Mplab v7.20, C#) которая при нажатии на кнопку RB0 на плате, зажигала светодиод RB1, программа рабочая, светодиод исправно зажигается) Но я не понимаю почему МК уходит на прерывание при условии Code: if (PORTBbits.RB0 == 0) хотя по моему он должен уходить при Code: if (PORTBbits.RB0 == 1) вот собственно и весь вопрос(просто прога учебная и будет использоваться для демонстрации работы МК будушим поколениям, поэтому надо все "разжевать") Code: /* MCU: PIC18F452 Lang: C Comp: MpLAB IDE v7.20 Программа обработки внешних прерываний (external interrupt) 08/07/2008 */ #include #pragma config OSC = HS #pragma config WDT = OFF #pragma config LVP = OFF void main (void); // Обьявляем прототип функции main void InterruptHandlerHigh (void); // Обьявляем прототип функции InterruptHandlerHigh #pragma interrupt InterruptHandlerHigh // Точка перехода по прерыванию #pragma code InterruptVectorHigh = 0x8 // Вектор прерывания void InterruptHandlerHigh(void) // Функция обработки прерывания { PORTBbits.RB1 = 1; // Зажечь диод INTCONbits.INT0IF = 0; // очистка флага прерывания } #pragma code void main() { TRISBbits.TRISB1 = 0; // 0 - Out направление сигнала TRISBbits.TRISB0 = 1; // 1 - In направление сигнала PORTBbits.RB1 = 0; // инициалиация: диод выключен INTCON2bits.INTEDG0 = 1; // 1 - прерывание по переднему фронту сигнала INTCONbits.GIEH = 1; // 1 - разрешить прерывания с высоким приоритетом INTCONbits.INT0IE = 1; // 1 - разрешить внешние прерывания сo входа RB0 if (PORTBbits.RB0 == 0) // Условие возникновения прерывания { _asm goto InterruptHandlerHigh //Переходим в функцию обработки прерывания _endasm } } И как вобще на ваш взгляд эта прога, просто это моя первая в жизни программа на МК, так что сильно не пинайте)
PIC не юзаю, но могу сказать со своего опыта роботы с АВР. В АВР прерывания можна настраивать на срабатывания от разных условий - от высокого уровня, от низкого уровня, от смены уровней и еще какие-то... Может и в ПИКах есть такая вещь... Глянть даташит по прерываниям для этого МК там должно быть. ---------------- Еще раз пересмотрел исходники и ничего вооьще не понял... Прерывания используются в основном АВТОМАТИЕСКИ... Тоесть ты пишеш функцию и говориш МК чтобы ее вызывал когда на ножке будет высокий уровень... Но в твоем примере ты вызываеш прерывания вручную if (PORTBbits.RB0 == 0) // Условие возникновения прерывания { _asm goto InterruptHandlerHigh //Переходим в функцию обработки прерывания _endasm Смысла юзать прирывания не вижу... Можна было исползьзовать обычную функцию... ------------ ИМХО
Все нашел обьяснение. Оказывается все как всегда просто. Активный низкий уровень, подключен к RB0 При нажатии любой кнопки входной уровень переключается на землю. В отпущенном состоянии на ней 5Вольт. То есть в нажатом состоянии на ней 0. И при нажатии выполняется Code: if (PORTBbits.RB0 == 0)
Да, прога конечно - без пузыря не обойдешься... Очень заинтересовало, что это за компилятор такой, приведи плиз его полное наименование. Далее: Code: if (PORTBbits.RB0 == 0) // Условие возникновения прерывания { _asm goto InterruptHandlerHigh //Переходим в функцию обработки прерывания _endasm } этого куска не должно быть вообще! Президент правильно сказал, иначе это и не прерывание вовсе. Во вторых, после того, как выполнится весь код в функции маин, необходимо программу на месте зациклить, вполне подойдет while(true) Когда все правильно заработает, у тебя после нажатия на кнопку загорится светодиод раз и навсегда (пока питание не скинешь). Дальше есть много интересных предложений, как твою демку сделать более зрелищной и интересной, но ты сначала с этим разберись. И еще, к слову, если есть возможность, то возьми сначала контроллер попроще, из 16F семейства и компилятор рекомендую CCS PICC, он попроще в обращении (пример можешь посмотреть в теме "Непримитивная сигнализация") Пока все, пожем чем можем, как говорится.
Извини что так долго не отвечал, сессия) Вобщем компилятор MICROCHIP MPLAB C18. Release Notes for MPASM(tm) Assembler version v3.90 November 8, 2004 А как должно быть? Это я знаю, но мне вроде как ненадо так делать, потом в случае чего исправлю, просто препод как то неопределенно сказал что ему надо) С ЭТИМ я уже разобрался, спасибо. Более зрелишно это наверно будет более сложно, или как(прога пишется для людей которые в первый раз в жизни познакомятся с МК и скорее всего вобще с программированием, так что думаю не стоит особо усложнять)? Вобщем жду предложения) Это я не для себя ведь делаю, как "начальство" скажет так и сделаю)
Прерывание сделай по таймеру, чтоб оно раз 200 в секунду вызывалось. А в прерывании: если кнопка нажата, то зажечь светодиод, если не нажата, то погасить. С наворотами программа не обязательно станет сложнее. Больше - да, но она может состоять из нескольких простых относительно независимых блокох, каждый из которых будет достаточно доступен для понимания "неискушенного" программера. Семисегментный индикатор не желаешь "прикрутить"?