>I need to generate a "random" delay between 0.5 and 10 second using 12c508
>int osc, prescaled at whatever!
I think that you need an n-bit random number generator that would satisfy
the number of steps in the interval. Here is an 8-bit example (sorry, no
code). I came across it somewhere in TI's MSP430 application notes some time
ago.
rnd(n) = rnd(n-1)*mult+inc
n - iteration number
rnd(0)= 123 - seed number
mult = 221 - multiplier
inc = 54 - prime number
(I modeled this in MATLAB. Looks ok)
Note, that result may be greater than 8 bit. Just leave only lower 8 bits.
This will generate pseudo-random sequence. Addition is not a problem.
Multiplication too can be found in Microchip's apps.
Well... If you you really want to learn how to walk..
Let's see, how to put the idea in words (; PIC ASM - words ;)
1. Delay = 0.5 - 10 sec
2. The random number generator will output numbers 0 - 255. This makes 256
steps resolution of the delay. (10 - 0.5) / 256 = 0.037 sec.
3. If you run 12c508 at 4 Mhz than instruction cycle time = 4 / 4e6 = 1e-6
sec and
one step equals 0.037 / 1e-6 = 37109 instructions. To generate this delay
you can choose between timer with prescaler and nested loops.
One step delay using nested loops:
;***************************************
MiniDelay macro
Local L1, L2
movlw x ;1
movwf Reg1 ;2
L1
movlw y ;1 ;3 ;6+d1 ;9+2*d1...
movwf Reg2 ;2
L2 decfsz Reg2, f ;3;6;9..
goto L2 ;4;7;
decfsz Reg1, f ;3+d1 ;6+2*d1
goto L1 ;4+d1 ;7+2*d1
endm
;***************************************
Internal loop will generate delay1 = 1 + 3 * y (instruction cycles)
The whole loop will consume delay = 1 + 3 * x + (x * delay1) = 1 + 4 * x + 3
* y * x
Note, that zero x or y is the same as 256 when using decfsz.
In our case delay = 37109. Find x and y that would best fit :).
4. The delay can be broken in two parts - one constant (0.5 sec) and another
variable (0 - 9.5sec). A common routine for both of them can be used. Let's
call it VarDelay
;***************************************
;Input: w - number of 0.037 sec mini-delays
VarDelay
iorlw 0 ;check if w=0
btfsc STATUS, Z
return ;exit if w=0
movwf Reg3 ;store input number
L3
MiniDelay
decfsz Reg3, f ;repeat if needed
goto L3
return
;***************************************
5. Now the most interesting - Pseudo Random Number Generator. There may be a
better approach, but for the beginning it's okay. (The problem is it has 128
numbers regularity)
;***************************************
;Random Number Generator
;rnd(n) = rnd(n-1) * 221 + 54
;***************************************
Rand
;Straight code multiplication:
;x * 221 = x * (1 + 4 + 8 + 16 + 64 +128)
;In this case we need only lower byte of result, so the higher byte is
ignored
movf Rnd, w ;w = rnd0
rlf Rnd, f ;rnd = 2 * rnd0 (MSB discarded, LSB not
cleared)
;I don't know if leaving LSB as it is will increase randomness - it needs
testing, but
;you can always clear it by including BCF Rnd, 0
rlf Rnd, f ;rnd = 4 * rnd0
addwf Rnd, w ;w = rnd0 + 4 * rnd0
rlf Rnd, f ;rnd = 8 * rnd0
addwf Rnd, w ;w = rnd0 + 4 * rnd0 + 8 * rnd0
rlf Rnd, f ;rnd = 16 * rnd0
addwf Rnd, w ;w = rnd0 * (1 + 4 + 8 + 16)
rlf Rnd, f ;rnd = 32 * rnd0
rlf Rnd, f ;rnd = 64 * rnd0
addwf Rnd, w ;w = rnd0 * (1 + 4 + 8 + 16 + 64)
rlf Rnd, f ;rnd = 128 * rnd0
addwf Rnd, w ;w = rnd0 * (1 + 4 + 8 + 16 + 64 + 128) = rnd0 *
221
addlw 54 ;w = rnd0 * 221 + 54
movwf Rnd ;Store result
return
;***************************************
Hoooh... I hope this message won't make you stumble. Good luck in putting
it all together.
>Hello Nikolai
>
> Thank you for the reply, but I dont yet have the experience to write
the
>code.
>Iam trying to run before I have learned to walk!!
>
>Cheers
> Kev
>
>