Site icon Microcontroller Based Projects

Controlling PWM Fan with PIC16F684

Controlling PWM Fan with PIC16F684 Featured Image

In this post I’d like to share a design of PWM Fan controller based on PIC16F684 MCU. For Arduino version click here. Previously I’ve designed similar circuits some of them more complex than this one. I recommend you to look at this post for additional information and ideas. I wanted to build a simplified version and eliminate additional external components as much as possible. By using PIC16F684 instead of PIC16F877A you’ll get a smaller circuit, only 14 pins and get rid of external oscillator because this micro controller has a 8 MHz internal oscillator. This circuit can be built on a small strip board inside a PC case. If your motherboard has only one connector for case fan but you need to control additional fans this circuit can be of use. The code wasn’t written from scratch but instead retargeted for current MCU from earlier post. The controlling scheme hasn’t changed much. It uses 12V power supply and PWM signal of 25KHZ generated by PIC to control fan speed. In order to simplify this design only 3 speed settings were defined for the fan. High, Medium and Low and can be selected by DIP switch. Switch is connected to PORTC of the micro controller.

Prototype was tested on DeepCool 140mm UF140 PWM Fan. I have recently built a new PC and purchased this fan. However current design should work on a variety of standard 4 – wire PWM fans. One important thing to remember is that fans have different min and max speeds so the code may need some tweaking to make it work correctly with other fan brands.I’ve used PICKit3 to program the controller. Learn how to connect it at this link.See next pages for more information.

LIST P=PIC16F684
include <P16f684.inc>

__CONFIG _CP_OFF & _WDT_OFF & _BOD_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _CPD_OFF
org 0x00
nop
goto start
org 0x10
start: bcf STATUS,RP0
bcf STATUS,RP1
CLRF T2CON
BSF T2CON,0x0
CLRF CCP1CON ;CCP module OFF
CLRF TMR2 ;Clear Timer2
;——————————————————-
bsf STATUS,RP0
bcf STATUS,RP1
bsf TRISC,0x00 ;Bits 0,1,2 are Inputs
bsf TRISC,0x01
bsf TRISC,0x02
clrf ANSEL ;All ports are Digital
bcf STATUS,RP0
movlw 0x07
movwf CMCON0 ;All ports are Digital
;——————————————————-
loop: MOVLW 0x30 ;Default is High Speed
btfss PORTC,0x00 ;High Fan Speed
MOVLW 0x30
btfss PORTC,0x01 ;Medium Fan Speed
MOVLW 0x15
btfss PORTC,0x02 ;Low Fan Speed
MOVLW 0x10
;——————————————————-
;MOVLW 0x20;0x03 ;0x30 – Duty 97%; 0x01 – Duty < 2%
;High – 0x30 Medium – 0x20 Low – 0x10
PWM: MOVWF CCPR1L ;Duty Cycle
CLRF INTCON ;Disable interrupts, clear T0IF
BSF STATUS,RP0 ;Bank1
MOVLW 0x30;0x09 ;PWM period is 10*4Tosc
MOVWF PR2
BCF TRISC,0x05 ;Make pin 5 Output
CLRF PIE1 ;Disable peripheral interrupts
BCF STATUS,RP0 ;Bank0
CLRF PIR1
MOVLW 0x0C ;PWM mode,2 LSB bits of Duty Cycle=10
MOVWF CCP1CON ;Duty Cycle=1010 =10Tosc
BSF T2CON,TMR2ON;Timer2 starts to increment
GOTO loop
end

On the next page you can get the code and see a short video.

Source code and a compiled HEX file can be downloaded here. Now let’s see how this circuit actually works.If you look closely you’ll notice that fan speed changes according to DIP switch position.The default speed setting is High. You can also connect a DVM at the PWM output of the microcontroller and verify that changing duty cycle causes the average voltage to vary from around 1.9 V to 5V.


Exit mobile version