Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Randomness of 16F84 program - sometimes works somtimes doesn

Status
Not open for further replies.

FusionITR

Member
Ok this is EXTREMELY odd, I am making a PIC 16F84A programming, and I have it simulating like I wanting it, but when I load it onto my actually pic and test it, a certain part of the program randomly works correctly and randomly doesnt work correctly.

Here is the code:

Code:
	errorlevel -302		;Suppress bank warning
	__config 3FFAh		; WDT Off, HS Oscillator, CP off

;****************************************************************************
;*  Set Up Varibles                                                         *
;****************************************************************************

STATUS	equ	0x03
TRISA	equ	0x85
TRISB	equ 0x86
PORTA	equ	0x05
PORTB	equ 0x06
COUNT1	equ	0x08
COUNT2	equ 0x09
COUNT3	equ 0x0C
CMDOUT	equ 0x0D
DATAIN	equ 0x0E
BTLOOP	equ 0x0F
BIT		equ 0x10
WTEMP	equ 0x11

;****************************************************************************
;*  Set Up Ports                                                            *
;****************************************************************************


	bsf STATUS,5
	movlw 0x01
	movwf TRISA
							; RA0 - DATA		INPUT
							; RA1 - COMMAND		OUTPUT
							; RA2 - ATT			OUTPUT
							; RA3 - CLOCK		OUTPUT
	movlw 0x00
	movwf TRISB				; Button Outputs
	bcf STATUS,5

;****************************************************************************
;*  Set Initial Conditions                                                  *
;****************************************************************************

	movlw 0x0C
	movwf PORTA
	movlw 0x00
	movwf PORTB

;****************************************************************************
;*   Main Program                                                           *
;****************************************************************************

	call DELAY				; Delay
	bcf PORTA,2				; Bring ATT Low
	call DELAY				; Delay
	movlw 0x01				; Set the command to be sent as 0x01
	movwf CMDOUT			; Move it into variable
	call START				; Send "Start" Command					Byte 1
	call DELAY
	call DELAY
	movlw 0x42				; Set the command to be sent as 0x42
	movwf CMDOUT			; Move into variable
	call REQUESTDATA		; Request Controller Data				Byte 2
	bsf PORTA,2				; Bring ATT High
	movf DATAIN,w
	movwf PORTB

LOOP
	movlw 0x00
	goto LOOP

;****************************************************************************
;*   START - Send 0x01 to Controller                                        *
;****************************************************************************

START
	movlw 0x08				; Set up 8 Clock Cycles
	movwf BTLOOP			;
	movlw 0x01				; Set up Bit Counter
LOOP2
	movwf BIT				; Move Bit
	andwf CMDOUT,w			; Is CMD high?
	skpz					; If not, skip next command
	bsf PORTA,1				; Set CMD bit high
	bcf PORTA,3				; Clock Low
	call DELAY				; Delay
	bsf PORTA,3				; Clock High
	rlf BIT,w				; Shift for next bit
	bcf PORTA,1				; Clear CMD bit
	call DELAY				; Delay
	decfsz BTLOOP
	goto LOOP2

	return

;****************************************************************************
;*   REQUESTDATA - Sending 0x42                                             *
;****************************************************************************

REQUESTDATA
	movlw 0x08				; Set up 8 Clock Cycles
	movwf BTLOOP			;
	movlw 0x00
	movwf DATAIN
	movlw 0x01				; Set up Bit Counter
LOOP3
	movwf BIT				; Move Bit
	andwf CMDOUT,w			; Is CMD high?
	skpz					; If not, skip next command
	bsf PORTA,1				; Set CMD bit high
	bcf PORTA,3				; Clock Low
	rrf PORTA,w				; Read bit from DATA in
	rrf DATAIN,f			; shift bit
	call DELAY				; Delay
	bsf PORTA,3				; Clock High
	rlf BIT,w				; Shift for next bit
	bcf PORTA,1				; Clear CMD bit
	call DELAY				; Delay
	decfsz BTLOOP
	goto LOOP3

	return

;****************************************************************************
;*   Delay Loop 195.84ms (x5 Delay Multiplier)                              *
;****************************************************************************

DELAY
	movwf WTEMP
	movlw 0xFF				; Set Up Delay
	movwf COUNT1
	movlw 0xFF
	movwf COUNT2
	movlw 0x05
	movwf COUNT3
	movf WTEMP,w
LOOP1
	decfsz COUNT1,1			; Decrease Count 1			1us x 255 = 255us
	goto LOOP1				; until Count1 is zero		2us x 255 = 510us
	decfsz COUNT2,1			; Repeat this process		1us x 255 = 255us
	goto LOOP1				; 255 times					2us x 255 = 510us
	decfsz COUNT3,1			; Repeat this process
	goto LOOP1				; 5	times
	return					; Return					(((3us * 255 times) * 255 times) + (3us x 255 times)) * 5

	end

The program is with the START function. During the 8 clock cycles, it is suppose to send 0000 0001 to the controller (RA1 bit is only suppose to go high the first clock cycle) and simulates as such. However when I turn on the pic, sometimes it incorrectly sends 0000 0011 and sometimes it correctly sends 0000 0001. When I turn it off and turn it on, it incorrectly sends it about 70% of the time and sends it right 30% of the time. Every other part of the program works, its just that part that is random.

It simulates just fine, so I dont have a clue on what could be going wrong. I'm sure my pic is hooked up correctly since everything else works fine and Ive never had this problem with any other programs ive made.

And I'm sure there isnt anything wrong with the actual PIC itself since i've tested this on multiple (brand new) PICs with the same result.
 
Re: Randomness of 16F84 program - sometimes works somtimes d

FusionITR said:
It simulates just fine, so I dont have a clue on what could be going wrong.

It happens to a lot of people using 16 series PIC. Ever heard of Read-Modify-Write limitation regarding port pins?

Consecutive BSF, BCF, BTFSS, BTFSC, RRF, RLF and other commands on port direct will absolutely be asking for troubles. The first instruction changes port pin(s) status, but pin(s) level take time to change if there are capacitance connected to it. When the second instruction read the pin status, the wrong status will be read.

Solution: Use a port shadow register or insert several NOPs between port change instructions.
 
Hi,
The one thing I could see is (in addition to the port problems) is that you have not defined the start pointer at the reset vector address, or the other interrupt vectors.

It might not mean anything here, but its always a good practice to define startingpoints/ vectors.

TOK ;)
 
Never hear of the Read-Modify-Write limitation, do you mind pointing me to any documents/articles relate to it?

Also, what is port shadowing? And do you mean put a few NOP each time I change a bit? Reguardless weather that bit is input/output?
 
While the RMW (read/modify/write) instructions can cause a problem, this is not your problem here. The problem you are seeing is due to the random nature of hardware when it is first turned on. Some of the RAM and SFRs are initialised into known states, such as the ports being set to input, the rest are random. Simulators, tend to set everything up and so produce the same result each time.

Your problem is caused by 1 bit that is setup randomly - the carry bit. If at the top of your code, you add bsf STATUS,C then you will see that after the rlf BIT,w that W now contains 3, not 1 as you expected, because the carry bit has been shifted into bit zero.

So, the easy fix is to add clrf STATUS at the top of your code.

I would add, that your code is not very easy to follow. Take note of some of the suggestions above like putting an org at the start of your code. Your START routine, uses w to keep track of the bit even though you have a variable called BIT. Go back and have a look at the code MIKE,K8LH posted, it's much cleaner.

HTH

Mike.
 
Thanks for the suggestion.

However, I put a clrf STATUS right after I set up the variables, and the randomness still occurs.
 
FusionITR said:
Thanks for the suggestion.

However, I put a clrf STATUS right after I set up the variables, and the randomness still occurs.


Instead, can you insert this.
Code:
START 
   movlw 0x08            ; Set up 8 Clock Cycles 
   movwf BTLOOP         ; 
   movlw 0x01            ; Set up Bit Counter 
LOOP2 
   movwf BIT            ; Move Bit 
   andwf CMDOUT,w         ; Is CMD high? 
   skpz               ; If not, skip next command 
   bsf PORTA,1            ; Set CMD bit high 
   bcf PORTA,3            ; Clock Low 
   call DELAY            ; Delay 
   bsf PORTA,3            ; Clock High 
   bcf STATUS,C     ; <<<<<<<<<<<<<<<<<<< inserted line.
   rlf BIT,w            ; Shift for next bit 
   bcf PORTA,1            ; Clear CMD bit 
   call DELAY            ; Delay 
   decfsz BTLOOP 
   goto LOOP2 

   return

As this is what is causing your problem.

HTH

Mike.
 
FusionITR said:
Never hear of the Read-Modify-Write limitation, do you mind pointing me to any documents/articles relate to it?

Also, what is port shadowing? And do you mean put a few NOP each time I change a bit? Reguardless weather that bit is input/output?

I'm glad that your problem is solved. But the issue of Read-Modify-Write might come back to haunt you, when you are least expected. You can type that phase in Google and get lot of hits.

It was mentioned in the 16F84 datasheet but got deleted in the 16F84A datasheet so you might not have seen it. Why it is deleted I have no clue because the problem is still there. The insertion of NOPs is to give time for the pin to attain the correct logic level and depends on what is connected to the pin.

A test by one user in the Microchip forum using just a 0.1uF capacitor on a port pin reveals it could take 10us or more for the pin level to match with the port latch. Within this time, there can be many PIC instructions and any read port instruction would return the wrong logic level.

Port shadowing is to set aside a register to store the port bit and we change the bit value of the shadow register instead. After we made the change, the register value can be outputted to the port.
 

Attachments

  • rmw.gif
    rmw.gif
    38.2 KB · Views: 506
eblc1388 said:
FusionITR said:
Never hear of the Read-Modify-Write limitation, do you mind pointing me to any documents/articles relate to it?

Also, what is port shadowing? And do you mean put a few NOP each time I change a bit? Reguardless weather that bit is input/output?

I'm glad that your problem is solved. But the issue of Read-Modify-Write might come back to haunt you, when you are least expected. You can type that phase in Google and get lot of hits.

It was mentioned in the 16F84 datasheet but got deleted in the 16F84A datasheet so you might not have seen it. Why it is deleted I have no clue because the problem is still there. The insertion of NOPs is to give time for the pin to attain the correct logic level and depends on what is connected to the pin.

A test by one user in the Microchip forum using just a 0.1uF capacitor on a port pin reveals it could take 10us or more for the pin level to match with the port latch. Within this time, there can be many PIC instructions and any read port instruction would return the wrong logic level.

Port shadowing is to set aside a register to store the port bit and we change the bit value of the shadow register instead. After we made the change, the register value can be outputted to the port.

Thanks for the info.

Would this only matter when doing a bit test on a input pin? Would the solution be put 10 NOP instructions before and after testing a particular bit?
 
FusionITR said:
Would this only matter when doing a bit test on a input pin? Would the solution be put 10 NOP instructions before and after testing a particular bit?

No. Not limited to bit testing as RMW effect is present in all instructions which change the port pin status. So BCF or BSF are also such instructions. The key element is "Sucessive" operation on the "Same" port.

Code:
LOOP2
   movwf BIT            ; Move Bit
   andwf CMDOUT,w         ; Is CMD high?
   skpz               ; If not, skip next command
   bsf PORTA,1            ; Set CMD bit high        <<<<< OK
   bcf PORTA,3            ; Clock Low               <<<<< possible RMW problem

It is difficult to tell whether 10 NOP instructions are sufficient. See the previous post of a 0.1uF capacitor resulting in a 10us port pin level delay. How much time would ten NOPs take?

There is more information in this thread, in the Microchip forum:

**broken link removed**
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top