Random

generates a 16-bit pseudorandom number.

Games require a source of random numbers to keep the play surprising and exciting. Streams of pseudorandom bits can be used to generate white noise or interpolate between A/D converter measurements. Random simulates a hardware pseudorandom sequence generator made up of a shift register and three exclusive-OR (XOR) gates wired up as follows:

A circuit like this generates a sequence of bits that repeats every 65,535 shifts. Because of the long interval between the same bit pattern showing up, the sequence can, for many purposes, be considered random. To use Random, just call it. Upon return, the bits previously held in hiB and lowB will have been clocked through the equivalent of the circuit above. You can then use hiB or lowB, or the two combined into a 16-bit value, as your random number. You may also use a bit of one of the variables as a coin-toss decision maker. Random can be used to generate white-noise effects. Call the routine from within a tight program loop and copy one bit of hiB or lowB to an output pin. The stream of random bits at the output produces a rushing sound in a connected speaker or amplifier.

From one call to the next, the pattern inherent in Random is very apparent. A number is doubled, truncated to 16 bits (or 8, if you're using only one of the variables), and may or may not have a 1 added to the result. If Random is used to control patterns of lights or sounds, this pattern may be objectionable. In those cases, try to borrow an element of uncertainty from the outside world. For example, continuously call Random while waiting for the user to press a switch. This is analogous to BASIC programs on PCs that seed the random number generator with the current contents of the timer.

Demonstrating Random.

To see Random in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run RANDOM.SRC. The LEDs will show the sequence of pseudorandom patterns as they cycle through the variable lowB.


;
; ***************************************************************************
; ***  Bubble Software Parallax to PIC Source Converter. Copyright 1999.  ***
; ***  http://www.bubblesoftonline.com                 email: sales@picnpoke.com  ***
; ***************************************************************************
;
; RANDOM
; Generates a pseudorandom number. Works best if called from a loop so that
; the value of its workspace variable (consisting of lowB and hiB) is
; constantly stirred.	

	P = pic16c55
	#include <16c55.inc>   ; processor assembler definitions
	_CONFIG _xt_osc & _wdt_off & _protect_off
 	reset start

 	org 8
hiB Res d'1' ; MSB of 16-bit random number.
lowB Res d'1' ; LSB of 16-bit random number.
temp Res d'1' ; Temporary counter for delay.
temp2 Res d'1' ; Temporary counter for delay.

; Device data and reset vector
 	org 0

start        MovLW  !rb,#0              ; Output to show sequ onence LEDs.
             MovWF  !rb,w 
             MOVLW d'13'                ; Arbitrary starting values
             MOVWF lowB
             MOVLW d'99'                ; for the shift register.
             MOVWF hiB
start_loop   CALL Random                
             MOVF lowB,w                ; Display 8-bit random numbers
             MOVWF 6h
             CALL delay                 ; on LEDs connected to RB.
             GOTO start_loop            ; Endless loop
; Random number generator.
Random       MOVF hiB,w                 ; First, ensure that hiB and lowB aren't
             IORWF lowB,w               ; all zeros. If they are, NOT hiB to FFh.
             BTFSC status,z             ; Otherwise, leave hiB and lowB as is.
             COMF hiB                   
             MOVLW 0x80                 ; We want to XOR hiB.7, hiB.6, hiB.4
             BTFSC hiB,d'6'             ; and lowB.3 together in W. Rather than
             XORWF hiB                  ; try to line up these bits, we just
             BTFSC hiB,d'4'             ; check to see whether a bit is a 1. If it
             XORWF hiB                  ; is, XOR 80h into hiB. If it isn't,
             BTFSC lowB,d'3'            ; do nothing. When we're done, the
             XORWF hiB                  ; XOR of the 4 bits will be in hiB.7.
             RLF hiB,w                  ; Move hiB.7 into carry. 
             RLF lowB                   ; Rotate c into lowB.0, lowB.7 into c. 
             RLF hiB                    ; Rotate c into hiB.0. 
             RETLW 0h                   ; Delay loop for program demo. Remove when using just Random. 
delay        DECFSZ temp                
             GOTO delay
             DECFSZ temp2               
             GOTO delay
             RETLW 0h                   

             
             
             end


; RANDOM
; Generates a pseudorandom number. Works best if called from a loop so that
; the value of its workspace variable (consisting of lowB and hiB) is
; constantly stirred.	

	device	pic16c55,xt_osc,wdt_off,protect_off
	reset	start

	org	8
hiB	ds	1	; MSB of 16-bit random number.
lowB	ds	1	; LSB of 16-bit random number.
temp	ds	1	; Temporary counter for delay.
temp2	ds	1	; Temporary counter for delay.

; Device data and reset vector
	org	0

start	mov	!rb,#0		; Output to show sequence on LEDs.
	mov	lowB,#13	; Arbitrary starting values
	mov	hiB,#99 	; for the shift register.
:loop	call	Random
	mov	rb,lowB 	; Display 8-bit random numbers
	call	delay		; on LEDs connected to RB.
	jmp	:loop		; Endless loop
; Random number generator.
Random	mov	w,hiB		; First, ensure that hiB and lowB aren't
	OR	w,lowB		; all zeros. If they are, NOT hiB to FFh.
	snz			; Otherwise, leave hiB and lowB as is.
	NOT	hiB
	mov	w,#80h		; We want to XOR hiB.7, hiB.6, hiB.4
	snb	hiB.6		; and lowB.3 together in W. Rather than
	XOR	hiB,w		; try to line up these bits, we just
	snb	hiB.4		; check to see whether a bit is a 1. If it
	XOR	hiB,w		; is, XOR 80h into hiB. If it isn't,
	snb	lowB.3		; do nothing. When we're done, the
	XOR	hiB,w		; XOR of the 4 bits will be in hiB.7.
	mov	w,<<hiB 	; Move hiB.7 into carry. 
        rl 	lowB 		; Rotate c into lowB.0, lowB.7 into c. 
	rl 	hiB 		; Rotate c into hiB.0. 
	ret 			; Delay loop for program demo. Remove when using just Random. 
delay 	djnz 	temp,delay 
	djnz 	temp2,delay 
	ret 


See also: