********************************************************************************************* * Switch-Debouncer IC Creates A Long-Period Timer * * Phill Leyva, Maxim Integrated Products, Sunnyvale, CA * * * * ==> Project Description <== * * Switch debouncer used as a long period external timer, allowing the microcontroller to reduce power * * * * consumption by entering a sleep mode. * * * * Total Elapsed Time = Count_T x Timer_period where * * Count_T = Number of external Timer periods * * Timer_period (s) = (63k x C1 x (-ln(1 - VT/VCC)) + 0.1s) * * VT = MAX6817 threshold voltage * * VCC = MAX6817 VCC voltage * * * * ICs utilized in project: * * Motorola MC68HC705J1A Microcontroller * * MAXIM MAX6817 ESD Protected CMOS Switch Debouncer * * Fairchild FDV303N N-Channel Digital FET * * * * ==> Program Description * * The Start section initializes the registers and I/O. The remaining code consists of the Main Program, the * * subroutines Input, Control, and Output, and interrupt subroutine IRQ_ISR. * * * * After power up, subroutine Input obtains current data from input Port A and stores it in the Input Data * * Table (IN_Port). Subroutine Control transfers this IN_Port data to the Output Data Table (OUT_Port), * * and accepts the user's control logic algorithm. Subroutine Output transfers the new output data * * (OUT_Port) to Output Port B. * * * * Finally, the Main Program calls the Interrupt subroutine (IRQ_ISR) when U1 has timed out for 1 period, * * and adds 1 to the counter. Count T specifies the number of timer periods before waking up the * * microcontroller. The Main program controls the flow of the program, and enters a low-power wait state * * when the input and output have been updated. * * * *********************************************************************************** * Register Equates * *********************************************************************************** PORTA equ $00 ; Port A byte address PORTB equ $01 ; Port B byte address DDRA equ $04 ; Port A Data Direction Register DDRB equ $05 ; Port B Data Direction Register TSCR equ $08 ; Timer Status and Control Register TCR equ $09 ; Timer-Counter Register ISCR equ $0A ; Interrupt Status and Control Register PDRA equ $10 ; Pull-Down Register Port A PDRB equ $11 ; Pull-Down Register Port B EPROG equ $18 ; EPROM Programming Control Register COPR equ $7F0 ; COP Reset Register MOR equ $7F1 ; Mask Option Register *********************************************************************************** * I/O Port Register Equates * *********************************************************************************** * Port A Data Register (PORTA Address = $00) PA0 equ 0 ; Port A bit 0, Input Bit PA1 equ 1 ; Port A bit 1, Input Bit PA2 equ 2 ; Port A bit 2, Input Bit PA3 equ 3 ; Port A bit 3, Input Bit PA4 equ 4 ; Port A bit 4, Input Bit PA5 equ 5 ; Port A bit 5, Input Bit PA6 equ 6 ; Port A bit 6, Input Bit PA7 equ 7 ; Port A bit 7, Input Bit * Port B Data Register (PORTB Address = $01) PB0 equ 0 ; Port B bit 0, Output Bit PB1 equ 1 ; Port B bit 1, Output Bit PB2 equ 2 ; Port B bit 2, Output Bit PB3 equ 3 ; Port B bit 3, Output Bit PB4 equ 4 ; Port B bit 4, Output Bit PB5 equ 5 ; Port B bit 5, Output Bit * Timer Status and Control Register (TSCR Address = $08) RT0 equ 0 ; Real-Time Interrupt Rate Select bit 0 RT1 equ 1 ; Real-Time Interrupt Rate Select bit 1 RTIFR equ 2 ; Real-Time Interrupt Flag Reset TOFR equ 3 ; Timer Overflow Flag Reset RTIE equ 4 ; Real-Time Interrupt Enable TOIE equ 5 ; Timer Overflow Interrupt Enable RTIF equ 6 ; Real-Time Interrupt Flag TOF equ 7 ; Timer Overflow Flag *********************************************************************************** * Memory Equates * *********************************************************************************** RAM equ $00C0 ; Start of on Chip Static RAM EPROM equ $0300 ; Start of on Chip ROM/EPROM Vectors equ $07F8 ; Start of Reset/Interrupt Vectors Timer_INT equ $07F8 ; Timer Vector IRQ_INT equ $07FA ; External Hardware Interrupt Vector SWI_INT equ $07FC ; Software Interrupt Vector RESET equ $07FE ; Reset Vector *********************************************************************************** * Program Equates * *********************************************************************************** Count_T equ $04 ; Number of external Timer periods desired ; Total elapsed time=Count_T x Timer_period *********************************************************************************** * RAM Variables * *********************************************************************************** org RAM ; Start of Static RAM address IN_Port rmb 1 ; Byte Wide, Input Data Table OUT_Port rmb 1 ; Byte Wide, Output Data Table Count rmb 1 ; External Timer pulse counter *********************************************************************************** * Program I/O Initialization * * Default for PORTA is as INPUT Port * * PortA Pins 7 6 5 4 3 2 1 0 * * Function In In In In In In In In * * Default for PORTB is as OUTPUT Port * * PortB Pins 5 4 3 2 1 0 * * Function Out Out Out Out Out Out * *********************************************************************************** org EPROM Start: sei ; Mask OFF Hardware Interrupt clra ; Clear Accumulator sta PORTA ; Blank data for registers sta DDRA ; Set Port A Byte Wide Inputs sta IN_Port ; Clear Input Data Table sta OUT_Port ; Clear Output Data Table sta Count ; Clear external timer counter sta PORTB ; Initialize Port B MCU-Latches lda #$FF ; sta DDRB ; Set Port B as Output Port lda #$0F ; sta TSCR ; Disable Timer Interrupts clrx ; Clear Index Registor clra ; Clear Accumulator sta COPR ; Reset Watchdog timer jsr Input ; Get initial Input Port A data jsr Control ; Manipulate Data Tables jsr Output ; Send out initial Output Port B data cli ; Mask ON Hardware Interrupts, enable ; external timer interrupts *********************************************************************************** * Main Program * *********************************************************************************** Main: wait ; Enter power saving mode until awaken by ; by timer (IRQ\) or system reset (RESET\) lda #Count_T ; Number of external Timer periods desired sbc Count ; Subtract (Count_T - Count) bls Next ; Test if accumulator is zero or negative jmp Main ; Counter not done Next: jsr Input ; Counter done, get new Input Port A data jsr Control ; Transfer data tables and other user tasks jsr Output ; Send out new Output Port B data jmp Main ; Do another loop through Main *********************************************************************************** * Input Port A Update Subroutine * *********************************************************************************** Input: lda PORTA ; Read new Input Port A data sta IN_Port ; Update Input Data Table rts ; Return from Subroutine *********************************************************************************** * Control Logic Update Subroutine * *********************************************************************************** Control: nop ; USER to remove "nop"s and insert CONTROL<<* nop ; LOGIC routine here <<********************** lda IN_Port ; Read new Input table data sta OUT_Port ; Update Output table rts ; Return from Subroutine *********************************************************************************** * Output Port B Update Subroutine * *********************************************************************************** Output: lda OUT_Port ; sta PORTB ; Send new data to Output Port B rts ; Return from Subroutine *********************************************************************************** * Interrupt Service Routine * * External Timer (MAX6817) has pulsed once * *********************************************************************************** IRQ_ISR: inc Count ; Add 1 to counter rti ; Done with Interrupt Routine ***************************************************************************** * Timer Interrupt Service Routine * ***************************************************************************** TIMER_ISR: nop ; Future User Timer Routine rti ; Done with Interrupt Routine ***************************************************************************** * Software Interrupt Service Routine * ***************************************************************************** SWI_ISR: nop ; Future User Sofware Routine rti ; Done with Interrupt Routine ***************************************************************************** * RESET and Interrupt Vectors * ***************************************************************************** org Vectors org Timer_INT fdb TIMER_ISR org IRQ_INT fdb IRQ_ISR org SWI_INT fdb SWI_ISR org RESET fdb Start ***************************************************************************** * MOR Vectors * ***************************************************************************** org MOR db $20 ; Set MOR Register Options, no Watchdog rti ; Done with Interrupt Routine ***************************************************************************** * Timer Interrupt Service Routine * ***************************************************************************** TIMER_ISR: nop ; Future User Timer Routine rti ; Done with Interrupt Routine ***************************************************************************** * Software Interrupt Service Routine * ***************************************************************************** SWI_ISR: nop ; Future User Sofware Routine rti ; Done with Interrupt Routine ***************************************************************************** * RESET and Interrupt Vectors * ***************************************************************************** org Vectors org Timer_INT fdb TIMER_ISR org IRQ_INT fdb IRQ_ISR org SWI_INT fdb SWI_ISR org RESET fdb Start ***************************************************************************** * MOR Vectors * ***************************************************************************** org MOR db $20 ; Set MOR Register Options, no Watchdog