Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

16F84A - output turns off during read?

Status
Not open for further replies.

ehud42

Newbie level 4
Newbie level 4
Joined
Oct 23, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Winnipeg, MB
Activity points
1,340
Ok, this has me a bit confused. I am using an older 16F84A 'cause it's free :) and I don't mind learning things the hard way....

I have an interrupt handler that counts up/down in response to a rise on RB0, and reads RB1 to determine whether to increment or decrement the count. In the handler I increase/decrease the count and output 4 bits to RB4-7. This code 'works' in MPLAB (v8.60), in that the state of the output pins RB4-7 stay as set until changed by the routine, however, when I update the actual chip, the output pins only pulse when the RB0 is pulsed.

It seems that responding to RB0 and/or reading RB1 is causing the outputs to reset.

Is this true?

To make sure the PIC is running, I also have a 'heartbeat' monitor that every 255 times the TMR0 interrupt fires a pin is toggled (LED is turned on or off).

Code:
		LIST	P=16F84A
		INCLUDE	<p16f84a.inc>

		__CONFIG _PWRTE_ON & _CP_OFF & _WDT_OFF & _RC_OSC

		ERRORLEVEL 1
		RADIX DEC

		cblock	0x0c
		cstep			;current step index
		istep			;invert current step index
		nopcnt			;something to do
		save_w			;W register
		save_status		;status bits
		endc

#define	f_ledon	flag,0	; it is 1 if LED is ON

;start program at memory location zero
		org	0

;fill memory spots 0-3 w/ house keeping and goto real start
		clrf	TMR0
		clrf	PORTB
		clrf	PORTB
		goto	begin

;0004h - Interupt memory location - this is a 'goto int routine'
		goto	inter

;MAIN PROGRAM
begin

;porta not used
		movlw	0xff
		banksel	TRISA
		movwf	TRISA

;portb pin 0,1 input, rest output
		movlw	0x03	;0000 0011
		banksel	TRISB
		movwf	TRISB

		movlw	B'10000000'
		banksel	PORTB
		clrf	PORTB
		iorwf	PORTB

;OPTION register bits
;B7 - !RBPU - internal pull-up resitors on port B are disabled
;B6 - INTEDG - external interrupt in on rising edge (0 to 1 transition)
;B5 - RTS - instruction clock is from internal oscillator
;B4 - RTE - RA4 rise/fall select (if RTS = 1)
;B3 - PSA - prescaler is assigned to timer 0
;B2,B1,B0 - PS2,1,0 - set to zero for faster resets.
; for clarity the value is specified in binary notation
		movlw	B'11001001'	
		banksel	OPTION_REG
		movwf	OPTION_REG
		banksel	0
	
; now we go back to bank 0 of RAM, where we have our variables	
		bcf	STATUS,RP0	
; we clear some variables, as needed 
		clrf	cstep			;current step index
		clrf	nopcnt			;no op counter. just give the CPU something to do

; now we enable the interrupts, setting three bits in the INTCON register
; they are the external interrupt enable (INTE), the timer 0 interrupt
; enable (T0IE) and the general interrupt enable (GIE)
; to be shorter we do it loading a single value in INTCON		
		movlw	B'10110000'	
		movwf	INTCON

;initialization complete - begin main loop
loop	;incf	TMR0
		goto	loop

; here is the interrupt service routine! all things will happen here 
; first of all we MUST save the current STATUS and W registers
; the istruction MOVF must be avoided, because in alters the status!
inter	movwf	save_w	 		
		swapf	STATUS,W
		movwf	save_status
; since there are two possibile interupt source in this program, 
; first of all we must know who generated this interrupt;
; if it was the step pulse, we jump to its routine	
		btfss	INTCON,T0IF
		goto	stepin

; we're here because of the timer
; we clear the timer interrupt flag, to enable it for the next time	
		bcf		INTCON,T0IF
; if hearbeat = 0 (rolled around the byte cycle) toggle LED (RB3)
		incfsz	nopcnt
		goto	endint

		movlw	B'00001000'		; mask for bit 3
		banksel	PORTB
		xorwf	PORTB			; toggle PORTA,bit3 (toggle the led)
		banksel	0
		goto	endint

;step in time! - disable further stepin interrupts?
stepin	bcf		INTCON,INTE
		bcf		INTCON,INTF	;clear RB0 int flag

;test dir flag - RB1, if 1 go forward, 0 go backward
		btfss	PORTB, 1	;skip goto if set
		goto	bckup

		incf	cstep		; add 1
		goto	mod8

bckup	decf	cstep		; subtract 1
mod8	movlw	B'00000111'	; setup bitmap for AND
		andwf	cstep		; bitwise AND with 7 to mod8

;convert cstep into output bits (stpdec)
;output bits on PORTB
		movfw	cstep
		call	stpdec
		banksel	PORTB
		movwf	PORTB
		banksel	0

;restore step toggle interrupt
		bsf		INTCON,INTE

; this is the common end for the two interrupt routines
; we restore the STATUS and W registers, then we end the interrupt
endint	swapf	save_status,w 		
		movwf	STATUS 
		swapf	save_w,f
		swapf	save_w,w
		retfie

;===========================
;Next step
; 8 steps of the motor (0-7)
stpdec	addwf	PCL, f
		retlw	B'10000000'
		retlw	B'11000000'
		retlw	B'01000000'
		retlw	B'01100000'
		retlw	B'00100000'
		retlw	B'00110000'
		retlw	B'00010000'
		retlw	B'10010000'
		
		end
 

Hi,
I am no expert but I can't see any delay routines and would expect the outputs to change too fast to be seen. I just forget but think it is 1/4 of the clock frequency.
Toggling Bit0 would probably show a quick blip maybe.
Worth trying some delays?
Hope that is of some help.
Best regards,

Dejayc.
 

Well, my problems are getting even stranger. I am suspecting I have a defective chip. If I create a simple program that outputs a pattern (add 1 to the PORTB every 255*255 instructions), I get a nice pattern outputing on the pins. If I replace the counter in the loop with some simple logic to increment the PORTB outputs on any change on PORTA (MOVFW PORTA, XORWF oldA, test Zero bit, etc), then I get either no change on PORTB, or worse, the output is not the programmed pattern, but rather a mirror/copy of the input stimulus on a pin. (Probe RA1, RB1 flashes in sync).

Again, the program 'works' in the lab/simulator, but acts weird in real life.

Do I have a bad chip?
 

Probably not!

I have not simulated it (except in my mind, so immediately be suspicious !) but two things may be causing your problem, firstly, did you intend to re-load a value into TMR0 or just let it keep rolling over every 256 counts and secondly, you might be seeing RMW effects. A Quick check for RMW would be to add a NOP instruction before any reads on the ports. 16F series devices write and read all the port bits in one go, even if you are only setting or reading a single bit. Sometimes stored charge on the pin and connected circuits can cause false logic levels to be read. A short delay, such as the NOP will often be enough to ensure the levels have settled before reading them.

Brian.
 

you might be seeing RMW effects

RMW makes some sense to me if I'm reading and then writing to the same port (which I am in the original code sample), however, even in a simple test program where I read from PortA and write to PortB I witness this pulsing phenomenon.

I'm probably going order some more PICs (I only have the one 16F84A to play with) to see if it is just the PIC or possibly my code.
 

I suggest ordering 16F628A instead of 16F84A. They are pin compatible, almost code compatible and best of all, they cost less !!
Their extra on-board peripherals are worth their weight in gold.

Brian.
 

Hi ehud42,
What I think is, it is due to read-modify-write problem as betwix suggested. 16F628A is an enhanced version of the 16F84A and as mentioned, it may be wiser to use that. 16F84A is a very old microcontroller and it's also quite expensive. Newer enhanced variants, you will see, tend to be cheaper.

Hope this helps.
Tahmid.
 

I'm not sure I have the funds to purchase all new infrastructure (this is just a sparetime hobby for me). I have downloaded MPLAB to compile and test my code, however, I am programming the 16F84A with an old serial PIC START 16B1.

Is the 16F628A pin compatible enough that the PIC START 16B1 will program it?
 

Check on the "Device support" section MPLAB, it is at "C:/Program Files/Microchip/MPLAB IDE/Readmes/Device Support.htm" if you have a standard install on Windows.
It looks like it will work. The real difference is in the programming algorithm rather than the pin outs.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top