;**************************************************************** ;Started 18/6/2009 ;STROOP GAME - Press button according to the colour of the LED ;Buttons recognised when project turned on. ;Port A drives 3 tri-coloured LEDs ;Port B drives 7 segment display and keys ;**************************************************************** list P = 16F628 ;microcontroller include ;registers for F628 __Config _cp_off & _lvp_off & _pwrte_on & _wdt_off & _intRC_osc_noclkout & _mclre_off ;code protection - off ;low-voltage programming - off ;power-up timer - on ;watchdog timer - off ;use internal RC for 4MHz - all pins for in-out ;**************************************************************** ; variables - names and files ;**************************************************************** ;Files for F628 start at 20h temp1 equ 20h ;for delay temp2 equ 21h ;for delay count equ 22h ;counts loops for switch Random equ 23h ;random number file units equ 24h ; tens equ 25h ; Sw_Flag equ 26h ; _20Secs equ 27h ;file for counting up to 20 seconds loops equ 28h ;loops for number display Produce equ 29h ;produce random number temp3 equ 2Ah ;for 500mS ;**************************************************************** ;Equates ;**************************************************************** status equ 0x03 cmcon equ 0x1F rp1 equ 0x06 rp0 equ 0x05 portA equ 0x05 portB equ 0x06 z equ 0x02 ;**************************************************************** ;Beginning of program ;**************************************************************** Start org 0x00 ;program starts at location 000 goto Stroop ;goto Stroop nop nop ;NOPs to get past reset vector address org 4 goto isr SetUp bsf status,rp0 movlw b'00000000' ;Make RA output movwf 05h ;trisA clrf 06h ;trisB Make all RB output movlw b'10000000'; movwf OPTION_REG ; x000 0000 x=1= weak pull-ups disabled bcf status,rp0 ;select programming area - bank0 movlw b'00000000' ;6,7=0 disables all interrupts movwf INTCON ;until we want timing to commence clrf Sw_Flag movlw 07h ;turn comparators off movwf cmcon clrf portA clrf portB clrf units clrf tens clrf Random ;random will be 1-9 movlw .39 movwf _20Secs goto Main ;************************************* ;* Tables * ;************************************* table1 addwf PCL,F ;02h,1 nop ;display random LED colour retlw b'00000001' ; Led A - red retlw b'00000011' ; Led A - orange retlw b'00000010' ; Led A - green retlw b'00000100' ; Led B - red retlw b'00001100' ; Led B - orange retlw b'00001000' ; Led B - green retlw b'01000000' ; Led C - red retlw b'11000000' ; Led C - orange retlw b'10000000' ; Led C - green table2 addwf PCL,F ;02h,1 add W to program counter retlw b'00111111' ; "0" -|F|E|D|C|B|A retlw b'00000110' ; "1" -|-|-|-|C|B|- retlw b'01011011' ; "2" G|-|E|D|-|B|A retlw b'01001111' ; "3" G|-|-|D|C|B|A retlw b'01100110' ; "4" G|F|-|-|C|B|- retlw b'01101101' ; "5" G|F|-|D|C|-|A retlw b'01111101' ; "6" G|F|E|D|C|-|A retlw b'00000111' ; "7" -|-|-|-|C|B|A retlw b'01111111' ; "8" G|F|E|D|C|B|A retlw b'01101111' ; "9" G|F|-|D|C|B|A ;************************************ ;* Sub routines * ;************************************ Attract ;flash all red, orange green then random LED movlw b'01000101' ; all red movwf portA call _250mS movlw b'11001111' ; all orange movwf portA call _250mS movlw b'10001010' ; all green movwf portA call _250mS clrf portA call _250mS call _250mS retlw 00 ;produce random number Create incf Produce,f movlw .10 ;put ten into w xorwf Produce,0 ;compare Random file with ten btfss status,2 ;zero flag in status file. Will be set if Random is ten goto $+3 clrf Produce incf Produce,f retlw 00 ;Delays _1mS nop decfsz temp1,f goto _1mS retlw 00 _10mS movlw 0Ah movwf temp2 _b nop decfsz temp1,f goto _b decfsz temp2,f goto _b retlw 00 _100mS movlw .100 movwf temp2 _c nop decfsz temp1,f goto _c decfsz temp2,f goto _c retlw 00 _250mS movlw .240 movwf temp2 _d nop decfsz temp1,f goto _d decfsz temp2,f goto _d retlw 00 _500mS movlw 02 movwf temp3 call _250mS decfsz temp3,f goto $-2 retlw 00 _3Sec movlw .12 movwf temp3 call _250mS decfsz temp3,f goto $-2 retlw 00 ;interrupt service routine isr nop bsf status,rp0 ;Bank 1 bsf PIE1,0 ;,0 1=enables TMR1 interrupt bcf status,rp0 ;bank 0 bcf PIR1,0 ;clear TMR1 overflow flag bsf INTCON,7 ;This instruction is needed HERE!!! bsf INTCON,6 ;1=enable all peripheral interrupts decfsz _20Secs,f ;creates 20Sec delay for each game. retfie bcf PIE1,0 ;,0 0=disables TMR1 interrupt bcf INTCON,6 ;0=disable all peripheral interrupts decf tens,f incf tens,f movlw .10 subwf units,f btfsc status,0 ;test carry bit for borrow goto $-4 movlw .10 addwf units,f movlw 03 movwf loops movf tens,w btfsc status,z goto $+.18 ;If 0-9, display single digit call table2 movwf portB call _500mS call _250mS clrf portB call _250mS movf units,w call table2 movwf portB call _500mS call _250mS clrf portB call _500mS call _500mS decfsz loops,f goto $-.18 goto SetUp movf units,w call table2 movwf portB call _3Sec goto SetUp ; show Stroop Stroop bsf status,rp0 clrf 06h ;trisB Make all RB output movlw b'10000000'; movwf OPTION_REG ; x000 0000 x=1= weak pull-ups disabled bcf status,rp0 ;select programming area - bank0 movlw 07h ;turn comparators off movwf cmcon clrf portA movlw b'01101101' ; "S" movwf portB call _500mS clrf portB call _250mS movlw b'01111000' ; "t" movwf portB call _500mS clrf portB call _250mS movlw b'01010000' ; "r" movwf portB call _500mS clrf portB call _250mS movlw b'01011100' ; "o" movwf portB call _500mS clrf portB call _250mS movlw b'01011100' ; "o" movwf portB call _500mS clrf portB call _250mS movlw b'01110011' ; "P" movwf portB call _500mS clrf portB goto SetUp Sw clrf Sw_Flag bsf status,rp0 bcf 06h,7 ;trisB Make bit 7 output bcf status,rp0 bsf portB,7 ;make bit 7 HIGH call _1mS ;create delay to charge 100n bsf status,rp0 bsf 06h,7 ;trisB Make bit 7 input bcf status,rp0 call _10mS call _10mS btfsc 06h,7 ;if HIGH, button not pushed retlw 00 clrf count bsf status,rp0 bcf 06h,7 ;trisB Make bit 7 output bcf status,rp0 bsf portB,7 ;make bit 7 HIGH call _1mS ;create delay to charge 100n bsf status,rp0 bsf 06h,7 ;trisB Make bit 7 input bcf status,rp0 SwA call _1mS call _1mS incf count,f btfsc 06h,7 ;is input HIGH? goto SwA ;count exits with 1-8 bsf Sw_Flag,0 ;button has been pushed decfsz count,f goto $+3 bsf Sw_Flag,1 retlw 00 decfsz count,f goto $+3 bsf Sw_Flag,1 retlw 00 decfsz count,f goto $+3 bsf Sw_Flag,2 retlw 00 decfsz count,f goto $+3 bsf Sw_Flag,2 retlw 00 decfsz count,f goto $+3 bsf Sw_Flag,2 retlw 00 bsf Sw_Flag,3 retlw 00 ;switch released Sw_Rel clrf Sw_Flag bsf status,rp0 bcf 06h,7 ;trisB Make bit 7 output bcf status,rp0 bsf portB,7 ;make bit 7 HIGH call _1mS ;create delay to charge 100n bsf status,rp0 bsf 06h,7 ;trisB Make bit 7 input bcf status,rp0 call _10mS call _10mS btfsc 06h,7 ;if HIGH, button not pushed retlw 00 bsf Sw_Flag,0 retlw 00 ;************************************* ;* Main * ;************************************* ;Stroop comes on "blank" looking for button-push Main call Create call Sw btfss Sw_Flag,0 goto $-3 ;no ;button pressed and Random Number generated ;Stroop goes into ATTRACT mode then stops on Random LED call Attract ;Display Random LED colour, waiting for sw press ;**************************************************************** ;* Start Timer1 to count 20 seconds in the background * ;**************************************************************** bsf status,rp0 ;Bank 1 movlw b'10000000' ; movwf OPTION_REG ; x000 0000 x=1= weak pull-ups disabled bcf status,rp0 ;bank 0 movlw b'11000000' ;b'11000000' movwf INTCON ;,0 1=RB port change interrupt flag ;,1 1=RB0 interrupt occurred ;bcf INTCON,2 ;1=TMR0 overflowed. Clear overflow flag ;bcf INTCON,3 ;1=enable RB port change interrupt ;bcf INTCON,4 ;1=enable RB external interrupt ;bsf INTCON,5 ;1=enable TMR0 overflow (interrupt) ;bcf INTCON,6 ;1=enable all peripheral interrupts ;bsf INTCON,7 ;1=enable all unmasked interrupts movlw b'00110101' ;b'00110001' movwf T1CON ;,7 not used ;,6 0=Timer1 is ON ;,5,4 11=8 prescale (max) 01=1:2 ;,3 bit ignored ;,2 This MUST BE SET!!!!!! ;,1 0=int clock ;,0 1=enable timer1 bsf status,rp0 ;Bank 1 (Must use Bank1) bsf PIE1,0 ;,0 1=enables TMR1 interrupt bcf status,rp0 ;bank 0 bcf PIR1,0 ;clear TMR1 overflow flag clrf TMR1L ;clear the Timer1 low register clrf TMR1H ;clear the Timer1 high register ;Timer0 is not used ; will go to isr when overflow occurs in TMR1 ;0.52 sec when prescaler=1:8 524,288uS bsf status,rp0 ;Bank 1 (Must use Bank1) bsf PIE1,0 ;,0 1=enables TMR1 interrupt bcf status,rp0 ;bank 0 ;game has started with random LED Main2 movf Produce,w movwf Random call table1 movwf portA ;show random number ;program gets to here after 1 press call Create call Sw btfss Sw_Flag,0 ;has button been pressed? goto $-3 ;no ;button pressed movlw 01 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,1 ;random=1 Is sw = button1 goto release incf units,f goto release movlw 02 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,2 ;random=2 Is sw = button2 goto release incf units,f goto release movlw 03 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,3 ;random=3 Is sw = button3 goto release incf units,f goto release movlw 04 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,1 ;random=4 Is sw = button1 goto release incf units,f goto release movlw 05 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,2 ;random=5 Is sw = button2 goto release incf units,f goto release movlw 06 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,3 ;random=6 Is sw = button3 goto release incf units,f goto release movlw 07 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,1 ;random=7 Is sw = button1 goto release incf units,f goto release movlw 08 xorwf Random,0 ;yes btfss status,z ;test zero bit for compare goto $+5 btfss Sw_Flag,2 ;random=8 Is sw = button2 goto release incf units,f goto release incf units,f goto release release clrf portA call _500mS goto Main2 End