;************************************************************************************ ;Software License Agreement ; ;The software supplied herewith by Erlich Industrial Development, Corp. EID, Corp. ;(the "Company") is intended and supplied to you, the Company’s customer, for use ;solely and exclusively on EID micro-base Kits and interface board products line. ;The software is owned by the Company and/or its supplier, and is protected under ;applicable copyright laws. All rights are reserved. Any use in violation of the ;foregoing restrictions may subject the user to criminal sanctions under applicable ;laws, as well as to civil liability for the breach of the terms and conditions of ;this license. ; ;THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, WHETHER EXPRESS, ;IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF ;MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. ;THE COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR ;CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. ;************************************************************************************ ;Filename: sequencer_S4.asm ;Author: Dr. Ron Erlich & Keith Youngblood ;Date: 2008-06-03 ;Version: 3.0.0 ;Description: This program allows one to run a multi-speed sequence ; on four digital outputs (dispaly via 4 LEDs). It uses interrupts ; and the speed is adjustable with a trim pot. (ADC) ; ; First, the last ADC reading (ADC_REGISTER) is stored in ; SYS_COUNT. Then, on each timer0 rollover/interrupt SYS_COUNT ; is decremented. When SYS_COUNT reaches zero, the ADD_MIN_TIME ; bit of the FLAGS register is set and SYS_COUNT is loaded with ; the MIN_DELAY_CNT value SYS_COUNT is then decremented again ; until it reaches zero when the state is incremented to the ; next and the last ADC reading is again loaded into SYS_COUNT ; and the ADD_MIN_TIME is cleared. This process repeats ; forever. The speed can be adjusted by changing the timer0 ; prescaler. ; ; Timing range is from approximately: ; MIN_DELAY_MS to ; (1uS * 256 * ADCMAX * timer0_prescale_factor) + MIN_DELAY_MS ; ;************************************************************************************* ; Revision History ; 2008-09-08 - v3.0.0 -- Initial release ;************************************************************************************* list p=12F675 ; list directive to define processor #include ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See data sheet for additional information on configuration word settings. ;************************************************************************************* ; Defines ;************************************************************************************* #define VERSION '3.0.0' #define BANK1 banksel 0x80 ; Select Bank1 #define BANK0 banksel 0x00 ; Select Bank0 #define LED_TRIS b'11011000' ; TRIS bit mask for I/O (0 = output) ; Define bit patterns for the cycled states #define LED_1_ON b'00011111' ; These LED's are active low #define LED_2_ON b'00111101' ; Different bit patterns may appear here #define LED_3_ON b'00111110' ; as necessaryfor the sequencing task at hand #define LED_4_ON b'00111011' ; #define ANSelect b'00011000' ; Used to configure AD ; x------- ; Not implemented ; -001---- ; ADCS<2:0> -- FOSC/8 ; ----1000 ; ANS3:ANS0 -- AN3 = analog #define ADControl b'00001101' ; Used to configure AD ; 0------- ; ADFM -- Left justified ; -0------ ; VCFG -- Vref = VDD ; --xx---- ; Not implemented ; ----11-- ; CHS1:CHS0 -- ADC Channel 3 selected ; ------0- ; GO /DONE -- Not in progress ; -------1 ; ADON -- Turn on ADC ; When the time adjustment potentiometer is all the way up ; (fastest sequence transitions), this time delay is used to limit how fast ; the transistions occur #define MIN_DELAY_MS d'8' ; Minimum delay time for sequence ; in milliseconds ; Approximate calculation of timer counts to complete MIN_DELAY_MS #define MIN_DELAY_CNT MIN_DELAY_MS/8 ;************************************************************************************* ; General Purpose Registers (GPR's) ;************************************************************************************* CBLOCK 0x20 WTEMP :1 ; register used in Interrupt Routine STATUS_TEMP :1 ; register used in Interrupt Routine PCLATH_TEMP :1 ; register used in Interrupt Routine FSR_TEMP :1 ; register used in Interrupt Routine FLAGS :1 ; register used to set flags ; Currently, only bit 0 is used ; Bit 0 -- ADD_MIN_TIME This flag is used ; to signal that the current ; countdown is for the minimum time timeout WHICH_LED :1 ; Holds the current state of the main ; state machine ADC_REGISTER:1 ; Holds the last read value from the ADC SYS_COUNT :1 ; 8 bit system countdown register. ; This is used to provide long delays ENDC ;************************************************************************************* ; Reset Vector ;************************************************************************************* ORG 0x000 ; processor reset vector nop ; Inserted For ICD2 Use goto Init ; go to beginning of program ;************************************************************************************* ; Interrupt Vector - Interrupts only active during animation sequence ; - Interrupt Sources: 1. TIMER0 Overflow ; ; FLAGS register - bit0: 1 = A/D will be serviced, 0 = Display will be serviced ; ;************************************************************************************* ORG 0x004 ; interrupt vector location Isr movwf WTEMP ; Save off current W register contents movf STATUS,w clrf STATUS ; Force to page0 movwf STATUS_TEMP movf PCLATH,w movwf PCLATH_TEMP ; Save PCLATH movf FSR,w movwf FSR_TEMP ; Save FSR BANK1 ; BANK1 ;************************************************************************************* ; Interrupt Source Checks ;************************************************************************************* Timer0InterruptCheck movf INTCON,w andlw 0x20 btfsc STATUS,Z ; Is T0IE Set? goto EndIsr ; No movf INTCON,w ; Yes andlw 0x04 btfss STATUS,Z ; Is TOIF Set? goto Timer0Interrupt ; Yes goto EndIsr ; No Timer0Interrupt ; Interrupt every 8192 uS call AD_Functions ; Yes, service A/D decf SYS_COUNT,f ; Decrement main counter btfss STATUS,Z ; Is it zero yet? goto Tmr0Done ; Not zero, we're done here ; Yes, determine if we are in main ; or min count btfsc FLAGS,0 ; ADD_MIN_TIME flag (Bit 2) set? goto HandleMainTimer ; no, this must be main timeout ; comes here if done with main count, then sets the min timeout movlw MIN_DELAY_CNT ; Get Min delay count value movwf SYS_COUNT ; Store it in the system count bsf FLAGS,0 ; Set flag for min delay count goto Tmr0Done ; We're done here HandleMainTimer incf WHICH_LED,f ; Delay done, go to the next LED state bcf FLAGS,0 ; Clear the ADD_MIN_TIME flag negf ADC_REGISTER, f ; Flip register value incf ADC_REGISTER, f ; Two's complement ; (ADC_REGISTER = 256 - value) movf ADC_REGISTER,w ; Get last ADC reading movwf SYS_COUNT ; and put it in for the next delay count btfsc STATUS,Z ; Is it zero? a Zero count acts like ; 256 (i.e. long delay) incf SYS_COUNT,f ; If zero, increment to one for short delay Tmr0Done BANK1 ; BANK1 bcf INTCON,T0IF ; Clear TMR0 Interrupt Flag ; All done, restore system variables and return from interrupt EndIsr clrf STATUS ; Select Bank0 movf FSR_TEMP,w movwf FSR ; Restore FSR movf PCLATH_TEMP,w movwf PCLATH ; Restore PCLATH movf STATUS_TEMP,w movwf STATUS ; Restore STATUS swapf WTEMP,f swapf WTEMP,w ; Restore W without corrupting STATUS bits retfie ; Return from interrupt ;************************************************************************************* ; AD_Functions ;************************************************************************************* AD_Functions BANK0 ; BANK0 movf ADRESH,W ; Move the most significant byte of A/D ; Result to W movwf ADC_REGISTER ; The A/D result is moved to LEDREGISTER ; and will be displayed bsf ADCON0,GO ; Start A/D return ;************************************************************************************* ; Initialization ;************************************************************************************* Init call 0x3FF ; retrieve factory calibration value ; comment instruction if using simulator, ; ICD2, or ICE2000 BANK1 movwf OSCCAL ; update register with factory cal value movlw LED_TRIS movwf TRISIO ; Tri-State set to LED_TRIS value BANK0 ; BANK 0 clrf GPIO ; Clear Port BANK1 ; BANK 1 clrf VRCON ; Vref Off BANK0 ; BANK 0 clrf TMR0 movlw 0x07 movwf CMCON ; Comparator Off BANK1 ; BANK 1 movlw b'10000100' movwf OPTION_REG ; TIMER0 Prescaler = 32 and pull-ups disabled bsf INTCON,T0IE ; Interrupt on TIMER0 Overflow Enabled bcf INTCON,T0IF ; Clear TIMER0 Overflow Interrupt Flag bsf INTCON,GIE ; Turn on Global Interrupts movlw ANSelect movwf ANSEL ; Configure AN0 & prescale to A/D BANK0 ; BANK 0 movlw ADControl movwf ADCON0 ; Select AN0, Left justified & enables A/D NOP NOP NOP NOP ; Give 4 uS delay before starting A/D bsf ADCON0,GO ; Start A/D bcf FLAGS,0 ; Clear the ADD_MIN_TIME flag movlw 1 ; Start with a very low value for first cycle, ; ADC used in next count movwf SYS_COUNT ; and put it in for the next delay count clrf WHICH_LED ; Start with LED 1 ;************************************************************************************* ; MAIN - Main Routine ;************************************************************************************* Main State_Machine ;clrwdt ; clear Watch Dog Timer movf WHICH_LED, w ; Mask out the high order bits of andlw B'00000011' ; WHICH_LED addwf PCL, f ; The program clock (PCL) is incre- goto State0 ; mented by STATE_LED in order goto State1 ; to go to the appropiate routine goto State2 goto State3 State0 ; Turns on LED 1 bcf STATUS, RP0 ; Bank 0 movlw LED_1_ON ; move predefined value to GPIO movwf GPIO goto State_Machine ; go back to state machine jump table State1 ; Turns on LED 2 bcf STATUS, RP0 ; Bank 0 movlw LED_2_ON ; move predefined value to GPIO movwf GPIO goto State_Machine ; go back to state machine jump table State2 ; Turns on LED 3 bcf STATUS, RP0 ; Bank 0 movlw LED_3_ON ; move predefined value to GPIO movwf GPIO goto State_Machine ; go back to state machine jump table State3 ; Turns on LED 4 bcf STATUS, RP0 ; Bank 0 movlw LED_4_ON ; move predefined value to GPIO movwf GPIO goto State_Machine ; go back to state machine jump table org 0x330 ; Write data to memory address 330 HEX dt "ELECTRONIC SEQUENCER PIC 12F675 BY DR R. ERLICH c/o EID CORP. & " dt "BY KEITH YOUNGBLOOD c/o YB TECH. AUG. 2008 " dt "THIS SOFTWARE IS PROVIDED ON AN AS IS CONDITION. " ; "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" ; ==================================================================================== ; ==================================================================================== ; End of program ; ==================================================================================== ; ==================================================================================== end ; Required directive