Witam! (Dobry wieczór?)
Przeczesałem "cały internet" i znalazłem wiele rozwiązań mojego problemu, ale żadne spośród tych, które zastosowałem nie przyniosło oczekiwanych rezultatów. A problem - może się wydawać - jest banalny, gdyż chodzi o obsługę zewnętrznego przerwania ze zwykłego tact switcha.
Mikrokontroler steruje za pomocą PWM jasnością diody. PWM działa (lub jak kto woli: "gro i burcy") i to nie jest tematem tego wątku. Przyciskanie switcha powoduje przejście w kolejne tryby jasności (różne wypełnienie PWM) oraz wyłączenie diody.
Zastosowałem sprzętową filtrację zakłóceń ze switcha. Problem polega na tym, że gdy nie zastosuję kondensatora (schemat), zachodzi debouncing, a przerwanie jest wywoływane wiele razy. Gdy go zastosuję, uC reaguje przerwaniem na co 10-te wciśnięcie switcha.
- Czy konfiguracja obwodów jest poprawna?
- Jak dobrać wartości rezystora oraz kondensatora?
- Czy zastosować programowy debouncing? Jak powinien wyglądać poprawny kod?
- Jak w ogóle (z zachowaniem elektronicznego ZEN) podłączyć i obsłużyć zwykły switch w C?
Poniżej zamieszczam kod źródłowy programu. Jest do bólu prosty. Zwracam się z prośbą do forumowiczów o garść porad dla początkującego
Dzięki!
Przeczesałem "cały internet" i znalazłem wiele rozwiązań mojego problemu, ale żadne spośród tych, które zastosowałem nie przyniosło oczekiwanych rezultatów. A problem - może się wydawać - jest banalny, gdyż chodzi o obsługę zewnętrznego przerwania ze zwykłego tact switcha.
Mikrokontroler steruje za pomocą PWM jasnością diody. PWM działa (lub jak kto woli: "gro i burcy") i to nie jest tematem tego wątku. Przyciskanie switcha powoduje przejście w kolejne tryby jasności (różne wypełnienie PWM) oraz wyłączenie diody.
Zastosowałem sprzętową filtrację zakłóceń ze switcha. Problem polega na tym, że gdy nie zastosuję kondensatora (schemat), zachodzi debouncing, a przerwanie jest wywoływane wiele razy. Gdy go zastosuję, uC reaguje przerwaniem na co 10-te wciśnięcie switcha.
- Czy konfiguracja obwodów jest poprawna?
- Jak dobrać wartości rezystora oraz kondensatora?
- Czy zastosować programowy debouncing? Jak powinien wyglądać poprawny kod?
- Jak w ogóle (z zachowaniem elektronicznego ZEN) podłączyć i obsłużyć zwykły switch w C?
Poniżej zamieszczam kod źródłowy programu. Jest do bólu prosty. Zwracam się z prośbą do forumowiczów o garść porad dla początkującego
Dzięki!
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define set_pwm(value) OCR1B=value
volatile unsigned int pwm = 0;
void start_pwm(void){
/* use PWM B on timer 1 (8-bit PWM) */
GTCCR = _BV(PWM1B) | _BV(COM1B1);
/* start timer 1 */
TCCR1 = _BV(CS10);
/* Set PWM value to 230 */
set_pwm(250);
/* Enable OC1B (PB4) as output and set to low. */
DDRB |= _BV(DDB4);
PORTB &= ~(_BV(PORTB4));
/* Enable Timer1 Interrupt for system_timer update */
TIMSK = _BV(TOIE1);
}
void stop_pwm(void){
// disable Timer1 overflow
TIMSK &= ~(_BV(TOIE1));
// disable PWM output and stop PLL
GTCCR = 0;
}
void switch_mode(void) {
start_pwm();
if(pwm==0) {
set_pwm(80);
}
else if (pwm==1) {
set_pwm(250);
}
else if (pwm==2) {
stop_pwm();
}
if(++pwm == 3)
pwm = 0;
_delay_ms(500);
}
ISR(INT0_vect)
{
switch_mode();
}
int main (void)
{
DDRB &= ~_BV(PB2); //PB2 as input
MCUCR |= _BV(ISC00) | _BV(ISC01); //rising edge int0
GIMSK |= _BV(INT0); //enable int0
start_pwm();
sei();
for(;;) {
}
return (0);
}
