'PIC code for Random number generation'
| David Sprenkle <EARTHLINK.NETdjsprenkle
Please find below PIC code for RANDOM NUMBER GENERATION by Peter H.
Anderson. I found it it one of the PIC sites. Hope it is useful to you.
Generating a Random Number
copyright, Peter H. Anderson, Dept of Electrical
Morgan State University, Baltimore, MD 21239, August 9, '97
This discussion presents a simple algorithm for generating a 16-bit
Any part of this 16-bit number may be used for random processes. For
example, if only a "coin
flip" is desired, any single bit may be used. If it is desired to
generate a random number in the
range 0, 1, 2 or 3, then any two bits may be used. In this application,
random numbers in the
range of 0 - 255 were desired and thus only eight of the 16 bits are
For applications where a random number in the range of 0-9 is desired,
one might use ten bits (0 -
1023) of the 16-bit random number and simply divide by 102. Another
possibility would be to
simply count the number of ones occuring in nine of the 16-bits.
Consider a 16-bit shift register consisting of bytes RAND_HI and
RAND_LO. Consider external
circuitry which exclusive ors bits RAND_HI.7, RAND_HI.6, RAND_HI.4 and
together to produce a feedback bit. A new random number is generated by
shifting this 16-bit
quantity to the left and then inserting the feedback bit in RAND_LO.0.
This is implemented in routine RANDOM in the following program.
Bit RAND_HI.7 is used to generate the feedback bit. If RAND_HI.6 is a
logic one, RAND_HI
is exclusive ored with 80H. However, if RAND_HI.6 is a logic zero,
RAND_HI is exclusive ored
with 00H. Thus RAND_HI.7 is now RAND_HI.7 XOR RAND_HI.6. Note that all
other bits in
RAND_HI are unchanged.
This process is continued for bits RAND_HI.4 and RAND_LO.3.
Thus, the feedback bit is now in bit RAND_HI.7. This is rotated into the
carry without modifying
RAND_HI by executing;
RLF RAND_HI, W
A two byte shift is then executed;
RLF RAND_LO, F ; feedback bit no in RAND_LO.0
; C contains former ms bit of RAND_LO
RLF RAND_HI, F ; former ms bit of RAND_LO now in ls bit of
Note that there is a problem with this 16-bit "ring counter"
implementation in that if the value is
0000, the next and all subsequent values will also be zero. Thus, this
condition is tested in the
RANDOM routine and if it is at 0000H, the value is modified to 00FF.
In the program, a call is made to RANDOM. The high byte, RAND_HI is
output to eight discrete
LEDs on PORTB. The low byte, RAND_LO is used for a delay of 10 - 2560
; Program RANDOM.ASM
; Illustrates an implementation of a 16-bit random number generator.
; Assumes 8 LEDs on PORTB. A random pattern is displayed for a random
; amount of time. Continuous loop.
; copyright, Peter H. Anderson, MSU, August 9, '97
LOOP3 EQU BASE_VAR+0 ; for timing
LOOP2 EQU BASE_VAR+1
LOOP1 EQU BASE_VAR+2
RAND_HI EQU BASE_VAR+3 ; 16-bit random number
RAND_LO EQU BASE_VAR+4
BSF STATUS, RP0
CLRF TRISB ; all bits on PORTB are outputs
BCF STATUS, RP0
CALL RANDOM ; generate 16-bit random number
MOVF RAND_HI, W ; use high byte as random pattern
MOVF RAND_LO, W ; use low byte as random delay
GOTO MAIN_1 ; repeat indefinitely
MOVF RAND_HI, W ; if current random is 0000, make it
IORWF RAND_LO, W
BTFSC STATUS, Z
COMF RAND_LO, F
BTFSS RAND_HI, 6 ; hi.7 = hi.7 xor hi.6
BTFSC RAND_HI, 6
XORWF RAND_HI, F
BTFSS RAND_HI, 4 ; hi.7 = hi.7 xor hi.4
BTFSC RAND_HI, 4
XORWF RAND_HI, F
BTFSS RAND_LO, 3 ; hi.7 = hi.7 xor lo.3
BTFSC RAND_LO, 3
XORWF RAND_HI, F
RLF RAND_HI, W ; carry = hi.7
RLF RAND_LO, F ; double left shift
RLF RAND_HI, F
DELAY: ; delays loop3 * 10 msecs
MOVLW .10 ; 10 msecs
DECFSZ LOOP1, F
DECFSZ LOOP2, F
DECFSZ LOOP3, F
David Sprenkle wrote:
Microchip Design Consultant
No. 70, 9th Main Road,
Bangalore - 560 054.
Tel : +91-80-3362807
Fax : +91-80-3369451
Email : vsnl.comchiptech
>Generating a Random Number
> copyright, Peter H. Anderson, Dept of Electrical
> Morgan State University, Baltimore, MD 21239, August 9, '97
This is a broken implementation of a PN generator. The need for a trap for
the all zeroes condition tells you that it's broken. In a good
implementation, unless you start it at all zero, it will never get there on
The hack to keep it from locking, also shortens the sequence. :(
'PIC code for Random number generation'
|On Sun, 31 Jan 1999 22:08:31 -0500 dave vanhorn <CEDAR.NET> dvanhorn
>>Generating a Random Number
>> copyright, Peter H. Anderson, Dept of Electrical
>> Morgan State University, Baltimore, MD 21239, August 9,
>This is a broken implementation of a PN generator. The need for a trap
>the all zeroes condition tells you that it's broken. In a good
>implementation, unless you start it at all zero, it will never get
>The hack to keep it from locking, also shortens the sequence. :(
It shouldn't unless the sequence generator (bits that are xor'd) is
wrong. Normal operation will not allow the register to shift to all zero
unless it starts at all zero. Generators that give maximum length are
given in reference texts (I think Lin and Costello's _Error Control
Coding_ has a page of them). I don't know offhand if the one given is
The possibility of locking up at all zero is a normal property of any
linear feedback shift register regardless of the implementation.
The author's xoring process can be optimized *a lot*. This code or some
variation would work:
;Use RAND_HI.7 to accumulate new bit (RAND_HI.7 xor RAND_HI.6 xor
; RAND_HI.4 xor RAND_LO.3
rlf RAND_HI,w ;Get new bit into C
It helps to choose a register length so the generation of the sequence
only requires xoring two bits. That leads to shorter xoring code, but
may require more RAM to hold the register. One classic example is a
17-stage register with stages 14 and 17 xor'd to produce the new bits.
An important point not mentioned in the description is that each call to
"random" only gennerates one new psuedo-random bit. If you use more than
one bit of the registers as the result, the resulting numbers will be
correlated to each other. For example, if you use the low 3 bits and a
value of 011 occurs, the next value can only be 110 or 111. To prevent
this, call "random" n times, then isolate n bits fromt he register to use
as your random number.
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]
>>The hack to keep it from locking, also shortens the sequence. :(
>It shouldn't unless the sequence generator (bits that are xor'd) is
>wrong. Normal operation will not allow the register to shift to all zero
>unless it starts at all zero.
'swhat I said.
>An important point not mentioned in the description is that each call to
>"random" only gennerates one new psuedo-random bit. If you use more than
>one bit of the registers as the result, the resulting numbers will be
>correlated to each other. For example, if you use the low 3 bits and a
>value of 011 occurs, the next value can only be 110 or 111. To prevent
>this, call "random" n times, then isolate n bits fromt he register to use
>as your random number.
I implemented it as running as the least important task, merrily spinning
away with an unpredictable number of shifts between uses. For my purpose it
was "random" enough. One could take bits from various places and invert
some of them, and make them out of order, as long as the number of bits you
take is significantly less than the length of the register it should be
pretty hard to predict, if that's your goal.
More... (looser matching)
- Last day of these posts
- In 1999
, 2000 only
- New search...