Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] pwm microcontroler using pic16f62a

Not open for further replies.


Newbie level 5
Aug 19, 2015
Reaction score
Trophy points
Activity points
Microcontroller based PWM fan controller with temperature feedback and overvoltage protection
The developed device should control the speed of a low voltage DC fan using a programmable microcontroller. The controller should cut-off the supply to the fan if the supply voltage exceeds 14V It must also automatically run the fan at full speed if the temperature in the ventilated area exceeds 70 deg C.The minimum specifications are:

1. The device should provide manual speed control of a 12V DC fan using pulse width modulation.
2. The control should be exercised either by the means of a potentiometer or by two push-buttons for acceleration and deceleration of the fan’s motor.

3. The device should be able to supply to the fan a current of up to 3A.The nominal voltage of the motor is 12V DC.

4. The speed of the motor should be controlled continuously from zero to its maximum value, corresponding to 12 V DC supply.

5. The fan motor supply should be disconnected if the supply voltage to the controller exceeds 14 V. It should be re-connected automatically if it is below 14 V.

6. There should be a red LED light on the front panel of the device indicating the ‘overvoltage’ condition described in 5.

7. The device should have an externally connected temperature sensor that should monitor the temperature of the ventilated by the fan area. If the temperature on the sensor exceeds 70 degrees C, the controller should start operating the fan automatically at maximum speed, regardless of the current manual setting. The speed of the fan is restored to the relevant manual setting once the temperature drops to 60 deg C.
8. The ‘high temperature’ condition should be indicated by a dedicated LED light on the front panel of the device.
i am struggling with this please assist.

There is no such device as a PIC16F62A so I'm assuming you mean a 16F627A or 16F628A which are almost identical to each other.

1. CCP1 (=RB3) is the pin producing PWM output. Use it to drive a transistor, preferably a MOSFET in series with the 12V supply and fan motor.

2. Tricky if you use a potentiometer because the 16F62xA does not have an ADC but easy with push buttons. Use one to increase PWM ratio, one to decrease it.

3. This is an electrical requirement, make sure the control transistor can handle > 3A.

4. Means the PWM must be adjustable from 0% to 100% which is it's normal range anyway.

5. Scale the 14V to something lower than 5V using resistors then connect it to one of the comparator inputs. Use it's output to enable or disable the PWM signal.

6. Same as 5 but use the signal to drive an IO pin withthe LED wired to it.

7. Derive a voltage from the temperature sensor and feed it to the other comparator. When the 70C voltage is exceeded, set the PWM to 100%, otherwise as in 2.

8. Same as 6. Use another IO pin to show the output of the second comparator.

It's a simple task and requires only a few external components. If you want to be adventurous, the challenge would be to read an analog voltage from the potentiometer without using an external ADC. It can be done but I'll leave you to work that one out!

Are you the one who asked this same question at mikroE forum ? If yes, then which compiler are you using to make the code ? I can help you with XC8 and mikroC PRO codes.

Please bear in mind the purpose of Edaboard is to help people by offering help in an open way so others can read and learn from it. Offering help like that will only work if you explain the reasoning for the solution you reach and the methods you used. While it may be very generous of you to do the work for garostoss, it will not help them or anyone else if you just hand over a finished program.

If you are offering private help, you message should be posted in the business advertizing section, also please do not promote specific compilers, especially if they are commercial products.


thanx for the reply im using assembler from microlabs the code challenges me when i get to the part where is should create signals which increase or decrease by 1v and im new to pwm modulation,iv been stuck for like 3 weeks trying to understand it

- - - Updated - - -

thanx im using assembler from microlabs and the part that is challenging the most is the code for the pwm , i dont undastand it at all been trying many online pdfs but they all explain it to much diffrent, if u can may please send m a code thas in assembler so i may undasatnd mode thank you

Sorry, I don't do asm programming much but myself and others here can try to help you if you can post your asm code.

The basics:

PWM doesn't control the voltage - it controls how long the voltage is present for. In the case of a fan, the speed can be controlled (crudely if you don't employ a feedback mechanism) by controlling the average power you give it. The average is over time, typically only a few milliseconds. The PWM signal is normally kept at a constant frequency but within each cycle the duration the signal is low or high can be changed. Using easy figures to explain, if the cycle period is 100mS (that's 10Hz, you would normally use much higher frequency!) and your PWM signal was high for 1mS and then low for 99mS, the average would be 1%, if your high was 50mS and low was 50mS, the average would be 50% and if your high was 90mS and low was 10mS, the average would be 90%. So within the same cycle rate, you can control the average amount of 'push' to the fan and hence it's speed.

You can convert the PWM signal to a variable analog voltage by electronically averaging it but in the case of your fan that probably isn't necessary, just pulsing the power directly with the PWM waveform should suffice.

What you need to do is work out how to put the PIC into PWM mode at the frequency you want (Timer 2 / PR2) and how to control the high/low ratio using CCPR1L and CCP1CON. Then by changing those values you control the fan speed. You can step the values up or down with your switches to increase or decrease the fan power.


if i get you right in my program i do not have to set values for the ccpr1l and ccp1con since im using push button switches and set the pic in pwm mode?

Its like you are switching ON the Fan for 2 secs OFF and 1 sec ON as repeatedly then the fan will run slow.

If you turn OFF for 1 sec and ON for 2 sec then the fan will run comparatively faster (first one is 1/3 of rated power and second one is 2/3 of rated power).

So by adjusting the ON and OFF time you are controlling the power of the FAN but without making it completely OFF in any situation So you have to it with a higher frequency.
oh nw i see...pwm its just to switch off the fan on and off at diffirent time intervals

- - - Updated - - -

well let me try make the assembler program il post it s soon s im done ...thanx

if i get you right in my program i do not have to set values for the ccpr1l and ccp1con since im using push button switches and set the pic in pwm mode?

I think you got the idea after reading post #9.
You DO change the values in CCPR1L and CCP1CON, they are the registers holding the bits that decide the PWM ratio. What you have to do is adjust their values when one of your switches is pressed so the ratio of off to on is increased or decreased.

Example: If your clock frequency is 8MHz and the PWM frequency is chosen to be 1KHz, set TMR2 prescaler to 16,

PR2 = 0b01111100;
T2CON = 0b00000111;

For 1% duty cycle,
CCPR1L = 0b00000001;
CCP1CON = 0b00001100;

For 50% duty cycle,
CCPR1L = 0b00111110;
CCP1CON = 0b00011100;

For 90% duty cycle,
CCPR1L = 0b01110000;
CCP1CON = 0b00011100;

Those are binary values. Note that PR2 and T2CON only set the frequency so you don't need to change them again to set the duty cycle. As CCP1CON only holds the least significant bits of the PWM ratio, you might be able to ignore them too and only use CCPR1L to change the fan power. If you do that, beware of a catch - you need to change the CCP1CON to get exactly 0% and exactly 100% power as the least significant bits play a small but important part in reaching both ends of the range.


ive tried typing some code but when I put it inside the ic the fan doenst run accourding to the speed I'm not sure I'm I went right on the pwm code please check 4 m heres the code.

Code ASM - [expand]
;                       program starting
START           CLRF            PORTA
                MOVLW           0x07    
                MOVWF           CMCON
                BSF             STATUS,RP0      
                MOVLW           0xFF
                MOVWF           TRISA
                MOVLW           B'00000011'
                MOVWF           TRISB
                BCF             STATUS,RP0
;               SWITCHES TESTING
SW0             btfss           portB,RB0 
                GOTO            INCREASE
                GOTO            SW1
SW1             BTFSS           PORTB,RB1
                GOTO            DECREASE
                GOTO            SW0
INCREASE        BTFSS           PORTB,RA1
                GOTO            SW0
                INCF            32H,1
                CALL            PWM
                GOTO            SW0
DECREASE        DECF            32H,1
                CALL            PWM
                GOTO            SW0
;               DISPLAY
PWM             MOVLW           d'16'
                MOVWF           TMR2
                MOVLW           B'00000111'
                MOVWF           T2CON
                BSF             STATUS,RP0
                MOVLW           B'01111100'
                MOVWF           PR2
                BCF             STATUS,RP0
                MOVLW           B'00001100'
                MOVWF           CCP1CON
TESTS0          BTFSS           PORTB,RB0
                INCF            CCPR1L
                BTFSS           PORTB,RB1
                DECF            CCPR1L
DISPLAY         CALL            BCD
                GOTO            SHIFT
BCD             CLRF            33H
TEN             MOVLW           D'10'
                SUBWF           32H,0
                BTFSS           STATUS,C
                GOTO            SORT
                INCF            33H,1
                MOVWF           32H
                GOTO            TEN
SORT            SWAPF           33H,0
                IOR             32H,0
;   SHIFT REGISTER                      
SHIFT           MOVLW           D'8'
                MOVWF           34H
BIT_DATA        BTFSC           32H,7
                BSF             PORTB,5
                BTFSS           32H,7
                BCF             PORTB,5
CLOCK           BSF             PORTB,6
                BCF             PORTB,6
                RLF             32H,1
                DECFSZ          34H,1
                GOTO            BIT_DATA
                GOTO            SW0

Last edited by a moderator:

You are making the code difficult to read by not using labels for your variables. I'm not familar with microlabs assembler but almost everybody uses Microchips own assembler, in this case XC8 which is free to download and use. It isn't at all clear what you are storing at addresses 0x32, 0x33 and 0x34. What I can tell is it would be better to initialise the timer and PR2 in your 'start' section as they do not require changes later on.

SW0 and SW1 seem to test the condition of RB0 and RB1 so I assume those are your 'accelerate' and 'decelerate' switch inputs. what I can't understand is why you then test them again in 'TESTS0'.

After the label 'INCREASE' you probably mean to use 'PORTB,RB1', you used RA1 instead. It probably doesn't make any difference as the port bit names are almost certainly equated to the same constants anyway.

I can see you might have problems with switch contact bounce unless you are doing it in hardware outside the PIC.


Not open for further replies.

Part and Inventory Search

Welcome to