Aiuto per codice
- Login o registrati per inviare commenti
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 #pragma config FOSC = HS //OSC = HS Impostato per lavorare ad alta frequenza void High_Int_Event (void); //Prototipo di funzione alta priorità #pragma code high_vector = 0x08 #pragma code #pragma interrupt High_Int_Event void High_Int_Event (void){ //Funzione x la gestione dell'interrupt bassa priorità if (( INTCONbits.RBIF == 1 ) && (INTCONbits.TMR0IF == 1)) { //Controllo che l'interrupt sia stato generato da PORTB T0CONbits.T0PS2 = 1;// bits 2-0 PS2:PS0: Prescaler Select bits } 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 } void main (void) { unsigned int i; //Variabile usata per creare un conteggio fittizio di pausa //Imposto PORTA tutti ingrrssi LATA = 0x00; //Imposto PORTB tutti ingrrssi LATB = 0x00; //Imposto PORTC tutti ingressi LATC = 0x00; //Imposto PORTD tutte uscite LATD = 0x00; //Imposto PORTE tutti ingrrssi LATE = 0x00; EnablePullups (); //Abilita i resistori di PUL-UP sulla PORTB T0CONbits.TMR0ON = 1;// Timer0 On/Off Control bit:1=Enables Timer0 / 0=Stops Timer0 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 }
#include
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//WDT = OFF Disabilitato il Watchdog Timer
//LVT = OFF Disabilitato programmazione LVT
//PBADEN = OFF Disabilitato gli ingrassi analogici
void high_interrupt (void) {
_asm GOTO High_Int_Event _endasm
}
int i; // Indice x il ciclo di pausa
//for (i=0; i<10000; i++) { //Pausa filtraggio spike
//}
if (PORTBbits.RB4 == 0) { //Controllo la pressione di RB4
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
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
}
TRISA = 0xFF;
TRISB = 0xFF;
TRISC = 0xFF;
TRISD = 0x00;
TRISE = 0xFF;
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
}
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
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
- Login o registrati per inviare commenti


















3 giorni 17 ore fa
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