PWM generation using PIC24, DsPIC33, DsPIC30 or Controlling Fan Speed using PWM. (Code + Proteus Simulation)
This post will help us how to control speed of DC brushless Fan using PWM or how to generate PWM using 16bit microcontroller.
I am using MPLAB x IDE and C30 Compiler and Proteus Simulation on v8.0 (code and Proteus Simulation can be downloaded from downloads section at the bottom of this post). This code will work on PIC24, DsPIC33 and DsPIC30 (16bit microcontroller) by slightly changing the code.
I supposed that you know how to get input if not then I recommend to read this post before proceeding.
In the following figure I used two buttons one for increasing fan speed named “UP” and other for decreasing fan speed named “Down” which actually changing the pulse width of the signal given to the NPN transistor I used the frequency of 488Hz with 16MHz crystal. You can see the pulse width to be changing by simulating this example in Proteus. Remember that for DC small fan (approximately 650mW) this transistor is good otherwise you should use high wattage transistor for higher current. In this PIC24 we have Output Compare module for generating PWM. I am using PIC24F16KA102 which has only one PIN for generating PWM ie OC1.
|PWM Generation Proteus Simulation.|
In the following figure we have main function in which we have DutyCycle variable which will be decremented when down button is pressed and incremented when up button is pressed. InitializeTimer2For_PWM() this is function for initialing timer2 for generating precise frequency on OC1 pin. Initialize_PWM() is a function in which we initialize Output Compare module as generation of PWM. Then I enabled pullup resisters on buttons as I am not using external pullups which reduced my number of external components.
In while loop I increase the width by increasing the duty cycle whenever Up button is pressed and decreasing it whenever Down button is pressed. If conditions are very important this act as a guard to increase or decrease PWM within upper limits or lower after this we may have high or low continuous signal on OC1 PIN which may cause damage.
As I am using 488Hz which has max bits resolution of 15bits beyond this there will be a high signal. So it is 0x7FFF. The frequency and resolution is calculated by following formulas.
|formula for frequency Calculation.|
|formula for PWM resolution calculation.|
From formula one I got value for 488Hz which is 0x7FFF (hex) and has 15bits resolution.
In the figure below I configured timer2 for generating interrupt with a frequency of 488Hz. This variable is responsible for generation of frequency at OC1 pin.
|Timer2 for Frequency.|
In the following figure I configured Output Compare module for PWM generation with OCRS value min. for initial Pulse Width rest of the pulse is controlled by the value placed in OC1RS which is set by the function named SetDutyCycle_PWM(Parameter). Parameter is passed for the value of Dutycycle you required.
|Setting desired dutycycle function.|
You can download Code and Proteus Simulation Click here