soluzione PWM e INTERRUPT

13 Anni 7 Mesi fa #1 da Guido
soluzione PWM e INTERRUPT è stato creato da Guido
Forse ho trovato la soluzione per gestire un pulsante con l'interurpt abbinato al Pwm, ditemi se è la souzione.
Ecco il codice:

# include <p18f4550.h>

# include <pwm.h>
# include <timers.h>
#include <portb.h>

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


//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
//CCP2MX = ON il modulo CCP è posto su RC1

void High_Int_Event (void); //Prototipo di funzione basa 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 alta priorità

int i; // Indice x il ciclo di pausa

unsigned char period; //Periodo del segnale pwm





if ( INTCONbits.RBIF == 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


OpenPWM2(period) ; //Apro il modulo pwm

OpenTimer2 (TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_8 ); //Apro il timer2 per il pwm


period = 252; //249Imposto una frequenza di 20KHz


SetDCPWM2 (500); //Aggiorno il duty cycle

}

else {
ClosePWM2 () ; // Chiudo il modulo pwm
}
}
INTCONbits.RBIF = 0; //Resetto il flag


}


void main (void) {

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

unsigned char period; //Periodo del segnale pwm

int duty_cycle = 0; //Duty Cycle

//Imposto PORTA tutti ingrrssi

LATA = 0x00;
TRISA = 0xFF;

//Imposto PORTB tutti ingrrssi

LATB = 0x00;
TRISB = 0xFF;

//Imposto PORTC tutti ingressi ad RC1 come uscita

LATC = 0x00;
TRISC = 0b11111101;

//Imposto PORTD tutte uscite

LATD = 0x00;
TRISD = 0x00;

//Imposto PORTE tutti ingrrssi

LATE = 0x00;
TRISE = 0xFF;

EnablePullups (); //Abilito resistori di pullups



INTCONbits.RBIE = 1; //Abilito le interruzioni su PORTB

INTCON2bits.RBIP = 1; //Abilito le interruzioni su PORTB come alta priorità



//Abilito le interruzioni

RCONbits.IPEN = 0; //Abilito interruzioni alta priorità


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

INTCONbits.PEIE = 1; //Abilito gli interrupt delle periferiche



}


Lo testato con PROTEUS funziona, fa un po fatica a partire, mi spiego: devo premere più volte il pulsante una volta innescata la frequenza tutto funziona a dovere, ho provato a variare il tempo di pausa, in meno è peggio.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
13 Anni 7 Mesi fa #2 da Guido
Risposta da Guido al topic Re: soluzione PWM e INTERRUPT
Qundo uno pensa di aver capito ecco che si riparte da capo. Ho aggiunto un altro pulsante e ne funziona uno solo.
Codice:
# include <p18f4550.h>

# include <pwm.h>
# include <timers.h>
#include <portb.h>

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


//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
//CCP2MX = ON il modulo CCP è posto su RC1

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 alta priorità

int i; // Indice x il ciclo di pausa

unsigned char period; //Periodo del segnale pwm





if ( INTCONbits.RBIF == 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


OpenPWM2(period) ; //Apro il modulo pwm

OpenTimer2 (TIMER_INT_OFF & T2_PS_1_16 & T2_POST_1_16 ); //Apro il timer2 per il pwm


period = 255; //249Imposto una frequenza di 20KHz


SetDCPWM2 (500); //Aggiorno il duty cycle

}

else {
ClosePWM2 () ; // Chiudo il modulo pwm
}

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


OpenPWM2(period) ; //Apro il modulo pwm

OpenTimer2 (TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_1 ); //Apro il timer2 per il pwm


period = 255; //249Imposto una frequenza di 20KHz


SetDCPWM2 (500); //Aggiorno il duty cycle

}

else {
ClosePWM2 () ; // Chiudo il modulo pwm
}

INTCONbits.RBIF = 0; //Resetto il flag
}

}


void main (void) {

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

unsigned char period; //Periodo del segnale pwm

int duty_cycle = 0; //Duty Cycle

//Imposto PORTA tutti ingrrssi

LATA = 0x00;
TRISA = 0xFF;

//Imposto PORTB tutti ingrrssi

LATB = 0x00;
TRISB = 0xFF;

//Imposto PORTC tutti ingressi ad RC1 come uscita

LATC = 0x00;
TRISC = 0b11111101;

//Imposto PORTD tutte uscite

LATD = 0x00;
TRISD = 0x00;

//Imposto PORTE tutti ingrrssi

LATE = 0x00;
TRISE = 0xFF;

EnablePullups (); //Abilito resistori di pullups



INTCONbits.RBIE = 1; //Abilito le interruzioni su PORTB

INTCON2bits.RBIP = 1; //Abilito le interruzioni su PORTB come alta priorità



//Abilito le interruzioni

RCONbits.IPEN = 0; //Abilito interruzioni alta priorità


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

INTCONbits.PEIE = 1; //Abilito gli interrupt delle periferiche



}


AIUTOOO.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
13 Anni 7 Mesi fa #3 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: soluzione PWM e INTERRUPT
Ciao,

ho dato uno sguardo veloce.
Se il primo programma funziona mi sembra strano che il secondo non debba.
hai semplicemente copiato il blocco per il controllo del pulsante, cambiando il bit da controllare.
Hai inoltre correttamente impostato il registro TRISB.

In ogni modo cerca una soluzione alternativa al simulatore.
Quando qualcosa non funziona e hai il simulatore tra le mani è difficile capire chi effettivamente stia causando problemi. Se avverti che il simulatore fa fatica a partire con un programma di questo tipo ti dovrebbe far capire che c'e' pure qualcosa di sospetto nel simulatore (Proteus è comunque un ottimo programma).

OpenTimer2 (TIMER_INT_OFF & T2_PS_1_16 & T2_POST_1_16 ); //Apro il timer2 per il pwm

deve essere eseguito prima di OpenPWM.
Questa impostazione è inoltre in comune a tutto e non deve essere eseguita ogni volta.

Monta due componenti sua una bread board e testa il programma.

Imparare sbagliando è ok, ma purtroppo i PIC non seguono delle leggi fisiche che possono essere intuite o meno.
Devono essere impostati e il modo con cui impostarli dipende dalle decisione che i progetti hanno scelto.
Questo si ripercuote in un determinato registro che deve essere propriamente impostato. Come farlo non può essere lasciato alla creatività. Si deve leggere la documentazione e seguire i passi da seguire per impostare una periferica, altrimenti potrebbe non lavorare correttamente.

Saluti,

Mauro

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Moderator
  • Moderator
Di più
Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login