Схемы, программы, прошивки Вопрос по МК

Discussion in 'Электроника и Фрикинг' started by CHIP:)), 9 Jun 2008.

  1. CHIP:))

    CHIP:)) Elder - Старейшина

    Joined:
    17 Jan 2007
    Messages:
    81
    Likes Received:
    18
    Reputations:
    -3
    Наверно странная у меня просьба и немного необычная. Но тем не менее хотелось бы спросить, может ли кто нибудь мне обьяснить в чем моя ошибка или даже не ошибка.
    Вобщем мне нужно было написать учебную программу для микроконтроллера 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
    }
    }
    
    И как вобще на ваш взгляд эта прога, просто это моя первая в жизни программа на МК, так что сильно не пинайте)
     
  2. presidentua

    presidentua милиционер Античата

    Joined:
    4 Nov 2007
    Messages:
    305
    Likes Received:
    236
    Reputations:
    15
    PIC не юзаю, но могу сказать со своего опыта роботы с АВР.

    В АВР прерывания можна настраивать на срабатывания от разных условий - от высокого уровня, от низкого уровня, от смены уровней и еще какие-то...

    Может и в ПИКах есть такая вещь... Глянть даташит по прерываниям для этого МК там должно быть.

    ----------------

    Еще раз пересмотрел исходники и ничего вооьще не понял...
    Прерывания используются в основном АВТОМАТИЕСКИ... Тоесть ты пишеш функцию и говориш МК чтобы ее вызывал когда на ножке будет высокий уровень...

    Но в твоем примере ты вызываеш прерывания вручную
    if (PORTBbits.RB0 == 0) // Условие возникновения прерывания
    {
    _asm
    goto InterruptHandlerHigh //Переходим в функцию обработки прерывания
    _endasm

    Смысла юзать прирывания не вижу... Можна было исползьзовать обычную функцию...

    ------------
    ИМХО
     
  3. CHIP:))

    CHIP:)) Elder - Старейшина

    Joined:
    17 Jan 2007
    Messages:
    81
    Likes Received:
    18
    Reputations:
    -3
    Все нашел обьяснение. Оказывается все как всегда просто. Активный низкий уровень, подключен к RB0 При нажатии любой кнопки входной уровень переключается на землю. В отпущенном состоянии на ней 5Вольт. То есть в нажатом состоянии на ней 0. И при нажатии выполняется
    Code:
     if (PORTBbits.RB0 == 0) 
     
    #3 CHIP:)), 9 Jun 2008
    Last edited: 9 Jun 2008
    1 person likes this.
  4. Animal

    Animal Elder - Старейшина

    Joined:
    19 Oct 2007
    Messages:
    221
    Likes Received:
    89
    Reputations:
    6
    Да, прога конечно - без пузыря не обойдешься... :) Очень заинтересовало, что это за компилятор такой, приведи плиз его полное наименование.
    Далее:
    Code:
    if (PORTBbits.RB0 == 0) // Условие возникновения прерывания
    {
    _asm
    goto InterruptHandlerHigh //Переходим в функцию обработки прерывания
    _endasm
    }
    этого куска не должно быть вообще! Президент правильно сказал, иначе это и не прерывание вовсе.
    Во вторых, после того, как выполнится весь код в функции маин, необходимо программу на месте зациклить, вполне подойдет
    while(true)
    Когда все правильно заработает, у тебя после нажатия на кнопку загорится светодиод раз и навсегда (пока питание не скинешь).
    Дальше есть много интересных предложений, как твою демку сделать более зрелищной и интересной, но ты сначала с этим разберись.
    И еще, к слову, если есть возможность, то возьми сначала контроллер попроще, из 16F семейства и компилятор рекомендую CCS PICC, он попроще в обращении (пример можешь посмотреть в теме "Непримитивная сигнализация")
    Пока все, пожем чем можем, как говорится. :)
     
  5. CHIP:))

    CHIP:)) Elder - Старейшина

    Joined:
    17 Jan 2007
    Messages:
    81
    Likes Received:
    18
    Reputations:
    -3
    Извини что так долго не отвечал, сессия)

    Вобщем компилятор MICROCHIP MPLAB C18.
    Release Notes for MPASM(tm) Assembler version v3.90
    November 8, 2004

    А как должно быть?

    Это я знаю, но мне вроде как ненадо так делать, потом в случае чего исправлю, просто препод как то неопределенно сказал что ему надо)

    С ЭТИМ я уже разобрался, спасибо. Более зрелишно это наверно будет более сложно, или как(прога пишется для людей которые в первый раз в жизни познакомятся с МК и скорее всего вобще с программированием, так что думаю не стоит особо усложнять)? Вобщем жду предложения)

    Это я не для себя ведь делаю, как "начальство" скажет так и сделаю)
     
  6. Animal

    Animal Elder - Старейшина

    Joined:
    19 Oct 2007
    Messages:
    221
    Likes Received:
    89
    Reputations:
    6
    Прерывание сделай по таймеру, чтоб оно раз 200 в секунду вызывалось. А в прерывании: если кнопка нажата, то зажечь светодиод, если не нажата, то погасить. С наворотами программа не обязательно станет сложнее. Больше - да, но она может состоять из нескольких простых относительно независимых блокох, каждый из которых будет достаточно доступен для понимания "неискушенного" программера. :) Семисегментный индикатор не желаешь "прикрутить"?
     
  7. CHIP:))

    CHIP:)) Elder - Старейшина

    Joined:
    17 Jan 2007
    Messages:
    81
    Likes Received:
    18
    Reputations:
    -3
    Нет спс, я думаю и этого уже вполне достаточно)
     
  8. Animal

    Animal Elder - Старейшина

    Joined:
    19 Oct 2007
    Messages:
    221
    Likes Received:
    89
    Reputations:
    6
    Ну да... на пикдеме и свой ЖКшник неслабый есть. :)