1  /********************************************************************
  2    Filename:  subcontrol.c
  3    Created:  Friday, August 12, 2005
  4    Author(s):  Daniel Clarke
  5    Purpose:  Switches on or off a mono subwoofer amplifier using 
  6          three relays for mains power, input selection and
  7          speaker selection. Power can be applied via push 
  8          switch or a 12V trigger (selectable by a power mode
  9          slide switch). 
 10          
 11          For more detials, see 
 12          http://www.electro-dan.co.uk/subwoofer/construction6.aspx
 13  
 14    Copyrights(c) 2005 Daniel Clarke
 15  *********************************************************************/
 16  
 17  /** \file
 18    \brief Contains main C function and interrupt vector.
 19    
 20    It contains the application's entry point (main) and the interrupt
 21    vector sector to handle PIC's hardware interrupts. Specific funtions
 22    related to the subtest3 application are contained in
 23    this file as well.
 24  */
 25  #include <system.h>
 26  
 27  #pragma CLOCK_FREQ 4000000
 28  
 29  // Define device config block
 30  asm {
 31  list p=16F84A
 32  __config H'3F79' ;UNPROTECT&XT&WDTDIS&PWRTDIS&BORDIS&LVPDIS&DUNPROT&WRTEN&DEBUGDIS
 33  }
 34  
 35  // Global variables declaration
 36  short  timer1_clone@0x0E;
 37  
 38  // For detecting input changes
 39  #define PWRSW 5 // Power Switch on Port B, pin 5
 40  #define PWRMODE 4 // Power Mode Switch on Port B, pin 4
 41  #define TRIG 2 // Power 12V Trigger on Port B, pin 2
 42  
 43  char power = 0; // For detecting power on/off
 44  char powermode = 0; // For detecting the power mode (switch/trigger)
 45  char trigger = 0; // Trigger's current value
 46  char trigold = 0; // Trigger's old value
 47  
 48  /** \defgroup core_functions Application's Core
 49  
 50    Functions that form the basic structure of the application.
 51  */
 52  
 53  void powerOn( void ) {
 54    // Switch main relay on
 55    set_bit(porta, 2);
 56    // Wait 3 seconds before connecting input and speaker
 57    // Loop flashes each LED in turn for 3 seconds...
 58    char n = 0;
 59    while (n < 15) {
 60      // Switch off STBY LED, switch on PWR LED
 61      clear_bit(porta, 0);
 62      set_bit(porta, 1);
 63      // Wait 100ms 
 64      delay_ms(100);
 65      // Switch on STBY LED, switch off PWR LED
 66      set_bit(porta, 0);
 67      clear_bit(porta, 1);
 68      // Wait 100ms
 69      delay_ms(100);
 70      n++;
 71    }
 72    // Switch on speaker relay
 73    set_bit(portb, 0);
 74    // Wait 200ms, then switch input relay
 75    delay_ms(200);
 76    set_bit(porta, 3);
 77    // Switch off STBY LED, switch on PWR LED
 78    clear_bit(porta, 0);
 79    set_bit(porta, 1);
 80  }
 81  
 82  void powerOff( void ) {
 83    clear_bit(porta, 3); // Input disconnect
 84    delay_ms(200);
 85    clear_bit(portb, 0); // Speaker disconnect
 86    delay_ms(200);
 87    clear_bit(porta, 2); // Power removal
 88    // Switch on STBY LED, switch off PWR LED
 89    set_bit(porta, 0);
 90    clear_bit(porta, 1);
 91  }
 92  
 93  void checkPowerSw (void) {
 94    // If power switch is pressed (switch is on RB5)
 95    if (input_pin_port_b( PWRSW ) == 0) {
 96      // Wait, and then check again
 97      delay_ms(250);
 98      if (input_pin_port_b( PWRSW ) == 0) { // If switch is still pressed
 99        // Apply or Remove main power..
100        if (power == 1) {
101          power = 0;
102          powerOff();
103        }
104        else {
105          power = 1;
106          powerOn();
107        }
108      }
109    }
110  }
111  
112  void checkPowerMode (void) {
113      // check pin 4 on port b has changed
114      if (input_pin_port_b( PWRMODE ) == 0) // Change has occured
115      powermode = 1;
116    else // Switch 'off', wait 20ms
117      powermode = 0;
118  }
119  
120  void checkTrig (void) {
121      // check pin 2 on port b has changed
122      trigold = trigger; // Remember value before
123      trigger = input_pin_port_b( TRIG ); // Read trigger value
124      if (trigold != trigger) { // If new value is different from old, a change has occured
125      if (trigger == 0) { // If trigger is on
126        power = 1; // Power on
127        powerOn();
128      }
129      else { // Otherwise,
130        power = 0; // Power off
131        powerOff();
132      }
133    }
134  }
135  
136  /** \brief Executes only once as part of the program boot process.
137  
138    on_init is executed only once when the application has
139    enter the main loop, usually after boot up initialization.
140    This is a good place for hardware initialization code that usually
141    needs to be executed only at the beginning of the program. It contains
142    PIC's hardware initialization but user can also add any other type of
143    initializations here.
144    on_init will be called by the task scheduler.
145    \sa on_timerx(), on_command(), on_idle()
146    \ingroup core_functions
147  */
148  void on_init( void ) {
149    //TODO: add your initialization code
150    option_reg = 0xFF;
151    //i8_TasksCounter = 0;
152    // IO ports setup
153    trisa = 0x10;
154    porta = 0x20;
155    trisb = 0x34;
156    portb = 0x00;
157    // Turn on STBY LED
158    set_bit(porta, 1);
159  }
160  
161  
162  /** \brief Runs user's code when there is no other task to run.
163  
164    on_idle is executed continously when there are no other tasks
165    that need to be executed. Usually this is a good place to put
166    code that has the lowest priority. on_idle will be called by
167    the task scheduler. By default, it clears the watchdog timer
168    to avoid micro reset itself.
169    \sa on_timerx(), on_command(), on_init()
170    \ingroup core_functions
171  */
172  void on_idle( void ) {
173    checkPowerMode(); // Check the power mode switch
174    if (powermode == 0) // Check for change on RB5 (power switch), only if power is in mode 0
175      checkPowerSw();
176    else // Otherwise, check trigger status
177      checkTrig();
178    delay_ms(20);
179  }
180  
181  /** \brief This function is placed at the interrupt vector.
182  
183    interrupt is executed whenever a PIC's hardware interrupt has
184    been triggered. The user can change, add, or remove the
185    code in this function to fit the application's needs.
186    interrupt is automatically called by the PIC's hardware.
187    \sa main(), on_init()
188    \ingroup core_functions
189  */
190  void interrupt( void ) {
191    // TODO: handle interrupts by adding code here
192    // TODO: move code to fit your apps priorities
193    // NB. No interrupts required!
194  }
195  
196  /** \brief This is the entry point function for C programs.
197  
198    main is executed (by a goto instruction) after some required
199    initialization has been executed. The PICC's compiler adds this
200    initialization code to every C program.
201    \sa interrupt(), on_init()
202    \ingroup core_functions
203  */
204  main() {
205    // initialize peripherals and the application
206    on_init();
207    for (;;) {
208      // Run on_idle continously, there are no tasks to schedule
209      on_idle();
210    }
211  }


Generated by Java2HTML from C code here