////////////////////////////////////////////// // Fan Speed Controller // // Author(s): David Hobday // Date: 11 December 2006 // // Target Device: EZ-Controller Turbo (PIC18F2520 with booloader) // // Revision History: // V1.0 11/12/2006 - Initial Release // ////////////////////////////////////////////// // // This code controls the speed of a fan using pulse width modulation, // ie the fan speed is controlled by varying the duty cycle of voltage // waveform applied to the fan - all done without using any PWM hardware. // // The desired speed is set by typing a 1 to 3 digit number (0 to 255) on the // keypad and then pressing the '#' key. Pressing the '*' key switches // between the last two set speeds. // // This code uses Novo RTOS as it makes things so much simpler. // The PWM is implemented in software using Novo RTOS Sys_Sleep functions. // // The Keypad matrix is connected to PORTC (see keypad.c for details). // The pwm output is genrated from pin RB1. // // The Novo SysTimerUpdate() function is called in the main yield task, so any // time values used with waiting functions, such as Sys_Sleep(), represent the // number of times the run queue is transversed rather than an absolute time. // We use this technique to get a faster update of the software PWM signal. // The sleep queue is transversed every 10us on a PIC18 with 40MHz clock. // That gives a PWM signal period of 255 x 10us = 2.55ms // #include <system.h> #include <novocfg_pic18t3e5ts1.h> #include <novo.h> // use this configuration when not targeting EZ-COntroller turbo with bootloader, // also remember to remove linker option -rb 0x800 // #include "PicConfig.h" #pragma CLOCK_FREQ 40000000 #include "keypad.h" #define hTask0 0 #define hTask1 1 unsigned char speed = 50; // set initial speed // Delays are measured in run execution counts as we update SysTimerUpdate in the main yeild loop // In this application an update occurs around every 10us #define DEBOUNCE_DELAY_2500us() Sys_Sleep( 250 ) unsigned char WaitForKey() { unsigned char key = 0; unsigned char i; // wait for no key press and keypad stable for a number of loops for( i = 0; i < 10; i++ ) { if( ScanKeyMatrix() != 0xFF ) i = 0; DEBOUNCE_DELAY_2500us(); } // wait for key pressed and stable for a number of loops while( 1 ) { for( i = 0; i < 10; i++ ) { unsigned char k = ScanKeyMatrix(); if( key != k ) // key has changed the same { key = k; i = 0; } DEBOUNCE_DELAY_2500us(); // debounce delay } if( key != 0xFF ) // a key has been pressed return key; } } void Task0() { ScanKeyMatrixInit(); char key; unsigned char newSpeed = 0, oldSpeed = 0; while( 1 ) { key = WaitForKey(); if( key >= '0' && key <= '9' ) { newSpeed *= 10; newSpeed += key - '0'; } if( key == '#' ) { oldSpeed = speed; speed = newSpeed; newSpeed = 0; } if( key == '*' ) { newSpeed = speed; speed = oldSpeed; oldSpeed = newSpeed; newSpeed = 0; } } } void Task1() { while( 1 ) { portb.1 = 0; Sys_Sleep( 255 - speed ); portb.1 = 1; Sys_Sleep( speed ); } } void main() { SysInit(); SysCreateTask( hTask0, 2, Task0 ); SysCreateTask( hTask1, 2, Task1 ); SysStartTask( hTask0 ); SysStartTask( hTask1 ); trisb = 0x01; while( 1 ) { SysTimerUpdate(); Sys_Yield(); } }
Copyright © 2006 SourceBoost Technologies