; // ------------------------------------------------------------- // ; // PIC16F628 based controller for 4 channel amplifier. // ; // Alarm and control inputs. Amplifier power control and speaker // ; // protection relay control. Temperature comparator. // ; // // ; // Copyright 2004, Peter Wolkensdorfer // ; // ------------------------------------------------------------- // list p=16f628 #include p16f628.inc ; // -- Device configuration bits --- __CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _LVP_OFF & _MCLRE_OFF ; // ---------- Variables ----------- temp_WREG equ 0x20 temp_STATUS equ 0x21 temp_PCLATH equ 0x22 temp_FSR equ 0x24 FLAGS equ 0x25 ; // Status bits RemoteKey equ 0x26 ; // Keypress counter Countdown equ 0x27 ; // Counter for timer IT CMP_FLAGS equ 0x28 ; // Comparator flags LoopCount equ 0x29 ; // Loop variable ; // ------ Other status flags ------ AMP_STATE equ 0 ; // FLAGS.0 SWITFLAG equ 1 ; // FLAGS.1 TICK equ 2 ; // FLAGS.2 ; // ----- Port pin definitions ----- SPEAKERS equ 4 ; // PORTA.4 (open collector output) OK_SIGNAL equ 5 ; // PORTA.5 (input) FAULT equ 0 ; // PORTB.0 (output) SO_COOL equ 1 ; // PORTB.1 (output) SOFTSTART equ 2 ; // PORTB.2 (output) AMP_POWER equ 3 ; // PORTB.3 (output) HOT equ 4 ; // PORTB.4 (output) VENT equ 5 ; // PORTB.5 (output) BACKLIGHT equ 6 ; // PORTB.6 (output) MUTE equ 7 ; // PORTB.7 (input) REMOTE equ 7 ; // PORTA.7 (input) org 0x0000 ; // --------- RESET vector --------- CLRF PCLATH GOTO main org 0x0004 ; // ------- Interrupt vector ------- MOVWF temp_WREG ; // Goes to 0x20 or 0xA0 SWAPF STATUS,W ; // Get STATUS BCF STATUS,RP0 ; // Switch to bank 0 MOVWF temp_STATUS ; // Save STATUS MOVF PCLATH, W ; // Get PCLATH MOVWF temp_PCLATH ; // Save PCLATH CLRF PCLATH ; // Clear PCLATH MOVF FSR,W ; // Get FSR MOVWF temp_FSR ; // Save FSR CLRWDT ; // Clear watchdog timer BCF INTCON,T0IF ; // Clear timer IT flag BTFSC FLAGS,AMP_STATE ; // Check if amplifier is off GOTO count_down ; // No, it is on BTFSS Countdown,0 ; // Run backlight at half power BCF PORTB,BACKLIGHT BTFSC Countdown,0 BSF PORTB,BACKLIGHT count_down DECF Countdown ; // Count ITs BTFSS STATUS,Z ; // Countdown expired? GOTO restore_context ; // No MOVLW 102 ; // Count 102 ITs to provide a 10 Hz MOVWF Countdown ; // signal BSF FLAGS,TICK ; // Set tick flag restore_context MOVF temp_PCLATH,W ; // Restore context MOVWF PCLATH MOVF temp_FSR,W MOVWF FSR SWAPF temp_STATUS,W MOVWF STATUS SWAPF temp_WREG SWAPF temp_WREG,W RETFIE Delay100ms MOVLW 102 ; // ---- Provide 100 msec delay ---- MOVWF Countdown ; // Restart timer for 100 ms BCF FLAGS,TICK ; // Clear tick flag delay1 BTFSS FLAGS,TICK ; // Check if expired GOTO delay1 ; // No RETURN main BCF STATUS,RP0 ; // ---------- Main loop ----------- CLRF FLAGS ; // All flags cleared MOVLW 0xAF ; // Set TRIS and PORT defaults ... BSF STATUS,RP0 ; // ...for PORTA MOVWF TRISA ; // Only bit4 is output BCF STATUS,RP0 ; // Bit6 is set to output (not used) MOVLW 0x10 ; // Bit4 is inverted MOVWF PORTA MOVLW 0x80 BSF STATUS,RP0 ; // ... for PORTB MOVWF TRISB ; // Only bit7 is input BCF STATUS,RP0 CLRF PORTB MOVLW 0xC1 ; // Set configuration BSF STATUS,RP0 MOVWF OPTION_REG ; // Timer0 uses internal clock, with ; // 1:4 prescaler. This provides a ; // 0.976 kHz timer interrupt which ; // means 1 IT per 1024 instructions MOVLW 4 BCF STATUS,RP0 MOVWF CMCON ; // Config 2 independent comparators MOVLW 0xA0 MOVWF INTCON ; // Enable Timer0 IT, but no other BSF PORTB,BACKLIGHT ; // Turn on power key backlight MOVF CMCON ; // Clear status change flags BCF PIR1,CMIF main_loop BCF STATUS,RP0 ; // ------ Main amp control loop ----- BTFSS PORTB,FAULT ; // Check if trouble flag set GOTO no_trouble ; // No problem so far BCF PORTB,BACKLIGHT ; // Short backlight blinks if trouble CALL Delay100ms ; // Trouble cannot be cleared without CALL Delay100ms ; // powering down the amplifier CALL Delay100ms ; // completely. BSF PORTB,BACKLIGHT CALL Delay100ms GOTO main_loop no_trouble BTFSS PORTA,REMOTE ; // Check if power key or remote CALL remote_onoff ; // Yes BTFSC PORTA,REMOTE ; // No keypress CLRF RemoteKey ; // Clear keypress counter BTFSS FLAGS,AMP_STATE ; // Check current state GOTO main_loop ; // Do nothing else if power down check_fault BTFSS PORTA,OK_SIGNAL ; // Check if fault occurred GOTO temp_ctrl ; // No, running fine BSF PORTB,FAULT ; // Set trouble flag GOTO remote_off ; // Shut down immediately temp_ctrl BTFSC CMCON,6 ; // Check comparator #1 GOTO getting_warm ; // Hot state first stage reached BCF PORTB,VENT ; // Shut down cooling NOP BCF PORTB,HOT ; // Turn on hot state LED NOP BSF PORTB,SO_COOL ; // Running fine GOTO check_mute ; // Check if mute command received getting_warm BSF PORTB,VENT ; // Turn on cooling NOP BSF PORTB,HOT ; // Indicate hot state BTFSS CMCON,7 ; // Check comparator #2 GOTO check_mute ; // Not really hot BCF PORTB,SO_COOL ; // Turn off power LED BSF PORTA,SPEAKERS ; // Turn off speakers GOTO temp_ctrl ; // Wait for cooling down check_mute BTFSC PORTB,MUTE ; // Check if mute signal required BSF PORTA,SPEAKERS ; // If so, turn off speakers BTFSS PORTB,MUTE ; // Muting not required BCF PORTA,SPEAKERS ; // Turn on speakers GOTO main_loop ; // Restart cycle ; // ---- Turn amplifier on or off ---- ; // Note: This version does not use ; // the softstart feature remote_onoff BTFSS FLAGS,TICK ; // Synchronize to 100ms loop RETURN BCF FLAGS,TICK ; // Clear 10 Hz flag MOVF RemoteKey,W ; // Check keypress length SUBLW 4 ; // 3-400 ms length required BTFSC STATUS,Z ; // Keypress is long enough GOTO long_key ; // Yes INCF RemoteKey ; // Count keypress BCF RemoteKey,7 ; // Inhibit counter overflow RETURN long_key INCF RemoteKey ; // Avoid immediate off after on BTFSS FLAGS,AMP_STATE ; // Check if amplifier is on GOTO remote_on ; // No, keypress means turn on remote_off BSF PORTA,SPEAKERS ; // Turn off loudspeakers CALL Delay100ms ; // Wait a little BCF PORTB,AMP_POWER ; // Turn off power CALL Delay100ms ; // Wait BCF PORTB,SOFTSTART ; // Release softstart short relay NOP BCF PORTB,SO_COOL ; // Indicate power off BCF FLAGS,AMP_STATE ; // Set state flag RETURN remote_on BSF PORTB,SO_COOL ; // Indicate power on NOP BSF PORTB,SOFTSTART ; // Close softstart short relay CALL Delay100ms ; // Wait BSF PORTB,AMP_POWER ; // Turn on power MOVLW 50 MOVWF LoopCount ; // 5 seconds delay for stabilization spk_on_loop BTFSS PORTA,OK_SIGNAL ; // Check if fault is signalled GOTO safe_turn_on ; // Fault signal cleared CALL Delay100ms ; // Wait for a little MOVF LoopCount,W ; // Get counter ANDLW 1 ; // Create 200 ms clock to blink BTFSC STATUS,Z ; // during fault signal BCF PORTB,SO_COOL ; // Blink off BTFSS STATUS,Z BSF PORTB,SO_COOL ; // Blink on DECFSZ LoopCount ; // Check if delay expired GOTO spk_on_loop ; // No, next cycle BSF PORTB,FAULT ; // Set fault output GOTO remote_off ; // Turn off amplifier safe_turn_on BSF PORTB,SO_COOL ; // Turn on power LED NOP BCF PORTA,SPEAKERS ; // Turn on speakers BSF FLAGS,AMP_STATE ; // Set state flag RETURN end