REGISTRUOTIS »
; Quick Chrono v1.7 ; Copyright Romas Pumpalavičius www.sprendimai.com 2007 ;; CONFIGURE processor 16f84a include <p16f84a.inc> __config _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_ON; SET PROGRAM VECTORS org 0x00 ; Reset vector goto Initialization org 0x04 ; Interrupt vector goto Interrupts; INITIALIZATIONInitialization; Initialization of ports movlw B'00000000' ; PortA -> output tris PORTA clrf PORTA ; Clear PortA (turn off display) movlw B'00000001' ; PortB -> Pin0 - input, Pin1-Pin7 - output tris PORTB; Set up variablesChar1 equ 0x0C ; 7 segment indicator character 1Char2 equ 0x0D ; 7 segment indicator character 2Char3 equ 0x0E ; 7 segment indicator character 3TimerH equ 0x0F ; Timer high byteTimeEL equ 0x10 ; Time Elapsed low byteTimeEH equ 0x11 ; Time Elapsed high byteFlags equ 0x12 ; Program flags: ; bit0=1 -> needs calculation of speed ; bit1=1 -> impossible to subtract fully clrf Flags ; Initial clear flagsIntW equ 0x13 ; Temporary interrupt variable for WIntSTATUS equ 0x14 ; Temporary interrupt variable for STATUSIntOPTION equ 0x15 ; Temporary interrupt variable for OPTIONIntBANK equ 0x16 ; Temporary interrupt variable for BANKSensDistH equ 0x17 ; Distance between sensors milimeters * 1000 (for 4MHz clock) higher byteSensDistL equ 0x18 ; Distance between sensors milimeters * 1000 (for 4MHz clock) lower byte movlw 0xC3 ; Set up 50000 for distance bytes movwf SensDistH movlw 0x50 movwf SensDistLCalcDistH equ 0x19 ; Calculation distance variable higher byteCalcDistL equ 0x1A ; Calculation distance variable lower byteContrast equ 0x1B ; Starting pause low byte; Test sensors goto Test_sensors; Start normal program flowStart_normal; Initialization of interrupts bsf STATUS, RP0 ; Select Bank 1 bcf OPTION_REG, INTEDG ; Select INT edge low bcf OPTION_REG, T0CS ; Select internal timer bcf STATUS, RP0 ; Select Bank 0 bsf INTCON, GIE ; Enable all interrupts bsf INTCON, T0IE ; Timer0 interrupt Enable bcf INTCON, T0IF ; Clear Timer0 interrupt flag bsf INTCON, INTE ; INT interrupt Enable bcf INTCON, INTF ; Clear INT interrupt flag; Clear program flags (very important to do it after interrupt initialisation) clrf Flags; MAIN PROGRAM; Print "Chrono Ready" code call Chrono_Ready; Main outputMain_output movfw Char1 ; Get Char1 to W movwf PORTB ; Move W (Char1) to PortB bsf PORTA, 1 ; Turn on Char1 call contrast ; Pause output bcf PORTA, 1 ; Turn off Char1 movfw Char2 ; Get Char2 to W movwf PORTB ; Move W (Char2) to PortB bsf PORTA, 2 ; Turn on Char2 call contrast ; Pause output bcf PORTA, 2 ; Turn off Char2 movfw Char3 ; Get Char3 to W movwf PORTB ; Move W (Char3) to PortB bsf PORTA, 3 ; Turn on Char3 call contrast ; Pause output bcf PORTA, 3 ; Turn off Char3 btfsc Flags, 0 ; Check if calculation of speed is needed call Calculate ; If needed (Flag0 = 1) call calculation subroutine goto Main_output; CALCULATE SPEEDCalculate; Check if no error occurred incf TimeEH, f ; Increase time elapsed higher byte (TimerEH) btfss STATUS, Z ; Test for higher byte overflow goto DoCalc ; If overflow did not occurred (STATUS Carry = 0) goto "DoCalc" goto ErrorCalc ; If overflow occurred (STATUS Carry = 0) goto "ErrorCalc"; Error in calculationErrorCalc movlw 0x0C ; "E" -> Char1 movwf Char1 movlw 0x0E ; "r" -> Char2 movwf Char2 movlw 0x0B ; "C" -> Char3 movwf Char3 goto FinishCalc; Do calculationDoCalc decf TimeEH, f ; Decrease time elapsed higher byte (TimerEH) after checking clrf Char1 ; Clear display character 1 clrf Char2 ; Clear display character 2 clrf Char3 ; Clear display character 3 movfw SensDistH ; Set distance to calculation variable movwf CalcDistH movfw SensDistL movwf CalcDistL DivisionCalc call SubtractCalc btfsc Flags, 1 goto FinishCalc call IncreaseDEC goto DivisionCalcFinishCalc; Get Characters to display movfw Char1 call Get_char movwf Char1 movfw Char2 call Get_char movwf Char2 movfw Char3 call Get_char movwf Char3; bcf Flags, 0 ; Clear flag to calculate speed return ; Return from calculation; Increase decimal counterSubtractCalc bcf Flags, 1 ; subtract lower byte movfw TimeEL subwf CalcDistL, f btfsc STATUS, C goto SubtractHigh ; borrow from higher byte movlw .1 subwf CalcDistH, f btfss STATUS, C goto SubtractImpossible SubtractHigh ; subtract higher byte movfw TimeEH subwf CalcDistH, f btfss STATUS, C goto SubtractImpossible returnSubtractImpossible bsf Flags, 1 returnIncreaseDEC incf Char3, f movfw Char3 sublw .9 btfsc STATUS, C return movlw .0 movwf Char3 incf Char2, f movfw Char2 sublw .9 btfsc STATUS, C return movlw .0 movwf Char2 incf Char1, f movfw Char1 sublw .9 btfsc STATUS, C return decf Char1, f return ; TEST SENSORSTest_sensors btfsc PORTB, 0 ; Test RB0 for high level goto Start_normal ; If RB0=1 go to "Start_normal" call Error_sensors ; If RB0=0 call "Error_sensors" goto Main_output ; and go to "Main output"; INTERRUPTS; Test for which interruptInterrupts; Push bcf IntBANK, 0 ; Clear temp BANK btfsc STATUS, RP0 ; Check real BANK bsf IntBANK, 0 ; Store BANK if RP0=1 movwf IntW ; Save W bsf STATUS, RP0 ; Set BANK 1 movfw OPTION_REG ; Get OPTION_REG movwf IntOPTION ; Save OPTION bcf STATUS, RP0 ; Clear BANK btfsc IntBANK, 0 ; Check temp BANK bsf STATUS, RP0 ; Restore BANK if temp BANK = 1 movfw STATUS ; Get STATUS movwf IntSTATUS ; Save STATUS; btfsc INTCON, INTF ; Test for INT interrupt goto Sensor_interrupt ; If INTF=1 goto "Sensor_interrupt" btfsc INTCON, T0IF ; Test for TMR0 interrupt goto Timer_interrupt ; If T0IF=1 goto "Timer_interrupt"; Timer interruptTimer_interrupt incf TimerH, f ; Increase timer higher byte (TimerH) btfss STATUS, Z ; Test for higher byte overflow goto Time_left ; If overflow did not occurred (STATUS Carry = 0) goto "Time_left" movlw 0xFF ; If overflow occurred (STATUS Carry = 1) set FF => W ... movwf TimerH ; ... W => TimerH (= FF [maximum counter value, no reason to count further])Time_left bcf INTCON, T0IF goto Interrupts_end; Sensor interruptSensor_interrupt movfw TimerH ; Move TimerH to TimeEH (time elapsed high) movwf TimeEH movfw TMR0 ; Move TMR0 to TimeEL (time elapsed low) movwf TimeEL clrf TimerH ; Clear timer high byte clrf TMR0 ; Clear timer low byte bsf Flags, 0 ; Set flag to calculate speed bcf INTCON, INTF goto Interrupts_end; End of interruptInterrupts_end; Pop movfw IntSTATUS ; Get STATUS movwf STATUS ; Save STATUS movfw IntOPTION ; Get OPTION_REG bsf STATUS, RP0 ; Set BANK 1 movwf OPTION_REG ; Save OPTION movfw IntW ; Save W bcf STATUS, RP0 ; Clear BANK btfsc IntBANK, 0 ; Check temp BANK bsf STATUS, RP0 ; Restore BANK if temp BANK = 1; retfie ; Return from interrupts and set INTCON GIE bit; SUBROUTINES; Chrono readyChrono_Ready ; "Chr" to display movlw 0x0B ; "C" -> Char1 call Get_char movwf Char1 movlw 0x0D ; "h" -> Char2 call Get_char movwf Char2 movlw 0x0E ; "r" -> Char3 call Get_char movwf Char3 return; Error sensorsError_sensors ; "ErS" to display movlw 0x0C ; "E" -> Char1 call Get_char movwf Char1 movlw 0x0E ; "r" -> Char2 call Get_char movwf Char2 movlw 0x05 ; "S"/"5" -> Char3 call Get_char movwf Char3 return ; Get character code; charcter No => W; call Get_char; character Code => WGet_char addwf PCL, f ; Increase program counter in W steps retlw B'10000000' ; "0" retlw B'11110010' ; "1" retlw B'01001000' ; "2" retlw B'01100000' ; "3" retlw B'00110010' ; "4" retlw B'00100100' ; "5" retlw B'00000100' ; "6" retlw B'11110000' ; "7" retlw B'00000000' ; "8" retlw B'00100000' ; "9" retlw B'01111110' ; "-" retlw B'10001100' ; "C" retlw B'00001100' ; "E" retlw B'00010110' ; "h" retlw B'01011110' ; "r" retlw B'11111110' ; " "contrast movlw 0x80 movwf Contrastset_contr decfsz Contrast, f goto set_contr return; CODE END end
kas_nepatinka rašė:Gana nesudetinga, tik kaip reiks plokštę išėsdint?O pats ėsdinai plokštes ar uzsakinėjai kur ?