-
Categories
-
Platforms
-
Content
movf RANDOM,W
ANDWF three,0
Your last code in post #15 is:
What's your code using ANDLW?Code:movf RANDOM,W ANDWF three,0
;*******************************************************************************
; *
; Filename: *
; Date:02/23/2016 *
; FileVersion:0.6 *
; Author: *
; Company: *
; Description:Simple prog. to blink one port using ASM and repeated code *
; *
;*******************************************************************************
; *
; RevisionHistory: *
;0.0 syntax corrections and can't figure out __config issue!!! *
; 0.1 commented out config, temp. fix, used proper addressing of individual *
; -bits instead of broadly setting entire PORT *
; 0.2 blinking! - will have to play with values to achieve better timing *
; 0.3 learned how to access OSCCON and changed freq. - times closer to 1 sec *
; 0.4 LOOP'ed just the on/off and updated delay funct.-true100ms at 32k clock *
;0.5Create functions for different time delays *
;0.6Randomizewith TMR0 *
;*******************************************************************************
#include"p10LF320.inc"
;CONFIG
;__config 0x3FE6
__CONFIG _FOSC_INTOSC & _BOREN_ON & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _LVP_ON & _LPBOR_ON & _BORV_LO & _WRT_OFF
case0 equ .0
case1 equ .1
case2 equ .2
case3 equ .3
three equ .3
My_var UDATA
dc1 res 1
dc2 res 1
dc3 res 1
dc4 res 1
RANDOM res 4
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
Delay100ms
movwf dc3
dly2 movlw .1
movwf dc2
movlw .1 ;.127
movwf dc1 ;clrf dc1
dly1 decfsz dc1,f
goto dly1
decfsz dc2,f
goto dly1
decfsz dc3,f
goto dly2
retlw 0
On movlw b'0100' ;setting RA2 high
movwf PORTA
retlw 0
Off movlw b'0000' ;RA2 low
movwf PORTA
retlw 0
Standard
call On
movlw .1 ;.60
movwf Delay100ms
call Delay100ms
call Off
movlw .5
movwf Delay100ms
call Delay100ms
return ;retlw 0
Slow
call On
movlw .5 ;.175
movwf Delay100ms
call Delay100ms
call Off
movlw .2 ;.5
movwf Delay100ms
call Delay100ms
retlw 0
Fast
movlw .1
movwf dc4
One
call On
movlw .2 ;.25
movwf Delay100ms
call Delay100ms
call Off
movlw .1 ;.4
movwf Delay100ms
call Delay100ms
decfsz dc4
goto One
retlw 0
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
START
movlw b'00000010'
movwf OSCCON
clrf ANSELA ;digital i/o
clrf TRISA ;output
clrf PORTA ;clearing PORTA, all low except RA3
movf TMR0,W
movwf RANDOM
RLF RANDOM
RLF RANDOM
BTFSC RANDOM,4
XORLW 1
BTFSC RANDOM,5
XORLW 1
BTFSC RANDOM,3
XORLW 1
MOVWF RANDOM
LOOP
movf RANDOM,W
ANDLW 0x03
xorlw case0
btfsc STATUS, Z ;If SWITCH = CASE0, jump to LABEL0
goto Standard
xorlw case1^case0
btfsc STATUS, Z ;If SWITCH = CASE1, jump to LABEL1
goto Slow
xorlw case2^case1
btfsc STATUS, Z ;If SWITCH = CASE2, jump to LABEL2
goto Fast
xorlw case3^case2
btfsc STATUS, Z ;If SWITCH = CASE3, jump to LABEL3
goto LOOP
goto LOOP
end
It's the second line in loop under Main's LOOP. I also found a RNG, but that is not working either.
What do the operands do with BTFSC RANDOM,4? I thought that it would shift RANDOM by 4 places? When I simulate the lines that have BTFSC, they do nothing to the RANDOM register. (Edit - I will have to watch these registers in binary - apparently bit 4 is checked for zero). When it gets to the ANDLW line, it just tests boolean, if the number is not equal, a zero value is then loaded into W register. It looks like I need to find different code to accomplish what you were talking about (AND 0x03).
Thanks in advance for looking and helping.
Not all Harald, you have been a huge help and suggested an excellent solution, I have just failed to implement it properly or have made some other novice mistake. Your help is much appreciated and thank you!I'm sorry that what little I managed to find out doesn't help.
The only thing hat might have an influence is the notaton 0x03 for the number 3.
Hi John
Can we have a quick re-cap on where you are now. I have tried to pick up this thread but I am struggling. It looks like you are trying to create a random number by ANDing something together? The btfsc tests bit 4 of the register and if zero jumps over the next instruction in the code. Is that what you wanted to know?
cheers
Adam
And that is what it does. ANDing two binary values in this contect means the boolean AND between the corresponding bits (bitwise AND):Edit - I watched with ANDLW 0x03. What I saw was, b'00000100' (decimal 4, h0x04) was passed to W, when passed to next line ANDLW 0x03 the value of W changed from b'00000100' to b'00000000'. According to the datasheet, the ANDLW was supposed to AND the contents of W with the 'k' literal which in this case is 0x03 and then place that back in W.
0000 0011 AND
|||| ||||
0001 0000 =
-------------------
0000 0000
Adam, there are actually two tasks:It looks like you are trying to create a random number by ANDing something together?
I think the issue is John's misunderstanding of the AND operation, which I tried to clarify above.
but what if John uses module 4 instead? This operation is a simple AND 0x03, fast and small.
The result is a number between 0...3,
AND is not MOD, right, but in this special case AND 0x03 is equivalent to MOD 4!Yes, I am understanding now that it is operating as a boolean evaluation, but I was expecting a modulo function!
The issue then is not the reduction of the random number to a number between 0...n, but the lack of randomness in the input integer. The cure is to use a "better" pseudo random number generator (books have been written on that topic).Zero is the likely outcome since most will not be true after being AND'ed. I really need more of a modulo function for this to work as written or come up with a new routine.
Adam, there are actually two tasks:
- Generate a random number. One idea was to grab the count from a free running timer.
- Depending on the random number perform one out of three subroutine.
#2 John tried to do by computing Random MOD 3 which would give him an integer between 0....2.
As John is very limited in memory (sorry, not John himself, his PIC ) I suggested he use Random AND 0x03 instead, which would give him a number 0...3. By discarding one of the 4 possible results (discard it, get a new Random number, try again until the result is one of the 3 legal results) this would have the same effect at less memory and runtime requirements.
As I showed in my post #10, by making RAndom==3 the illegal case, one can even minimize the code further.
I think the issue is John's misunderstanding of the AND operation, which I tried to clarify above.
Yes, I am understanding now that it is operating as a boolean evaluation, but I was expecting a modulo function!
The above is why I thought that. The current code checks for 0,1,2,3 however the frequency of those numbers appearing is going to be very low since we are starting with an 8 bit number! Zero is the likely outcome since most will not be true after being AND'ed. I really need more of a modulo function for this to work as written or come up with a new routine.
That's what AND 0x03 is supposed to do.Could you not mask the upper bits to get rid of them?
Input AND 0x03
0 0
1 1
2 2
3 3
4 0
5 1
6 2
7 3
8 0
9 1
10 2
11 3
12 0
13 1
14 2
15 3
16 0
237 1
50 2
58 2
224 0
16 0
131 3
166 2
88 0
135 3
174 2
34 2
136 0
93 1
53 1
24 0
47 3
234 2
205 1
42 2
167 3
133 1
186 2
147 3
205 1
192 0
24 0
120 0
Oh boy - I just verified that... I did not use enough examples to verify my previous observation, my apologies! I was reading the datasheet and remembered seeing that the AND performed a boolean function, but it was the ANDWF not the ANDLW and that certainly makes a difference.AND is not MOD, right, but in this special case AND 0x03 is equivalent to MOD 4!
Agreed completely. I am thinking of changing the TMR0 into a counter instead, such that it produces a running number that increments with the clock cycle. That should give me more random numbers. As a timer, it is giving me a static startup value. In simulation it seems to like the value of 5 consistently and therefore when its fed through the small RNG section of code, it gives the same net result.The issue then is not the reduction of the random number to a number between 0...n, but the lack of randomness in the input integer. The cure is to use a "better" pseudo random number generator (books have been written on that topic).
I had implicitly assumed that you had the timer running this way all time long. Of course, if the timer isn't running, it can't generate any number even less random ones. Make sure it runs really fast to avoid reading the same number again and again.Agreed completely. I am thinking of changing the TMR0 into a counter instead, such that it produces a running number that increments with the clock cycle.