uso una stk500 com atmega1284p.
Cercando di risolvere il problema di debouncing ho trovato del codice su internet. Il problema del debouncing è risolto, ma come risultato ho anche un comportamento inaspettato. Riporto il codice:
- Code: Select all
void disattiva_timer0(){
TIMSK0=0x00;
}
void aziona_timer0(){
TCCR0A= (1<<WGM10);
TCCR0B=(1<<CS00);
TIMSK0=(1<<OCF0A);
OCR1A = 255;
}
void inizializza_porte(){
DDRA = 0xff; //porta A in uscita
PORTA = 0xff; //logica inversa
DDRB=0x00; //porta B in entrata
PINB = 0xff; //toggle ai pin.
DDRC = 0xff;// porta C in uscita
DDRD = 0xff; // porta D in uscita
PORTC = 0x00;
PORTD = 0x00;
}
void inizializza_interrupt(){
PCICR = (1<<PCIE1); //abilito gli interrupt per le PCINT1 (porta B)
PCMSK1 = 0xff; //abilito gli interrupt relativi ad ogni pin della porta B per le PCINT1
}
ISR(TIMER0_COMPA_vect){
if(cnt >0/*--f > 0*/){
cnt --;
//PORTC ^= 0xaa;
TCNT0 = 0;
//disattiva_timer0();
}
else{
cnt = 19;
static uint8_t key_state; // debounced and inverted key state:
static uint8_t ct0, ct1; // holds two bit counter for each key
uint8_t i;
/*
* read current state of keys (active-low),
* clear corresponding bit in i when key has changed
*/
i = key_state ^ ~PINB; // key changed ?
/*
* ct0 and ct1 form a two bit counter for each key,
* where ct0 holds LSB and ct1 holds MSB
* After a key is pressed longer than four times the
* sampling period, the corresponding bit in key_state is set
*/
ct0 = ~( ct0 & i ); // reset or count ct0
ct1 = (ct0 ^ ct1) & i; // reset or count ct1
i &= ct0 & ct1; // count until roll over ?
key_state ^= i; // then toggle debounced state
/*
* To notify main program of pressed key, the correspondig bit
* in global variable key_press is set.
* The main loop needs to clear this bit
*/
key_press |= key_state & i; // 0->1: key press detect
}
}
unsigned char ca=0;
int main (void)
{
uint8_t count = 0;
TCCR0A= (1<<WGM10);
TCCR0B=(1<<CS00);
TIMSK0=(1<<OCIE0A);
OCR0A = 255;
TCNT0 = 0;
DDRA = 0x00; // use all pins on PortD for input
PORTB = 0xff; // with pull-up enabled
DDRC = 0xff; // use all pins on PortB for output
PORTC = 0x00; // turn all LED off
DDRC = 0xff; // use all pins on PortB for output
PORTD = 0x00;
inizializza_timer1();
inizializza_porte();
inizializza_carichi();
inizializza_interrupt();
sei();
while(1)
{
while (key_press & ~PINB )
{
pin = ~PINB;
key_press = 0;
}
PORTC = ca;
}
}
quando premo lo switch, fintantoché è premuto, ho il comportamento desiderato. Ma nel momento in cui rilascio, torna nello stato di prima.
Nel caso che ho postato, mi aspetto che ogni volta che premo lo switch, la variabile ca venga incrementata e il suo valore passato alla PORTC a cui sono collegati dei led. Ma succede che ogni volta che lo premo ho sempre il valore 1 e quando rilascio i led si spengono.
Cosa sbaglio?
Saluti.