Home Forum MICROCONTROLLORI Aiuto per codice

Questo argomento contiene 3 risposte, ha 2 partecipanti, ed è stato aggiornato da  OPGUIDO 2 anni, 10 mesi fa.

Stai vedendo 4 articoli - dal 1 a 4 (di 4 totali)
  • Autore
    Articoli
  • #58568

    OPGUIDO
    Membro

    Salve, non riesco a far variare la frequenza del secondo pulsante : RB5, mi esce sempre la frequenza impostata nel primo interrupt.
    Dove sbaglio?
    Ecco il codice:

    #include #include
    #include

    #pragma config FOSC = HS
    #pragma config WDT = OFF
    #pragma config LVP = OFF
    #pragma config PBADEN = OFF

    //OSC = HS Impostato per lavorare ad alta frequenza
    //WDT = OFF Disabilitato il Watchdog Timer
    //LVT = OFF Disabilitato programmazione LVT
    //PBADEN = OFF Disabilitato gli ingrassi analogici

    void High_Int_Event (void); //Prototipo di funzione alta priorità

    #pragma code high_vector = 0x08
    void high_interrupt (void) {
    _asm GOTO High_Int_Event _endasm
    }

    #pragma code

    #pragma interrupt High_Int_Event

    void High_Int_Event (void){ //Funzione x la gestione dell’interrupt bassa priorità
    int i; // Indice x il ciclo di pausa

    if (( INTCONbits.RBIF == 1 ) && (INTCONbits.TMR0IF == 1)) { //Controllo che l’interrupt sia stato generato da PORTB
    //for (i=0; i<10000; i++) { //Pausa filtraggio spike
    //}
    if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4

    T0CONbits.T0PS2 = 1;// bits 2-0 PS2:PS0: Prescaler Select bits
    T0CONbits.T0PS1 = 1;
    T0CONbits.T0PS0 = 0;
    TMR0H = 0xFF; // preset for Timer0 MSB register
    TMR0L = 0xC1; // preset for Timer0 LSB register
    LATDbits.LATD1 = ~ LATDbits.LATD1; //Accendo il Led 1
    }
    INTCONbits.RBIF == 0; //Resetto il flag
    INTCONbits.TMR0IF == 0; // Resetto il flag

    }

    if (( INTCONbits.RBIF == 1 ) && (INTCONbits.TMR0IF == 1)) { //Controllo che l’interrupt sia stato generato da PORTB

    if (PORTBbits.RB5 == 0) { //Controllo la pressione di RB5

    T0CONbits.T0PS2 = 0;// bits 2-0 PS2:PS0: Prescaler Select bits
    T0CONbits.T0PS1 = 0;
    T0CONbits.T0PS0 = 0;
    TMR0H = 0x0F; // preset for Timer0 MSB register
    TMR0L = 0xC1; // preset for Timer0 LSB register
    LATDbits.LATD2 = ~ LATDbits.LATD2; //Accendo il Led 2
    }
    INTCONbits.RBIF == 0; //Resetto il flag
    INTCONbits.TMR0IF == 0; // Resetto il flag

    }
    }

    void main (void) {

    unsigned int i; //Variabile usata per creare un conteggio fittizio di pausa

    //Imposto PORTA tutti ingrrssi

    LATA = 0x00;
    TRISA = 0xFF;

    //Imposto PORTB tutti ingrrssi

    LATB = 0x00;
    TRISB = 0xFF;

    //Imposto PORTC tutti ingressi

    LATC = 0x00;
    TRISC = 0xFF;

    //Imposto PORTD tutte uscite

    LATD = 0x00;
    TRISD = 0x00;

    //Imposto PORTE tutti ingrrssi

    LATE = 0x00;
    TRISE = 0xFF;

    EnablePullups (); //Abilita i resistori di PUL-UP sulla PORTB

    T0CONbits.TMR0ON = 1;// Timer0 On/Off Control bit:1=Enables Timer0 / 0=Stops Timer0
    T0CONbits.T08BIT = 0;// Timer0 8-bit/16-bit Control bit: 1=8-bit timer/counter / 0=16-bit timer/counter
    T0CONbits.T0CS = 0;// TMR0 Clock Source Select bit: 0=Internal Clock (CLKO) / 1=Transition on T0CKI pin
    T0CONbits.T0SE = 0;// TMR0 Source Edge Select bit: 0=low/high / 1=high/low
    T0CONbits.PSA = 0;// Prescaler Assignment bit: 0=Prescaler is assigned; 1=NOT assigned/bypassed

    INTCONbits.TMR0IE = 1; //Abilito le interruzioni del timer0

    INTCON2bits.TMR0IP = 1; //Abilito le interruzioni del Timer come alta priorità

    //Abilito le interruzioni

    RCONbits.IPEN = 0; //Abilito interruzioni alta

    INTCONbits.GIE = 1; //Abilito gli interrupt ad alta priorità

    INTCONbits.PEIE = 1; //Abilito gli interrupt

    while (1) { //Ciclo infinito

    }
    }

    #70651

    slovati
    Partecipante

    ciao OPGUIDO,
    osservando il codice mi vengono in mente queste osservazioni:
    1. ho notato che più volte c’è un “==” anziche un singolo “=” nelle istruzioni di reset flag all’interno della routine di interrupt (ad es.: INTCONbits.RBIF == 0; //Resetto il flag). Da un punto di vista teorico, un’istruzione di questo tipo non modifica il contenuto dell’operando (cioè la flag in ogetto non viene alterata), ma tutto dipende da come si comporta lo specifico compilatore (magari quest’ultimo è “furbo” e corregge da solo l’istruzione).
    2. dovresti controllare sul datasheet del micro che stai utilizzando se prima di resettare la flag occorre fare una lettura dal registro (port B nel tuo caso). L’architettura di molti PIC richiede proprio che prima di resettare la flag venga fatta una lettura “fittizia” dal registro (una sorta di latch & reset). Se è così, devi agiungere un’istruzione del tipo pippo=PORTB prima del reset effettivo.
    3. comincerei a correggere queste istruzioni, e poi includerei queste istruzioni nei blocchi aperti dalle istruzioni “if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4″ e analogamente per RB5. Ora, infatti, avviene che le flag vengono resettate anche quando RB4 o RB5 non sono stati premuti. Quindi se si entra nella procedura e RB4 non è stato premuto (ma lo è stato RB5) non si potrà mai entrare nel blocco relativo a RB5 perchè le flag sono state resettate nel blocco precedente.

    Spero di esserti stato utile.
    Saluti

    #70801

    OPGUIDO
    Membro

    Ciao, purtroppo mi chiedi troppo non sono cosi bravo, intanto grazie per avermi risposto. Perche io capisca meglio dovresti modificarmi il codice che ho postato, come compilatore uso MPLABX, se non tutto il codice scrivermi le istruzioni da correggere.
    Grazie

    #70657

    slovati
    Partecipante

    ciao,
    ho provato a modificare solo la routine di interrupt, che ti riporto qui sotto. Tieni presente che non l’ho compilata, ho solo modificato il codice, quindi non è detto che risolva subito il tuo problema:

    void High_Int_Event (void){ //Funzione x la gestione dell’interrupt bassa priorità
    int i; // Indice x il ciclo di pausa
    unsigned char tmp_char;
    if (( INTCONbits.RBIF == 1 ) && (INTCONbits.TMR0IF == 1)) { //Controllo che l’interrupt sia stato generato da PORTB
    //for (i=0; i<10000; i++) { //Pausa filtraggio spike
    //}
    if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4
    T0CONbits.T0PS2 = 1;// bits 2-0 PS2:PS0: Prescaler Select bits
    T0CONbits.T0PS1 = 1;
    T0CONbits.T0PS0 = 0;
    TMR0H = 0xFF; // preset for Timer0 MSB register
    TMR0L = 0xC1; // preset for Timer0 LSB register
    LATDbits.LATD1 = ~ LATDbits.LATD1; //Accendo il Led 1

    tmp_char = PORTB;
    INTCONbits.RBIF = 0; //Resetto il flag
    INTCONbits.TMR0IF = 0; // Resetto il flag
    }
    if (PORTBbits.RB5 == 0) { //Controllo la pressione di RB5
    T0CONbits.T0PS2 = 0;// bits 2-0 PS2:PS0: Prescaler Select bits
    T0CONbits.T0PS1 = 0;
    T0CONbits.T0PS0 = 0;
    TMR0H = 0x0F; // preset for Timer0 MSB register
    TMR0L = 0xC1; // preset for Timer0 LSB register
    LATDbits.LATD2 = ~ LATDbits.LATD2; //Accendo il Led 2

    tmp_char = PORTB;
    INTCONbits.RBIF = 0; //Resetto il flag
    INTCONbits.TMR0IF = 0; // Resetto il flag
    }
    }
    }

    Saluti

Stai vedendo 4 articoli - dal 1 a 4 (di 4 totali)

Devi aver eseguito l’accesso per poter rispondere a questa discussione.