ti rispondo qui xchè così altri possono trarre spunto da quello che stiamo facendo. E soprattutto altri + esperti di me posso correggere se ci sono errori
una possibile soluzione è questa:
- attivo l'oscillatore interno a 4MHz
- attivo i pullups interni della porta_B (quindi i pulsanti NORMALMENTE APERTI andranno connessi tra i pin B7..B2 della porta_B e massa, meglio se tramite una resistenza... 100ohm ad esempio)
- imposto il timer2 per andare in overflow 25 volte al secondo
- aggancio una ISR al timer2 Questa ISR controlla il valore di 6 variabili (1 per ogni uscita). Se una varibile contiene un valore maggiore di zero allora viene decrementata di 1. Quando il valore di tale variabile raggiunge zero allora porto a livello logico basso l'uscita corrispondente sulla porta_A
- il loop principale controlla continuamente lo stato della porta_B Appena si accorge che uno dei bit da 0..5 è a livello logico 1 allora significa che c'è un pulsante premuto. Quando un pulsante è premuto il valore della relativa variabile viene impostato a 25*15=375 (15 sono i secondi che l'uscita deve rimanere alta) Con questo sistema si risolve il problema del debounce per i pulsanti e il conteggio parte quando si rilascia il pulsante
nb: sul pin 4 della porta_A ci vuole un pullup esterno
#include #use delay(clock=4000000) #fuses NOWDT,INTRC_IO, PUT, NOPROTECT, NOBROWNOUT, NOMCLR, NOLVP, NOCPD
#define T2_INTS_PER_SECOND 25 // (4000000/(4*16*250*10)) #define HIGH_FOR_15SEC T2_INTS_PER_SECOND*15 long out0,out1,out2,out3,out4,out5;
#int_timer2 void timer2_ISR() { if (out0>0) { out0--; if (out0==0) output_low(pin_A0); } if (out1>0) { out1--; if (out1==0) output_low(pin_A1); } if (out2>0) { out2--; if (out2==0) output_low(pin_A2); } if (out3>0) { out3--; if (out3==0) output_low(pin_A3); } if (out4>0) { out4--; if (out4==0) output_low(pin_A4); } if (out5>0) { out5--; if (out5==0) output_low(pin_A5); } }
void main() {
int k;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DIV_BY_16, 250, 10); set_timer2(0); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE);
port_B_pullups(TRUE); output_A(0); out0=0; out1=0; out2=0; out3=0; out4=0; out5=0; enable_interrupts(INT_TIMER2); enable_interrupts(GLOBAL);
while (1) { if (k=(input_B()&0x3f)>0) { if ((k&0x01)==0x01) { output_high(pin_A0); out0=HIGH_FOR_15SEC; } if ((k&0x02)==0x02) { output_high(pin_A1); out1=HIGH_FOR_15SEC; } if ((k&0x04)==0x04) { output_high(pin_A2); out2=HIGH_FOR_15SEC; } if ((k&0x08)==0x08) { output_high(pin_A3); out3=HIGH_FOR_15SEC; } if ((k&0x10)==0x10) { output_high(pin_A4); out4=HIGH_FOR_15SEC; } if ((k&0x20)==0x20) { output_high(pin_A5); out5=HIGH_FOR_15SEC; } } // a key has been pressed (or is being pressed) } // forever loop
} // main