Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

PIC16lf1906 - przerwanie INT źle działa

satanistik 12 Wrz 2013 09:59 1320 2
  • #1 12 Wrz 2013 09:59
    satanistik
    Poziom 27  

    Przerwanie źle działa - reaguje n zmianę stanu jednak tylko raz na kilkanaście zmian.
    Jeżeli uruchamiam procesor ze stanem wysokim na wejściu INT a INTEDG = 0 (zbocze opadające) to po starcie procedura obsługi przerwania jest wywoływana. Jeżeli jest tam zero to po starcie nie wchodzi do procedury obsługi.

    Przerwanie kiedy procesor pracuje wywoływane jest dopiero po wielokrotnym wciśnięciu dołączonego przycisku.

    Code:

    //#include "16f1906.h"


    //#pragma unlockISR //poczatek programu poza obszarem przerwan
    void delay_ms(char msek);
    char bity;
    //interrupt isr();
    #pragma origin 4
    interrupt isr()
    { //przerwania

    // char svrWREG, svrSTATUS;
    //    svrWREG = W;
    //    svrSTATUS = swap(STATUS);

    if (INTF==1){ //funkcja od przerwania int

    if (bity == 1){
    INTF = 0;



    LCDDATA1 = 255;
    }

    else{


    LCDDATA3 = 255;
    }[syntax=c][/syntax]
    }


    void main()
    {

    TRISB = 0b11111111; //
    ANSELB = 0;
    //przerwanie int
    PEIE = 0;
    IOCIE = 0;

    TMR0IE = 0;
    INTEDG = 0; //falling edge
    INTE = 1; //enable int interrupts

    OSCCON = 0b01101011; //4Mhz internal
    //TMR0CS = 0; //timer taktowny z oscylatora
    //PSA = 0; //prescaler przypisany do timera
    //PS0 = 1;
    //PS1 = 1;
    //PS2 = 0;
    //lcd controler
    LCDEN = 1;
    SLPEN = 0;
    CS0 = 0;
    CS1 = 0;
    LMUX0 = 1;
    LMUX1 = 1;
    WFT = 1;
    BIASMD = 0;
    LCDA = 1;
    WA = 1;

    LP0 = 0;
    LP1 = 0;
    LP2 = 0;
    LP3 = 0;

    VLCD3PE = 0;
    VLCD2PE = 0;
    VLCD1PE = 0;

    LCDIRE = 1;
    LCDIRI = 0;

    LCDCST = 7; //kontrast na 0max 7min

    LCDSE0 = 0b10110110;
    LCDSE1 = 0b01110000;
    LCDSE2 = 0b00000000;
    LCDSE3 = 0b00000110;
    LCDRL = 0b01010100;
    LCDDATA3 = 0;
    LCDDATA0 = 0;
    LCDDATA1 = 0;//uzyty  w przerwaniu
    //LCDDATA2 = 0;//nie uzywany
    //LCDDATA3 = 0;
    LCDDATA4 = 0;
    //
    LCDDATA6 = 0;
    LCDDATA7 = 0;
    //
    //LCDDATA9 = 0;//nie uzywany
    LCDDATA18 = 0;
    LCDDATA10 = 0;
    LCDDATA15 = 0;
    LCDDATA12 = 0;
    LCDDATA21 = 0;

    while(1)
    {

    LCDDATA9 = 255;
    delay_ms(300);
    LCDDATA9 = 0;
    delay_ms(300);
    }


    }


    void delay_ms(char msek)
    {
       do{
       TMR0=0;
       while(TMR0<125)
       ;}

       while(--msek>0);
       
       
    }

    0 2
  • #2 12 Wrz 2013 10:23
    solarstone
    Poziom 11  

    nie widzę GIE = 1;

    0
  • #3 12 Wrz 2013 12:35
    satanistik
    Poziom 27  

    GIE = 1; było jednak przy kopiowaniu na forum przypadkiem usunąłem.
    Okazało się że problemem nie był brak przerwania tylko wykorzystanie do wizualizacji segmentu LCD. Kontroler LCD źle znosi bezpośredni zapis i nie zawsze to działa.

    0