Source Code File:"fanspeed.c"

//////////////////////////////////////////////
// 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();
    }
}

http://www.sourceboost.com

Copyright © 2006 SourceBoost Technologies