⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Real Time Operating System for Hi-Tech C compiler.
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* we get here through POR. All these things need be   */
    /*  initialized only once.                             */
    if ( !WokeFromSleep() ) {
    
        /* initialize port pin default values and modes.   */
        /*      GP0:          input    Rx data             */
        /*      GP1:          input    key up              */
        /*      GP2:          output   serial strobe       */
        /*      GP3:          input    key down            */
        /*      GP4:          output   PWM                 */
        /*      GP5:          output   Tx data             */
        PORT  = (GP0_NO_SERIAL_DATA)
              | (GP1_NO_SERIAL_CLK)
              | (GP2_NO_SERIAL_STB)
              | (GP3_NO_KEY_DOWN)  
              | (GP4_NO_PWM)
              | (GP5_RS232_IDLE);
              
              
        /* these variables are initialized only on power-  */
        /*  up and persist until the system loses power.   */
        /*      .dontSleep:   default is to sleep          */
        /*      speed:        start speed                  */
        sysStat.dontSleep =               0;
        speed             = FAN_START_SPEED;
        
        
        /* set non-default baud rate if selected.          */
        if ( !keyUP )
            oneBitDelay =  BAUD_KEY_UP;
        else if ( !keyDN )
            oneBitDelay = BAUD_KEY_DN;
        else
            oneBitDelay = BAUD_DEFAULT;
        

        /* initialize Salvo.                               */
        /* required because Salvo's vars are declared as   */
        /*  persistent.                                    */
        OSInit();
    
    
        /* create tasks. For those builds that use task    */
        /*  priorities (not really necessary here),        */
        /*  TaskBeep() must be lowest since it normally    */
        /*  only yields.                                   */
        OSCreateTask(TaskReadKeys, TASK_READ_KEYS_P, 1);
        OSCreateTask(TaskSpinFan,  TASK_SPIN_FAN_P,  2);
        OSCreateTask(TaskBeep,     TASK_BEEP_P,      3);        
    }
    
    
    /* these variables are (re-)initialized on power-up    */
    /*  and wake-up.                                       */
    /*      .beep:        no beeping required              */
    /*      .change:      force PWM & bargraph init        */
    /*      .onPWM:       PWM output is OFF                */
    /*      .xmitOK:      OK to transmit to remote         */
    /*      sleepTimer:   reset this counter               */
    sysStat.beep   =             0;
    sysStat.change =             1;    
    sysStat.onPWM  =             0;
    sysStat.napBit =             0;
    sysStat.xmitOK =             1;
    sleepTimer     = TIME_TO_SLEEP;
        

    /* reset Timer0 prior to entering main loop. This      */
    /*  clears the prescalar, too.                         */
    TMR0 = 0;


    /* the usual "infinite for() loop", with extra code to */
    /*  handle timer and sensing for sleep.                */
    for (;;) {
    
        /* if Timer0 has rolled over mark it so we can call*/
        /*  OSTimer. A temporary placeholder for Timer0 is */
        /*  required because it might change value between */
        /*  the first and second reads. This is the normal */
        /*  way the    system keeps track of time.         */
        tmpTMR0 = TMR0;
        if ( tmpTMR0 < oldTMR0 ) {
        
            /* call Salvo's Timer to process delayed tasks.*/
            OSTimer();
            
            /* time-to-sleep countdown timer runs at       */
            /*   system tick rate.                         */
            if ( sleepTimer )
                sleepTimer--;
        }
        oldTMR0 = tmpTMR0;            
        
        
        /* act on command, if present. Note that this has  */
        /*  no deleterious effect on the command that woke */
        /*  us up from sleep.                              */
        RcvCmd();
        
        
        /* if sleep timer times out, then there's been no  */
        /*  no user activity for a while, and it's safe    */
        /*  to shut things down. Wake up on pin change or  */
        /*  incoming RS-232 data.                          */
        /* GPIO pins are in the GPIO_NORMAL_CONFIG mode,   */
        /*  so no housekeeping is necessary.               */
        if ( !sleepTimer && !sysStat.dontSleep ) {
        
            /* turn off fan, bargraph and beeper. No need  */
            /*  to do anything else, since it will all     */
            /*  be reset on POR/wake-on-pin anyway.        */
            outPWM = PWM_OFF;
            OutBargraph(LEDs[0]);
                            
            /* reset woke-up flag.                         */
            ClrWakeFlag();
        
            /* dummy read for proper wake-on-change        */
            /*  operation.                                 */
            oldTMR0 = PORT;
                        
            /* sleepy time - will wake up on pin change.   */
            GoToSleep();
        }
        
        
        /* dispatch most eligible task.                    */        
        OSSched();
    }
}


/************************************************************
****                                                     ****
**                                                         **
TaskReadKeys()

Interprets user activity on the two pushbutton keys, and
does key-repeat without acceleration. External action from
RS-232 port is processed here by monitoring sysStat.change
periodically.

**                                                         **
****                                                     ****
************************************************************/
void TaskReadKeys ( void )
{    
    static persistent i; /* persistent to avoid init code  */
    char tickTockPattern; 
    
    
    /* intialize this once, when task first runs.          */
    i = NAP_TOCK_PERIOD;

    for (;;) {
        /* sample keys every 20ms.                         */
        OS_Delay(SAMPLE_PERIOD, TaskReadKeys1);
                
        /* keypress means user wants to wake system and/or */
        /*  change fan speed.                              */ 
        if ( !keyUP || !keyDN ) {
        
            /* wait the debounce period.                   */
            OS_Delay(DEBOUNCE_PERIOD, TaskReadKeys2);
            
            /* if keyUP is still pressed, then it's valid. */
            /* by not waiting for the key to be released,  */
            /*  we get key-repeat for free!                */
            if ( !keyUP ) {
            
                /* do keyUP stuff. force beep, etc. even   */
                /*  if speed doesn't change.               */
                sysStat.change = 1;                
                if ( speed != PWM_STEPS )
                    speed++;
            }
            
            /* repeat for keyDN.                           */
            else if ( !keyDN ) {
            
                sysStat.change = 1;
                if ( speed != 0 )
                    speed--; 
            }
        }
        
        
        /* time for some fun -- couldn't leave any free    */
        /*  ROM leftover, after all ...    do a two-bit    */
        /*   metronome  at 1Hz when the unit is napping.   */
        if (  !sysStat.dontSleep 
          && ( sleepTimer <= (TIME_TO_SLEEP - TIME_TO_NAP) ) ) {
          
              /* countdown timer of SAMPLE_PERIOD.         */
              if ( --i == 0 ) {
              
                  /* reset timer. Note the error in the    */
                  /*  nap tock period -- it's compounded   */
                  /*  by this multiplier.                  */
                  i = NAP_TOCK_PERIOD;
                  
                  /* tick or tock on bargraph.             */
                  sysStat.napBit ^= 1;
                  if ( sysStat.napBit )
                      tickTockPattern = TICK_PATTERN;
                  else
                      tickTockPattern = TOCK_PATTERN;    
                  OutBargraph(tickTockPattern);      
            }
        }
          
        
        /* make necessary changes if the user requested    */
        /*  a change in speed or if an external command    */
        /*  was received.                                  */
        if ( sysStat.change ) {    
                
            /* reset changed flag.                         */
            sysStat.change =             0;    

            /* reset sleep timer.                          */
            sleepTimer     = TIME_TO_SLEEP;
            
            /* request a beep.                             */
            sysStat.beep   =             1;
        
            /* show new speed on LED bargraph. Force       */
            /*  -MON/BEEP low to enable Rx data monitoring.*/    
            OutBargraph(LEDs[speed]);
            
            /* now send the speed out via RS-232.          */
            OutRS232(speed | '0');
        }
    }
}


/************************************************************
****                                                     ****
**                                                         **
TaskSpinFan()

Drives the fan at the current fan setting via a PWM.

**                                                         **
****                                                     ****
************************************************************/
void TaskSpinFan ( void )
{
    OStypeDelay delay;
    
    
    for (;;) {
        /* speed of 0 means fan is completely OFF. No PWM -*/
        /*  dc only. Revisit in one system tick.           */
        if ( speed == 0 ) {
            delay             =                ONE_TICK;
            outPWM            =                 PWM_OFF;
        }
        
        /* speed of PWM_STEPS means fan is completely ON.  */
        /*  No PWM - dc only. Revisit in one system tick.  */
        else if ( speed == PWM_STEPS ) {
            delay             =                 ONE_TICK;
            outPWM            =                   PWM_ON;
        }
        
        /* intermediate speeds (1 <= speed <= 7)           */
        /*  require PWM action.                            */
        else {
        
            /* If PWM output is OFF, we need to create the */
            /*  "ON pulse" whose length is directly propor-*/
            /*  tional to the fan speed.                   */
            if ( !sysStat.onPWM ) {
                delay         = PWM_EXTRA_PERIODS + speed;
                outPWM        =                    PWM_ON;    
                sysStat.onPWM =                         1;
            }
            
            /* If PWM output is ON, we need to finish the  */
            /*  PWM period with the output OFF.            */
            else {
                delay         =         PWM_STEPS - speed;
                outPWM        =                   PWM_OFF;    
                sysStat.onPWM =                         0;
            }
        }
        
        /* PWM port value has been set -- now delay either */
        /*  4ms (dc output) or PWM high- or low-cycle.     */
        OS_Delay(delay, TaskSpinFan1);
    }
}


/************************************************************
****                                                     ****
**                                                         **
TaskBeep()

Beep by outputting a 4kHz waveform to the beeper for a short
time:
      _    _    _    _    _    _    _ 
    _| |__| |__| |__| |__| |__| |__| |________________  etc.
    
Pulse width is ca. 125us. Checks for the need to beep 
every system tick, except when it's in the middle of
beeping. Yields to more important tasks.

NOTE: since no interrupts are used, semaphore management is
very simple ...

**                                                         **
****                                                     ****
************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -