Hallo,
ich habe ein Problem mit meiner Schaltung/Programm und finde einfach den
Fehler nicht ;-(
Eine kleine mit 4,5V batteriebetriebene Schaltung soll bei Tastendruck
LED hochdimmem, bei erneutem Tastendruck runterdimmen oder nach ca.
maximal 60s von allein wieder runterdimmen falls keine Taste gedrückt
wurde. Stromsparend solls auch sein. Anwendung ist eine Beleuchtung für
ein Plastikmodell.
Jetzt zum Problem: Die Schaltung funktioniert einwandfrei wenn ich den
Dragon Programmierer dranhängen habe aber spielt verrückt wenn ich sie
vom Dragon trenne. Und das verstehe ich nicht so ganz... Das Programm
überspringt nach Tastendruck z.B. manchmal direkt die Abdimmphase oder
geht sofort nach dem Aufdimmen aus oder noch verrückter: die LED fängt
an zu blinken obwohl in meinem Code nirgendwo ein Blinken programmiert
ist...
Ich vermute ein Übersprechen des Tastenprellens auf die SPI
Schnittstelle oder das evtl. der Interrupt des Aufwachens mehrfach
ausgeführt wird und was anstellt, was ich nicht ergründen kann.
Vielleicht kann mir jemand Tips geben was an meinem Code verbessert
werden kann damit ich das evtl. Softwaremäßig in den Griff bekommen
kann. Ansonsten werde ich gleich mal versuchen das Prellen hardwaremäßig
zu unterdrücken, vielleicht bringt das ja einen Erfolg. Oder sollten die
SPI Kanäle zusätzlich hochohmig geerdet werden?
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/sleep.h>//NEU
#include <avr/interrupt.h>//NEU
int main (void)
{
DDRB |= (1 << PB2);//auf 1 setzen => als Ausgang
PORTB &= ~((1 << PB2));//auf 0 setzen => LED aus
DDRB &= ~((1 << PB1));//als Eingang
PORTB |= (1 << PB1);//mit Pullup
TCCR0A = (1 << COM0A1)|(1 << WGM00);//phase correct PWM
GIMSK |= (1 << PCIE);
PCMSK |= (1 << PCINT1);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
for(;;)
{
//in den Power-Down Modus gehen
sleep_enable();
sei();
sleep_cpu();//ab hier schlafen und aufwachen
sleep_disable();
OCR0A = 0x00;
TCCR0B = (1 << CS01);//Clock = CLK/8, Starte PWM
//Langsames Hochfahren
for(int i=0;i<=40;i+=1)
{
OCR0A = i;
_delay_ms(25);
}
//Beleuchtungsdauer des Modells = i*_delay_ms
for(int i=0;i<=6000;i+=1)
{
if((PINB&(1 << PB1))==0)break;//bei Tastendruck Ende der
Beleuchtungszeit & langsames Abdimmen
_delay_ms(10);
}
//Langsames Runterfahren
for(int i=40;i>=0;i-=1)
{
OCR0A = i;
_delay_ms(25);
}
TCCR0B &= ~((1 << CS02)|(1 << CS01)|(1 << CS00));//Timer aus
}
}
ISR (PCINT_vect)
{
cli();
}