Jag har en "app" som ska bli väckarklocka men även styra sänglampan plus en del annat.
Nu försöker jag PWM:a en lysdiod men den fladdrar trots att jag i min enfald tycker att den inte borde.
void initTimer(void)
{
OCR1A = 250; // timer compare value
TCCR1B = _BV(WGM12) | 2; // Presc -> Clock/ 8 -> 250000 MHz -> int 2000 Hz
TIMSK1 = _BV(OCIE1A);
sei(); /* enable interrupts */
timerCounter = 0;
}
int pwm = 0;
unsigned int pwmcnt;
int pwmdir = 1;
int PWMMAX = 10;
int secs = 0;
ISR(TIMER1_COMPA_vect)
{
timerCounter++; // inc timeout tick
if (++tcount == 2000) // one second tick
{
tcount = 0;
sec_flag = 1;
UTCtime ++;
}
if (++pwmcnt == PWMMAX)
pwmcnt = 0;
cli();
if ((pwmcnt % PWMMAX == 0) && (pwm != 0))
PORTC = 0xF0;
if (pwmcnt % PWMMAX == pwm)
PORTC = 00;
if (sec_flag)
if (secs-- == 0)
{
pwm += pwmdir;
secs = 100;
}
if (pwm == PWMMAX-1)
pwmdir = -1;
if (pwm == 0)
pwmdir = 1;
sei();
}
Jag tycker att Jag med den här koden borde få en blinkhastighet på 200 Hz men är jag kör på de lägre intensiteterna så flimrar lysdioden, med PWMMAX = 4 blir ljuset stabilt men skulle vilja ha lite fler steg.
Har jag ett hjärnsläpp modell större eller vad är fel.
//Den här funktionen startar timern...
void initTimer(void)
{
OCR1A = 250; // timer compare value Interrupt var 250 "tick"
TCCR1B = _BV(WGM12) | 2; // Presc -> Clock/ 8 -> 500000/250 MHz -> int 2000 Hz
TIMSK1 = _BV(OCIE1A);
sei(); /* enable interrupts */
timerCounter = 0;
}
//globala variabler för PWM hanteringen
int pwm = 0; // Vilken "pwm-nivå som används
unsigned int pwmcnt; ////pwmräknare, borde kanske byta till char jag kan i allafall inte köra med så stor PWM
int pwmdir = 1; // Riktning att räkna upp eller ner pwm värdet
int PWMMAX = 10; //Antal PWM steg, borde ge 200Hz
int secs = 0; //Ingen direkt koppling till PWM delen
ISR(TIMER1_COMPA_vect)
{
timerCounter++; // inc timeout tick minns inte exakt vad den här var
if (++tcount == 2000) // one second tick kollar om en sekund upplupit
{
tcount = 0;
sec_flag = 1;
UTCtime ++;
}
// Här kommer PWM delen
if (++pwmcnt == PWMMAX)
pwmcnt = 0;
if ((pwmcnt % PWMMAX == 0) && (pwm != 0))
PORTC = 0xF0;
if (pwmcnt % PWMMAX == pwm)
PORTC = 00;
// Koden som följer räknar upp och ned PWM värdet
if (sec_flag)
if (secs-- == 0)
{
pwm += pwmdir;
secs = 100;
}
if (pwm == PWMMAX-1)
pwmdir = -1;
if (pwm == 0)
pwmdir = 1;
}
Dessutom har jag försökt titta på utkurvan i ett "oscilloskåp" och kunde inte se annat än en kurva på ~200Hz. Tyvärr är skåpet inte riktigt hundra verkar vara ngt glapp eller annat mystiskt. Så hur kan en PWM signal på 200Hz ge ett synligt flimmer?
Okej. Jag tycker din kod verkar stämma. En lysdiod på 200 Hz borde inte flimra.
Men jag undrar varför du kör med modulus i din kod. Den första if-satsen ser ju till att pwmcnt bara går mellan 0 och PWMMAX-1. Du borde därför kunna jämföra "pwmcnt" istället för "pwmcnt % PWMMAX".
Modulus beror på att jag inte nollade pwmcnt tidigare. Eftersom det flimrar för mig så har jag ändrat koden åtskilliga gånger.
Men flimret inte bara att koden verkar stämma "skåpet" säger 200 Hz dessutom men likafullt flimrar det. Ju kortare puls desto mer flimmer.
Kopplingen är som följer.
Ut på porten till basen på en BC337:a.
Emittern till jord.
Spänningen från STK-500 till Powerled.
Powerled till resistor.
Resistor till kollektor.
Har du provat om det blir flimmer med en vanlig lysdiod?
Sen blir väl förresten frekvensen 100 Hz, och inte 200 Hz, eftersom en tänd-släck-cykel är en period.
Kan du inte låta en separat timer sköta PWM:en istället? Då ställer du in pulskvoten genom att helt enkelt ändra motsvarande OCR-register. Då får du ju fler "intensitetsnivåer" också.
Jag har satt ett motstånd i serie mellan porten och 337:an efter första påpekandet kanske lite liten ~150 ohm.
Nej processorn snurrade snällt på kanske beronde på att den går på 3.3 V.
erikbrannlund:
> Lös lysdiod flimrade sist jag provade. Lysdiod på STK-plattan flimrade inte.
Om vissa lysdioder flimrar medan andra inte gör det så är det nog inte AVR:en eller ditt program det är fel på i alla fall. Vad som kan vara fel vet jag däremot inte.
Nu har jag bytt till ett större motstånd mellan port och bas på trissan, 10k blev det. Jag undrar hur jag tänkte när jag inte hade ngt motstånd, inte alls mest troligt. Eventuellt blev flimret mindre men jag har inte haft tid att testa så mycket. Vad som däremot hände är att ADC:n inte stördes lika kraftigt av påslaget ljus, tidigare indikerade den 3-4 grader högre temperatur både inne och ute när lyset var på.
Bumpar denna: Jo flimret blev bättre med motståndet men det försvann inte helt. Däremot om jag slår av ADC:n och inte får några interrupt så blir ljuset helt plötsligt stabilt. Kanske beroende på mina försök att översampla för en högre upplösning enligt ngn appnote från ATMEL.