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

📄 main.c

📁 Real Time Operating System for Hi-Tech C compiler.
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************ 
Copyright (C) 1995-2002 Pumpkin, Inc. and its
Licensor(s). Freely distributable.

$Source: C:\\RCS\\d\\salvo\\demo\\d3\\main.c,v $
$Author: aek $
$Revision: 3.2 $
$Date: 2002-04-24 11:49:51-07 $

Multitasking Salvo-based application using delay 
services but no event services due to the limited amount of
ROM and RAM in the host Microchip PIC12C509A PICmicro.

For use on Pumpkin's Salvo PIC12 Demo Board, assembly P/N 
710-00197.

See "AN-6 Multitasking PIC12C509A-based Remote Fan 
Controller" for more information. 

	v1.1	aek		updated to reflect v2.2 library scheme
    v1.2    aek     minor edits 
    v1.3    aek     v2.3 used less ROM, now all builds
                     have optional baud rates. 
	

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

#include "salvo.h"


/* detect which target we're compiling for.                */
#if defined (_12C509) || defined (_12C509A) || defined (_12CR509A)
#define USING_12C50X TRUE
#define BATTERY_OPERATION  TRUE
#if ((_HTC_VER_MAJOR_*1000 + \
      _HTC_VER_MINOR_*  10 + \
      _HTC_VER_PATCH_*   1) < 8000 )
__CONFIG(INTRC | UNPROTECT);
#else
__CONFIG(INTRC & UNPROTECT);
#endif
#else
#undef USING_12C50X
#define BATTERY_OPERATION  FALSE
#endif


/* port pin defs for different targets. Alternate target   */
/*  is PIC16C77 or equivalent.                             */
#ifdef USING_12C50X
#define PORT               GPIO
#define outDATA            GP0
#define inRX               GP0
#define outCLK             GP1
#define keyUP              GP1
#define outSTB             GP2
#define keyDN              GP3
#define outPWM             GP4
#define outTX              GP5
#define OPTION_CONFIG      0x03
#else
#define PORT               PORTB
#define TRIS               TRISB
#define outDATA            RB0
#define inRX               RB0
#define outCLK             RB1
#define keyUP              RB1
#define outSTB             RB2
#define keyDN              RB3
#define outPWM             RB4
#define outTX              RB5
#define OPTION_CONFIG      0x03
#endif


/* I/O port configurations for different modes.            */
#define GPIO_NORMAL_CONFIG  0x0B       /* normal operation */
#define GPIO_SERIAL_CONFIG  0x08       /* serial writes    */


/* I/O port default values.                                */
#define GP0_NO_SERIAL_DATA  0x00 
#define GP1_NO_SERIAL_CLK   0x00 
#define GP2_NO_SERIAL_STB   0x00 
#define GP3_NO_KEY_DOWN     0x08 
#define GP4_NO_PWM          0x10 
#define GP5_RS232_IDLE      0x20


/* Salvo task pointers.                                    */
#define TASK_READ_KEYS_P    OSTCBP(1)
#define TASK_SPIN_FAN_P     OSTCBP(2)
#define TASK_BEEP_P         OSTCBP(3)


/* delays based on system tick of 4.096ms. Times are       */
/*  approximate.                                           */
#define FOUR_MS             1
#define TWENTY_MS           5
#define FIFTY_MS            12
#define SEVENTY_FIVE_MS     18
#define HUNDRED_MS          24
#define HUNDRED_FIFTY_MS    36
#define ONE_S               244
#define TWENTY_S            4883
#define THIRTY_S            7324
#define ONE_MIN             14648
#define TWO_MIN             29297
#define ONE_TICK            FOUR_MS
#define TIME_TO_NAP         THIRTY_S
#define TIME_TO_SLEEP       TWO_MIN
#define SAMPLE_PERIOD       TWENTY_MS
#define DEBOUNCE_PERIOD     SEVENTY_FIVE_MS
#define MINIMUM_PERIOD      FOUR_MS
#define NAP_TOCK_PERIOD     ONE_S / SAMPLE_PERIOD


/* PWM output is active-low.                               */
#define PWM_ON              0
#define PWM_OFF             1


/* PWM steps and extra periods to ensure that fan spins at */
/*  all settings. Extra periods are determined empirically.*/
#define PWM_STEPS           8
#define PWM_EXTRA_PERIODS   2
#define PWM_PERIOD          PWM_STEPS + PWM_EXTRA_PERIODS


/* duration of pulse train to beeper.                      */
#define BEEP_PULSES         10        /* pulses            */


/* values for the serial data stream to be shifted through */
/*  U2 in order to disable or enable the beeper. Since each*/
/*  bit affects the beeper, it's imperative to use full-0's*/
/*  and full-1's as the patterns, as other patterns will   */
/*  result in non-50%-duty-cycle waveforms.                */
#define BEEPER_OFF          0x00
#define BEEPER_ON           0xFF


/* for OutShiftRegister()'s second argument -- either just */
/*  shift the data through U2, or shift and then latch it. */
#define SHIFT_ONLY          FALSE
#define SHIFT_AND_LATCH     TRUE


/* bit times in 1us instructions for RS-232 baud rates.    */
/*  Note that low baud rates will have an adverse effect on*/
/*  the PWM period when there's RS-232 activity, and high  */
/*  baud rates lead to poor command receiption due to the  */
/*  narrow sampling window. 2400 baud is default because   */
/*  it responds best to commands. 4800 is OK, 9600 barely  */
/*  works.                                                 */
#ifndef BAUD
#define BAUD                2400
#elif   BAUD < 1310               /* limit w/char delays   */
#error RS-232 baud rate too low.
#elif   BAUD > 19200
#error RS-232 baud rate too high.
#endif
#define DLY                 3     /* cycles per delay loop */
#define OHEAD               8     /* overhead in Tx and Rx */
#define XTAL                4000000
#define ONE_BIT             ((XTAL/4/BAUD)-(OHEAD))/DLY 
#define ONE_BIT_1200        ((XTAL/4/1200)-(OHEAD))/DLY
#define ONE_BIT_2400        ((XTAL/4/2400)-(OHEAD))/DLY
#define ONE_BIT_4800        ((XTAL/4/4800)-(OHEAD))/DLY    
#define ONE_BIT_9600        ((XTAL/4/9600)-(OHEAD))/DLY    
#define BAUD_DEFAULT        ONE_BIT            
#define BAUD_KEY_UP         ONE_BIT_9600            
#define BAUD_KEY_DN         ONE_BIT_4800           


/* software handshaking / flow control characters. Used to */
/*  indicate when we're ready to receive a command.        */        
#define XON                 17        /* Ctrl-Q            */
#define XOFF                19        /* Ctrl-S            */


/* return codes for InRS232                                */
#define NO_RX_CHAR          1         /* none detected     */
#define BAD_RX_CHAR         2         /* bad stop bit      */


/* bit patterns for bargraph LEDs when napping.            */
#define TICK_PATTERN        0x7F
#define TOCK_PATTERN        0xBF


/* speed of fan at POR start -- show some life.            */
#define FAN_START_SPEED     6


/* function-calling overhead on PIC12 is greater (by 2     */
/*  instructions) than in-lining delay functionality, so   */
/*  use this macro instead.    Downside is that a char     */
/*  variable declaration for delay must accompany it ...   */
/* with full optimizations, each loop iteration takes three*/
/*  cycles.                                                */
#define ShortDelay(a, b)     { b = a; while ( --b ) ; }        


/* sleep instruction. Don't sleep when debugging via ICE.  */
#define Sleep() asm("SLEEP");    
#if BATTERY_OPERATION
#define ClrWakeFlag()       { GPWUF = 0; }
#define GoToSleep()         { Sleep(); }
#define WokeFromSleep()     GPWUF 
#else
#define ClrWakeFlag()        
#define GoToSleep()         { SleepHere: goto SleepHere; }
#define WokeFromSleep()     0 
#endif


/* function prototypes.                                    */
char InRS232 ( void );
void OutBargraph ( char pattern );
void OutRS232 ( char byte );
void OutShiftRegister ( char byte, char useStrobe );
void RcvCmd ( void );
void TaskBeep ( void );
void TaskReadKeys ( void );
void TaskSpinFan ( void );


/* context-switching labels.                               */
_OSLabel(TaskBeep1)
_OSLabel(TaskReadKeys1)
_OSLabel(TaskReadKeys2)
_OSLabel(TaskSpinFan1)


/* global system status and sysStat byte.                  */
typedef struct {
  char beep      :1;        /* keypress beep required (sem)*/
  char change    :1;        /* speed changed (flag)        */
  char dontSleep :1;        /* suppress sleeping           */
  char onPWM     :1;        /* PWM out active, not dc      */
  char xmitOK    :1;        /* OK to transmit to remote    */
  char napBit    :1;        /* for nap display on bargraph */
} typeSysStat;
persistent typeSysStat sysStat;


/* fan speed, 0-8. Too expensive (ROM-wise) to have this   */
/*  nibble in sysStat.                                     */
persistent char speed;


/* system ticks counter. By declaring it persistent (OK,   */
/*  since we always reset it on startup) we're able to rid */
/*  ourselves of all the startup variable initialization   */
/*  code.                                                  */ 
persistent unsigned int sleepTimer;


/* baud-rate-specific delay counter. Used by ShortDelay(). */
persistent char oneBitDelay;


/* U2's output to drive bargraph display. D2 on REV A and  */
/*  REV B has odd pinout, hence the bit juggling.          */
const char LEDs[PWM_STEPS+1] = { 0xFF,      /* 0 / OFF     */
                                 0xEF,      /* 1           */
                                 0xCF,      /* 2           */
                                 0x8F,      /* 3           */
                                 0x0F,      /* 4           */
                                 0x07,      /* 5           */
                                 0x03,      /* 6           */
                                 0x01,      /* 7           */
                                 0x00 };    /* 8           */ 
                                       
                                       
/************************************************************
****                                                     ****
**                                                         **
main()

Typical Salvo main(), with extra code to accomodate 
differences between resets, OSTimer() and receipt of RS-232
in main loop due to lack of interrupts, and entering sleep.

**                                                         **
****                                                     ****
************************************************************/
void main ( void )
{
    unsigned char oldTMR0, tmpTMR0;


    /* Power-on reset (POR) and wake-up-from-sleep (WUF)   */
    /*  bring us here after startup code. No other resets  */
    /*  in use.                                            */
    
    /* setting TRIS and OPTION is always required.         */
    /* port outputs in normal configuration.               */
    /* Timer0 in timer mode at fosc/4 w/1:16 prescalar,    */
    /*  free-running. Rolls over every 256 * 16 = 4096     */
    /*  instruction cycles.                                */
    TRIS   = GPIO_NORMAL_CONFIG;
    OPTION = OPTION_CONFIG;

            
    /* wake-on-pin-change can be due to either a keypress  */
    /*  or RS-232 Rx activity. The Device Reset Timer (DRT)*/
    /*  period is around 300us for non-POR resets and      */
    /*  varies over operating conditions. This, coupled    */
    /*  with the number of instructions it takes to get    */
    /*  from reset to RcvCmd() actually sampling incoming  */
    /*  RS-232 Rx data, makes processing the command that  */
    /*  woke us up from sleep simply infeasible. Hence     */
    /*  there's nothing to do on wake-on-pin-change.       */ 
    
    

⌨️ 快捷键说明

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