/******************************************************************** Filename: subcontrol.c Created: Friday, August 12, 2005 Author(s): Daniel Clarke Purpose: Switches on or off a mono subwoofer amplifier using three relays for mains power, input selection and speaker selection. Power can be applied via push switch or a 12V trigger (selectable by a power mode slide switch). For more detials, see http://www.electro-dan.co.uk/subwoofer/construction6.html Copyrights(c) 2005 Daniel Clarke *********************************************************************/ /** \file \brief Contains main C function and interrupt vector. It contains the application's entry point (main) and the interrupt vector sector to handle PIC's hardware interrupts. Specific funtions related to the subtest3 application are contained in this file as well. */ #include #pragma CLOCK_FREQ 4000000 // Define device config block asm { list p=16F84A __config H'3F79' ;UNPROTECT&XT&WDTDIS&PWRTDIS&BORDIS&LVPDIS&DUNPROT&WRTEN&DEBUGDIS } // Global variables declaration short timer1_clone@0x0E; // For detecting input changes #define PWRSW 5 // Power Switch on Port B, pin 5 #define PWRMODE 4 // Power Mode Switch on Port B, pin 4 #define TRIG 2 // Power 12V Trigger on Port B, pin 2 char power = 0; // For detecting power on/off char powermode = 0; // For detecting the power mode (switch/trigger) char trigger = 0; // Trigger's current value char trigold = 0; // Trigger's old value /** \defgroup core_functions Application's Core Functions that form the basic structure of the application. */ void powerOn( void ) { // Switch main relay on set_bit(porta, 2); // Wait 3 seconds before connecting input and speaker // Loop flashes each LED in turn for 3 seconds... char n = 0; while (n < 15) { // Switch off STBY LED, switch on PWR LED clear_bit(porta, 0); set_bit(porta, 1); // Wait 100ms delay_ms(100); // Switch on STBY LED, switch off PWR LED set_bit(porta, 0); clear_bit(porta, 1); // Wait 100ms delay_ms(100); n++; } // Switch on speaker relay set_bit(portb, 0); // Wait 200ms, then switch input relay delay_ms(200); set_bit(porta, 3); // Switch off STBY LED, switch on PWR LED clear_bit(porta, 0); set_bit(porta, 1); } void powerOff( void ) { clear_bit(porta, 3); // Input disconnect delay_ms(200); clear_bit(portb, 0); // Speaker disconnect delay_ms(200); clear_bit(porta, 2); // Power removal // Switch on STBY LED, switch off PWR LED set_bit(porta, 0); clear_bit(porta, 1); } void checkPowerSw (void) { // If power switch is pressed (switch is on RB5) if (input_pin_port_b( PWRSW ) == 0) { // Wait, and then check again delay_ms(250); if (input_pin_port_b( PWRSW ) == 0) { // If switch is still pressed // Apply or Remove main power.. if (power == 1) { power = 0; powerOff(); } else { power = 1; powerOn(); } } } } void checkPowerMode (void) { // check pin 4 on port b has changed if (input_pin_port_b( PWRMODE ) == 0) // Change has occured powermode = 1; else // Switch 'off', wait 20ms powermode = 0; } void checkTrig (void) { // check pin 2 on port b has changed trigold = trigger; // Remember value before trigger = input_pin_port_b( TRIG ); // Read trigger value if (trigold != trigger) { // If new value is different from old, a change has occured if (trigger == 0) { // If trigger is on power = 1; // Power on powerOn(); } else { // Otherwise, power = 0; // Power off powerOff(); } } } /** \brief Executes only once as part of the program boot process. on_init is executed only once when the application has enter the main loop, usually after boot up initialization. This is a good place for hardware initialization code that usually needs to be executed only at the beginning of the program. It contains PIC's hardware initialization but user can also add any other type of initializations here. on_init will be called by the task scheduler. \sa on_timerx(), on_command(), on_idle() \ingroup core_functions */ void on_init( void ) { //TODO: add your initialization code option_reg = 0xFF; //i8_TasksCounter = 0; // IO ports setup trisa = 0x10; porta = 0x20; trisb = 0x34; portb = 0x00; // Turn on STBY LED set_bit(porta, 1); } /** \brief Runs user's code when there is no other task to run. on_idle is executed continously when there are no other tasks that need to be executed. Usually this is a good place to put code that has the lowest priority. on_idle will be called by the task scheduler. By default, it clears the watchdog timer to avoid micro reset itself. \sa on_timerx(), on_command(), on_init() \ingroup core_functions */ void on_idle( void ) { checkPowerMode(); // Check the power mode switch if (powermode == 0) // Check for change on RB5 (power switch), only if power is in mode 0 checkPowerSw(); else // Otherwise, check trigger status checkTrig(); delay_ms(20); } /** \brief This function is placed at the interrupt vector. interrupt is executed whenever a PIC's hardware interrupt has been triggered. The user can change, add, or remove the code in this function to fit the application's needs. interrupt is automatically called by the PIC's hardware. \sa main(), on_init() \ingroup core_functions */ void interrupt( void ) { // TODO: handle interrupts by adding code here // TODO: move code to fit your apps priorities // NB. No interrupts required! } /** \brief This is the entry point function for C programs. main is executed (by a goto instruction) after some required initialization has been executed. The PICC's compiler adds this initialization code to every C program. \sa interrupt(), on_init() \ingroup core_functions */ main() { // initialize peripherals and the application on_init(); for (;;) { // Run on_idle continously, there are no tasks to schedule on_idle(); } }