pwm-styra 8 fläktar med en PIC?
Ok. Styrningen ska användas till pc-fläktar med storlekar på 120mm eller mindre, så mer än 0,5A per kanal/fläkt lär inte behövas. För att bli lite mer realistisk så får väl 8 nivåer räcka. Men jag vill fortfarande kunna ha 8 individuella fläktar.
Kanske detta är lite mer genomförbart. Dessutom lär inte pwm behövas. Vilket är det billigaste sättet att styra fläkar individuellt med 8 nivåer? Jag skulle kunna ha 8st motstånd med olika värden på som kopplas i serie med fläkten, frågan är hur.
Kanske detta är lite mer genomförbart. Dessutom lär inte pwm behövas. Vilket är det billigaste sättet att styra fläkar individuellt med 8 nivåer? Jag skulle kunna ha 8st motstånd med olika värden på som kopplas i serie med fläkten, frågan är hur.
Med 20 Khz och 8 nivåer så behöver en programvaru-PWM anropas
med ett intervall om ca 6 us. Fortfarande lite väl tight. Om du kan
ha en lägre PWM frekvens (och kanske filtrera spänningen lite för att
jämna ut pulserna) så blir det enklare.
> Jag kanske borde utföra ett experiment med lågfrekvens pwm på
> en fläkt och se om det bildas otrevliga ljud eller inte,
Absolut!
Det är den typen av proof-of-concept tester som måste göras innan
man binder sig mot en specifik teknisk lösning.
med ett intervall om ca 6 us. Fortfarande lite väl tight. Om du kan
ha en lägre PWM frekvens (och kanske filtrera spänningen lite för att
jämna ut pulserna) så blir det enklare.
> Jag kanske borde utföra ett experiment med lågfrekvens pwm på
> en fläkt och se om det bildas otrevliga ljud eller inte,
Absolut!
Det är den typen av proof-of-concept tester som måste göras innan
man binder sig mot en specifik teknisk lösning.
Siktar du på 8 nivåer, ca 12 kHz med en AVR på 20 MHz systemklocka så är det betydligt mer rimligt att köra mjukvaru-PWM på godtyckligt antal pinnar (kanaler).
En timer utan prescaler satt på compare-mode i ugefär ~200 steg ger:
20 MHz/(200*8) = 12,5 kHz
sen måste du se till att avbrottshanteraren tar mindre än 200 instruktioner att exekvera i värsta tänkbara situationen.
Edit: Smilie och stavning
En timer utan prescaler satt på compare-mode i ugefär ~200 steg ger:
20 MHz/(200*8) = 12,5 kHz
sen måste du se till att avbrottshanteraren tar mindre än 200 instruktioner att exekvera i värsta tänkbara situationen.
Edit: Smilie och stavning
Senast redigerad av $tiff 6 april 2008, 22:48:34, redigerad totalt 2 gånger.
Kan jag inte göra så här i koden:
säg att jag har ca 20 000 interrupt i sekunden och att jag har valt nivå 3 på en fläkt.
Vid varje interrupt ökar jag en variabel med 3 och kollar sedan om variabeln är större eller lika med 8, är den det så minskas variabelns värde med 8 och fläkten får vara på fram till nästa interrupt. men varje gång variabeln är mindre än 8 så får fläkten vara av fram till nästa interrupt.
Detta sätt fungerar perfekt med nivåer som är jämt delbara med åtta, i de fall där det inte är jämt delbart t.ex. 3, så blir det inte helt bra, men kanske tillräkligt?
säg att jag har ca 20 000 interrupt i sekunden och att jag har valt nivå 3 på en fläkt.
Vid varje interrupt ökar jag en variabel med 3 och kollar sedan om variabeln är större eller lika med 8, är den det så minskas variabelns värde med 8 och fläkten får vara på fram till nästa interrupt. men varje gång variabeln är mindre än 8 så får fläkten vara av fram till nästa interrupt.
Detta sätt fungerar perfekt med nivåer som är jämt delbara med åtta, i de fall där det inte är jämt delbart t.ex. 3, så blir det inte helt bra, men kanske tillräkligt?
Visst gör det det, det är en helt vanlig programvaru PWM du har beskrivit.
Men notera att frekvensen som fläkten ser = interruptfrevnesen delat
med antal steg, d.v.s 20 KHz/8 = 2.5 KHz. Om du kör med tätare
interrupt så stiger PWM frekvensen i samma grad. Det är av denna anledning
som det blir strultigt med många steg. T.ex 20KHz/256 om du vill ha 256 steg.
Men notera att frekvensen som fläkten ser = interruptfrevnesen delat
med antal steg, d.v.s 20 KHz/8 = 2.5 KHz. Om du kör med tätare
interrupt så stiger PWM frekvensen i samma grad. Det är av denna anledning
som det blir strultigt med många steg. T.ex 20KHz/256 om du vill ha 256 steg.
om styrningen har 8 steg och är inställd på 1 så blir det alltså först 7st interrupt då fläkten är avstängd och sedan 1st interrupt då den är påslagen. pwm upplösningen blir alltså 20kHz/8 = 2.5kHz. Men om styrningen är inställd på nivå 4 så är fläkten igång en interrupt och sedan av en interrupt. Borde inte detta bli en upplösning på 10kHz?
- Swech
- EF Sponsor
- Inlägg: 4750
- Blev medlem: 6 november 2006, 21:43:35
- Ort: Munkedal, Sverige (Sweden)
- Kontakt:
Det går att göra en mjukvaru pwm som klarar detta med 9 interrupts,
Först - utanför interrpt, skapa en tabell över dina 8 pwm värden,
sortera tabellen i stigande PWM ordning.
Exempel. 10% 16% 30% 35%.....
detta omvandlas till tidskonstanter. 0-255
Sätt din capture compare timer till 0
Sätt på alla fläktar.
sätt ditt första compare värden till första värdet i tabellen
Invänta capture/compare interrupt
I interruptet, stäng av första fläkten 10% i exempel.
Hämta capture compare för nästa fläkt 16% i vårt fall
Sätt capture compare till detta värde
invänta nytt inerrupt
upprepa tills tabellen är slut.
Invänta timer overflow och börja om från början.
Först - utanför interrpt, skapa en tabell över dina 8 pwm värden,
sortera tabellen i stigande PWM ordning.
Exempel. 10% 16% 30% 35%.....
detta omvandlas till tidskonstanter. 0-255
Sätt din capture compare timer till 0
Sätt på alla fläktar.
sätt ditt första compare värden till första värdet i tabellen
Invänta capture/compare interrupt
I interruptet, stäng av första fläkten 10% i exempel.
Hämta capture compare för nästa fläkt 16% i vårt fall
Sätt capture compare till detta värde
invänta nytt inerrupt
upprepa tills tabellen är slut.
Invänta timer overflow och börja om från början.
- Swech
- EF Sponsor
- Inlägg: 4750
- Blev medlem: 6 november 2006, 21:43:35
- Ort: Munkedal, Sverige (Sweden)
- Kontakt:
jag vet inte riktingt kopplingen 20Mhz -5Mhz ......
men det bör gå att få till en 19,5kHZ pwm
Finns 2 hakar att tänka på så att det inte bryter ihop.
Man måste ta hänsyn till om det finns 2 identiska PWM värden.
Man måste ha en differens mellan två pwm värden som är större
än exekveringstiden för interruptrutinen.
Tar det t.ex. 3uS att exekvera interrupten måste PWM
värdesdiffen vara större än 3uS...
Swech
men det bör gå att få till en 19,5kHZ pwm
Finns 2 hakar att tänka på så att det inte bryter ihop.
Man måste ta hänsyn till om det finns 2 identiska PWM värden.
Man måste ha en differens mellan två pwm värden som är större
än exekveringstiden för interruptrutinen.
Tar det t.ex. 3uS att exekvera interrupten måste PWM
värdesdiffen vara större än 3uS...
Swech
Det är *ett* sätt att göra det på.
Du kan bl.a få problem om två fläktvärden ligger för "tätt"
så att interruptet inte hinner igenom i tid. Två fläktar med samma
värde går dock att hantera, med lite extra kod i ISR'en för att hantera det
fallet.
Dessutom, om du ska ha 19,5 KHz och (enligt exemplet) 256 nivåer,
så kommer det bara att vara ca 0.2 us mellan varje "värde" för
de olika fläktarna. Du behöver sannolikt ett steg om minst 10-20 us
(d.v.s 50-100 instruktionscykler) för att kunna vara säker på att du
"hinner runt" i ISR'en och sätta ett nytt compare-värde o.s.v. Annars
missar du en fläkt helt och hållet. I slutänden vinner du ingenting
på den metoden jämfört med den vanliga metoden nedan.
Det rimliga (och även det vanliga) sättet att hantera det är att ha
en räknare per PWM-kanal, dessa sätts initialt till ett värde som
motsvarar duty-cycle för resp kanal. Dessa räknas sedan alla ner
i en Timer-ISR och respektive PWM-kanal "nollas" om räknaren kommer
till noll. När en huvudräknare även har kommit till noll så återställs
alla värden och allt börjar om.
Vilken frekvens man lyckas köra med, beror på hur kompakt man
kan skriva timer-ISR'en och hur många "steg" man behöver.
Ytterligare en helt annan metod är att låta sin processor styra någon
av Maxim's "fan-controllers", eller att helt enkelt bara använda Maxim
kretsarna, de är kompletta med temp-mätning och allt. Men det
kanske inte passar in riktigt i ditt projekt...
Slutligen ett par länkar...
http://www.piclist.com/techref/microchip/pwm.htm
http://www.dattalo.com/technical/software/pic/pwm8.asm
Du kan bl.a få problem om två fläktvärden ligger för "tätt"
så att interruptet inte hinner igenom i tid. Två fläktar med samma
värde går dock att hantera, med lite extra kod i ISR'en för att hantera det
fallet.
Dessutom, om du ska ha 19,5 KHz och (enligt exemplet) 256 nivåer,
så kommer det bara att vara ca 0.2 us mellan varje "värde" för
de olika fläktarna. Du behöver sannolikt ett steg om minst 10-20 us
(d.v.s 50-100 instruktionscykler) för att kunna vara säker på att du
"hinner runt" i ISR'en och sätta ett nytt compare-värde o.s.v. Annars
missar du en fläkt helt och hållet. I slutänden vinner du ingenting
på den metoden jämfört med den vanliga metoden nedan.
Det rimliga (och även det vanliga) sättet att hantera det är att ha
en räknare per PWM-kanal, dessa sätts initialt till ett värde som
motsvarar duty-cycle för resp kanal. Dessa räknas sedan alla ner
i en Timer-ISR och respektive PWM-kanal "nollas" om räknaren kommer
till noll. När en huvudräknare även har kommit till noll så återställs
alla värden och allt börjar om.
Vilken frekvens man lyckas köra med, beror på hur kompakt man
kan skriva timer-ISR'en och hur många "steg" man behöver.
Ytterligare en helt annan metod är att låta sin processor styra någon
av Maxim's "fan-controllers", eller att helt enkelt bara använda Maxim
kretsarna, de är kompletta med temp-mätning och allt. Men det
kanske inte passar in riktigt i ditt projekt...

Slutligen ett par länkar...
http://www.piclist.com/techref/microchip/pwm.htm
http://www.dattalo.com/technical/software/pic/pwm8.asm
Jo jag inser att det inte får vara för tätt mellan värdena, jag hade ju inte tänkt ha mer än kanske 8-10 värden mellan 0 och 255 så det blir nog inga problem. Kopplingen mellan 20MHz och 5M-instruktioner är ju för att varje instruktion tar 4 svängningar att utföra, kanske tog det för hastigt där.
Tack för länkarna, får ta mig en titt på dem och maxim kretsarna.
edit: Jag menar inte att jag ska ha 256 nivåer i exemplet. Säg att man har en fläkt på nivå 50 och en annan på 150. Då slår man på alla fläktar, räknar upp till 50, slår av den fläkten, räknar upp till 150, slår av den fläkten och till sist räknar man upp till 255 och kör om hela proceduren. Därav uträkningen 5000000/256.
Tack för länkarna, får ta mig en titt på dem och maxim kretsarna.
edit: Jag menar inte att jag ska ha 256 nivåer i exemplet. Säg att man har en fläkt på nivå 50 och en annan på 150. Då slår man på alla fläktar, räknar upp till 50, slår av den fläkten, räknar upp till 150, slår av den fläkten och till sist räknar man upp till 255 och kör om hela proceduren. Därav uträkningen 5000000/256.