Introduction This project describes a PIC10F200-based electronic dice. The reason I made this was that I had a small corner left over when ordering a panel with a couple of other PCBs and thought I would rather use the corner for something interesting than leave it unused, so I made a dice project. The PCB is quite small, so it is hard to etch it yourself. Even though this is a very simple project, it requires some surface mount soldering skills, proper tools, and a steady hand as it is built with surface mount components only. But it might be a good start if you have experience with through-hole soldering and want to try surface mount.
;** #include p10f222.inc list r=dec __CONFIG _CP_OFF & _WDT_OFF & _IOFSCS_4MHZ & _MCLRE_OFF temp0 equ 0x10 temp1 equ 0x11 temp2 equ 0x12 digit equ 0x13 state equ 0x14 time_l equ 0x15 time_h equ 0x16 number equ 0x17 S_IDLE equ 0x00 S_WAIT equ 0x01 S_ROLL equ 0x02 S_SHOW equ 0x03 ;rst nop code 0x00 ;Reset Vector movwf OSCCAL goto Start ;Jump to Start code ; Table with digits and graphics for roll ; Note that order of numbers doesn't matter ; because they are shown randomly so the ; table has been rolled to make roll table ; and digit table overlap thus saving one ; byte in the table, a lot of memory left ; so it is just to show off ;) digits andlw 7 ;prevents micro jumping past table addwf PCL,F retlw B'1001' ;4 retlw B'0001' ;5 retlw B'1011' ;6 retlw B'0100' ;1 retlw B'1000' ;2 retlw B'0000' ;3 \ retlw B'0101' ;/ retlw B'0110' ;- ; big delay loop to create a delay of about w*3cc bigdelay movwf temp1 bigdelay_l0 movlw 0xFF movwf temp0 bigdelay_l1 decfsz temp0,F goto bigdelay_l1 decfsz temp1,F goto bigdelay_l0 retlw 0 ; Initialize ports etc Start movlw B'1000' ; set leds as outputs and switch as input tris GPIO clrf ADCON0 ; disable ADC on PIC10F22X movlw B'00000000' option clrf time_l ;clear time clrf time_h main ;display phase 1 movfw digit ;for a given digit call digits ;get on/off values for the four LED sets movwf temp2 ;store in temp2 for phase 2 andlw B'0011' ;mask out lower 2 bits movwf GPIO ;output to LEDs (and set common to low) movlw 3 call bigdelay ;wait for 1/200 second ;display phase 2 rrf temp2,F ;shift down upper two bits rrf temp2,W xorlw B'0100' ;set common line bit to high movwf GPIO ;output to LEDs movlw 3 call bigdelay ;wait for 1/200 second ;handle timer incf time_l,f ;increase timer low byte skpnz ;if overflow incf time_h,f ;then increase timer high byte ;handle main state machine movfw state ;switch on state andlw 0x03 ;prevent illegal jump to be safe addwf PCL,F ;jump to one of the four lines below goto state_idle goto state_wait goto state_roll ;"fall through" to show state below ;-------------------------------------------------------- ;- Show state, shows the result state_show movlw S_WAIT btfss GPIO,3 ;if button is pressed movwf state ;set state to WAIT to make another roll movfw time_h ;check if time = 512 main loop cycles xorlw 0x2 skpz goto main ;if not get back to main and keep waiting clrf state ;otherwise: set idle state clrf GPIO ;turn of leds sleep ;go to sleep ;-------------------------------------------------------- ; this is the state where the system wakes up state_idle btfsc GPIO,3 ;if button was not pressed sleep ;then power down movlw S_WAIT movwf state ;otherwise set state to wait goto main ;-------------------------------------------------------- ;- Wait for button to be released and decrease number ;- to get user pressing time to generate a random value state_wait movlw S_ROLL btfss GPIO,3 ;if button is released goto state_wait_j0 movwf state ;set state to roll clrf time_l ;and clear time clrf time_h state_wait_j0 decfsz number,F ;decrease number goto state_wait_j1 movlw 6 ;restart at 6 if zero movwf number ;"random" number of 0..5 state_wait_j1 goto spin ;show spin effect ;-------------------------------------------------------- ;- Roll state, this is just to get som tensions, rolling ;- for a couple of extra seconds state_roll movfw time_h xorlw 0x1 ;check if time = 256 main loop cycles skpz goto spin; ;show spin effect before getting ;back to main and keep waiting movlw S_SHOW ;otherwise, set state = show movwf state clrf time_l ;clear time clrf time_h decf number,w ;set digit to number-1 (result of roll) movwf digit goto main ;get back to main, show the result ;-------------------------------------------------------- ;- Spin effect, shows a rolling sequence of \/- spin movfw time_l ;get low part of time andlw 0x1F ;check lower 4 bits skpz ;if nonzero goto main ;then continue ;the following is done every 16 display cycles incf digit,w ;else increase digit andlw 0x03 ;keep below upper limit skpnz ;and check for zero movlw 0x01 ;additional increase if zero xorlw 0x04 ;keep above lower limit movwf digit ;store back to digit goto main ;go to main loop end |