;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Dig_test.asm ; ; By Adriaan Van Nuffel and Robin Reusens ; afvnuffe@vub.ac.be, rreusens@vub.ac.be ; ; This program tests the two 7-segment digits. The digits are controlled by ; shift registers 1 and two. (Other pins are also defined in the beginning ; of the program, but they are not used.) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LIST P=PIC16F877A #INCLUDE P16F877A.INC __CONFIG _CP_OFF & _DEBUG_OFF & _LVP_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _XT_OSC ORG 0 ; *** Giving names to the used registers *** TIMER1 EQU H'20' ; For the Delay routine TIMER2 EQU H'21' SH_REG1 EQU H'22' ; Used for accessing the shift registers (SH_REG1 controls SH_REG2 EQU H'23' ; the left digit, SH_REG2 the right one) INSDIG_COUNTER EQU H'24' ; Used as counter in the INSERDIGITS subroutine SCORE_DEC1 EQU H'25' ; Used in main loop to test the binary to decimal conversion SCORE_DEC2 EQU H'26' A_SH_REG EQU H'27' ; Used for the conversion to a decimal number of the score A_DEC EQU H'28' ; Idem. DIG_0 EQU H'70' ; The digits DIG_1 EQU H'71' DIG_2 EQU H'72' DIG_3 EQU H'73' DIG_4 EQU H'74' DIG_5 EQU H'75' DIG_6 EQU H'76' DIG_7 EQU H'77' DIG_8 EQU H'78' DIG_9 EQU H'79' ; *** Configure all pins *** RESET ; Outputs: ; ; RB5-RB0 (Actuation of the relays) ; RA0 -> DS Shift Register 1 (Data Send) ; RA1 -> DS Sh Reg 2 ; RA2 -> OE Sh Reg 1&2 (Output Enable, active low) ; RA3 -> ST_CP Sh Reg 1&2 (Storage register clock pulse) ; RA4 -> SH_CP Sh Reg 1&2 (Shift register clock pulse) ; ; Inputs: ; ; RD2-RD7 (From comparators) ; ; Not used: ; ; RA5, RE0-RE2, RC0-RC3, RC4-RC7, RD0-RD1 (= 14 pins) ; RB6 & RB7 are only connected to the programming pins ; BCF STATUS, RP0 ; Go to Bank 0 BCF STATUS, RP1 CLRF PORTA ; Initialize Port A (See example datasheet p 41) CLRF PORTB ; " " B CLRF PORTD ; " " D (I'm not sure if all this is necessary...) BSF STATUS, RP0 ; Go to Bank 1 MOVLW B'00000110' ; Adjust the settings in ADCON1, to make all the pins MOVWF ADCON1 ; of port A digital I/O. See datasheet ('ds', from now on) p.128 MOVLW B'11000000' ; All pins of A are outputs, except RA7 and RA6, which MOVWF TRISA ; are non-existant CLRF TRISB ; All pins of port B are outputs. BCF TRISE, PSPMODE ; Port D pins are digital I/O. (ds p. 50) MOVLW B'11110000' ; And they are all inputs, except RD0 and RD1, which MOVWF TRISD ; are not used. ; *** Defining the digits *** BCF STATUS, RP0 ; Go to Bank 0 MOVLW B'01111011' MOVWF DIG_0 MOVLW B'01100000' MOVWF DIG_1 MOVLW B'00110111' MOVWF DIG_2 MOVLW B'01110110' MOVWF DIG_3 MOVLW B'01101100' MOVWF DIG_4 MOVLW B'01011110' MOVWF DIG_5 MOVLW B'01011111' MOVWF DIG_6 MOVLW B'01110000' MOVWF DIG_7 MOVLW B'01111111' MOVWF DIG_8 MOVLW B'01111110' MOVWF DIG_9 CLRF SCORE_DEC1 CLRF SCORE_DEC2 ; *** Main part *** ; Here we choose what to show on the digits. First we do some showing off. ; Then there is a counter (SCORE) which counts the number of loops. This is ; to test the conversion from a binary number to a decimal number displayed ; on the digits... mainloop BSF PORTA,H'2' ; Output disable: lettin' it blink a bit... CALL DELAY BCF PORTA,H'2' ; Output enable again... MOVF DIG_0, 0 MOVWF SH_REG1 ; First we show zero's... MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_1, 0 ; ...34... MOVWF SH_REG1 MOVF DIG_1, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_2, 0 ; ..and now we can start showing off: 12... MOVWF SH_REG1 MOVF DIG_2, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_3, 0 ; ...34... MOVWF SH_REG1 MOVF DIG_3, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_4, 0 ; ...34... MOVWF SH_REG1 MOVF DIG_4, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_5, 0 ; ...34... MOVWF SH_REG1 MOVF DIG_5, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_6, 0 ; ...56... MOVWF SH_REG1 MOVF DIG_6, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_7, 0 ; ...34... MOVWF SH_REG1 MOVF DIG_7, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_8, 0 ; ...78... MOVWF SH_REG1 MOVF DIG_8, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY MOVF DIG_9, 0 ; ...90... MOVWF SH_REG1 MOVF DIG_9, 0 MOVWF SH_REG2 CALL INSERTDIGITS CALL DELAY CALL SHOWSCORE ; Showin' the score by lettin' it blink! CALL INCSCORE CALL DELAY CALL DELAY CALL DELAY GOTO mainloop ; *** INCSCORE: This subroutine increments the score. ; The two decimals of the score are calculated seperately, to make ; the conversion to decimal easier. SCORE_DEC1 is the right decimal, ; SCORE_DEC2 the left one. (This is the opposite of the SH_REG's, just ; to make it easier.) INCSCORE INCF SCORE_DEC1, 1 MOVF SCORE_DEC1, 0 SUBLW H'0A' ; When the first decimal of the score has become 10, BTFSS STATUS, Z ; the Z-bit will be set. GOTO ietsverder BSF PORTD, H'2' CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY CALL DELAY BCF PORTD, H'2' CLRF SCORE_DEC1 ; We have to put the first decimal then back to 0, INCF SCORE_DEC2, 1 ; and increment the second decimal. ietsverder RETURN ; *** SHOWSCORE: This subroutine calls CONVERTSCORE twice to check for each ; score_decimal which digit should be displayed. Finally, they get displayed ; by calling INSERTDIGITS (automatically) SHOWSCORE MOVF SCORE_DEC1,0 MOVWF A_DEC CALL CONVERTSCORE MOVF A_SH_REG, 0 MOVWF SH_REG2 MOVF SCORE_DEC2, 0 MOVWF A_DEC CALL CONVERTSCORE MOVF A_SH_REG, 0 MOVWF SH_REG1 CALL INSERTDIGITS RETURN ; *** CONVERTSCORE: This subroutine takes care of the conversion to decimal of the score. ; We simply check for both decimals with which DIG_... they correspond. CONVERTSCORE test_nul MOVLW H'00' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_een MOVF DIG_0, 0 MOVWF A_SH_REG GOTO einde_van_testen test_een MOVLW H'01' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_twee MOVF DIG_1, 0 MOVWF A_SH_REG GOTO einde_van_testen test_twee MOVLW H'02' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_drie MOVF DIG_2, 0 MOVWF A_SH_REG GOTO einde_van_testen test_drie MOVLW H'03' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_vier MOVF DIG_3, 0 MOVWF A_SH_REG GOTO einde_van_testen test_vier MOVLW H'04' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_vijf MOVF DIG_4, 0 MOVWF A_SH_REG GOTO einde_van_testen test_vijf MOVLW H'05' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_zes MOVF DIG_5, 0 MOVWF A_SH_REG GOTO einde_van_testen test_zes MOVLW H'06' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_zeven MOVF DIG_6, 0 MOVWF A_SH_REG GOTO einde_van_testen test_zeven MOVLW H'07' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_acht MOVF DIG_7, 0 MOVWF A_SH_REG GOTO einde_van_testen test_acht MOVLW H'08' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO test_negen MOVF DIG_8, 0 MOVWF A_SH_REG GOTO einde_van_testen test_negen MOVLW H'09' SUBWF A_DEC, 0 BTFSS STATUS, Z GOTO einde_van_testen MOVF DIG_9, 0 MOVWF A_SH_REG GOTO einde_van_testen einde_van_testen RETURN ; *** INSERTDIGITS: This subroutine 'inserts' the correct bits in the shift registers *** INSERTDIGITS BCF STATUS, RP0 ; Go to Bank 0 (in case we weren't there yet...) BCF STATUS, RP1 BSF INSDIG_COUNTER, H'3' ; 8 is the value, and we stick it in a counter! insdigloop CLRF PORTA ; (Remark: OE is active low, so clearing port A will enable the output) RLF SH_REG1,1 ; Check the next bit BTFSC STATUS, C ; and if it's set, then set the RA0 BSF PORTA, H'0' ; (which is connected to the DS of the first shift register). RLF SH_REG2,1 ; Now we do the same for the second shift register. BTFSC STATUS, C BSF PORTA, H'1' ; RA1 is connected to the DS of the second shift register. BSF PORTA, H'4' ; Then we give a pulse on the clock of the shift registers (SH_CP) DECFSZ INSDIG_COUNTER, 1 GOTO insdigloop BSF PORTA, H'3' ; Now we give a pulse on the clock of the storage registers (ST_CP) to show the result. RETURN ; End of subroutine ; *** Delay routine *** DELAY CLRWDT MOVLW D'255' MOVWF TIMER1 DELAY2 MOVLW D'255' MOVWF TIMER2 DECFSZ TIMER2,F GOTO $-1 DECFSZ TIMER1,F GOTO DELAY2 RETLW 0 END ; End of source code.