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.

Stupid code problem

Status
Not open for further replies.

Nrets

New Member
Code:
Main	btfss	GRD_PORT, 1	
		goto	Next
		movlw	b'00000001'
		movwf	GRD_PORT
		call	Delay255
		goto	Main

Next		movlw	b'00000010'
		movwf	GRD_PORT
		call	Delay255
		goto	Main			;loop for ever

I've been having a larger problem with a different program, and am trying to segment it out to figure out what is causing the problem. This segment above should loop switching between between two pins, but this is not the case. Pin 0 goes on, then stays off thereafter, as if the loop had been exited.

Any ideas?
 
Have you turned off the comparators?
Have you made the port digital or is it still analogue?
Have you disabled the WDT?

Posting part of your code normally results in no conclusion because the error often lays elsewhere. Post all your code.

Mike.
 
Code:
	LIST	p=16F628		;tell assembler what chip we are using
	include "P16F628.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3D18			;sets the configuration settings (oscillator type etc.)




		cblock	0x20			;start of general purpose registers
			count			;used in looping routines
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			tmp1			;temporary storage
			tmp2
			p_temp			;save register
			s_temp			;save register
			w_temp			;save register
		endc

SEG_PORT	Equ	PORTB			;7 segment port
SEG_TRIS	Equ	TRISB
GRD_TRIS	Equ	TRISA
GRD_PORT	Equ	PORTA

		movlw	0x07
		movwf	CMCON			;turn comparators off (make it like a 16F84)
		bsf 	STATUS,		RP0	;select bank 1
		movlw	b'00000000'		;Set port data directions, data output
		movwf	SEG_TRIS
		movlw	b'00010000'
		movwf	GRD_TRIS
		bcf 	STATUS,		RP0	;select bank 0
		
Main	btfss	GRD_PORT, 1	
		goto	Next
		movlw	b'00000001'
		movwf	GRD_PORT
		call	Delay255
		goto	Main

Next		movlw	b'00000010'
		movwf	GRD_PORT
		call	Delay255
		goto	Main			;loop for ever


Delay255	movlw	0xff			;delay 255 mS
		goto	d0
Delay100	movlw	d'100'			;delay 100mS
		goto	d0
Delay50		movlw	d'50'			;delay 50mS
		goto	d0
Delay20		movlw	d'20'			;delay 20mS
		goto	d0
Delay5		movlw	0x05			;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7			;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

END

There, that probably will help.

Tris is set to '00010000' for PORTA

It's modified from Nigel's tutorial.
 
Do you have current limiting resistors in series with your LEDs?

Mike.
 
I do. I currently just have an LED hooked up to each of these pins with a single resistor for each.

The pins are normally switching transistors that are grounding 7 segment displays, but they did not seem to be working properly, as in the same digit was appearing on both displays.

I've also noticed that even when the pins are low, they still seem to be lighting up the LEDs, but only dimly, is this normal?
 
Since the snippet is pretty simple, you could just try this:

Code:
Main
		movlw	b'00000001'
		movwf	GRD_PORT
		call	Delay255
		movlw	b'00000010'
		movwf	GRD_PORT
		call	Delay255
		goto	Main			;loop for ever
 
Don't try to read the output pin as if it was an input. Create a shadow register or flag register instead.

I cannot do a bit test on GRD_PORT? I was under the impression that it would see GRD_PORT as whatever bit configuration it is assigned previously, whether they are inputs or outputs.

Should I just assign 1 or 0 to some other variable, and do the test on this variable?

Since the snippet is pretty simple, you could just try this:

Code:
Main
		movlw	b'00000001'
		movwf	GRD_PORT
		call	Delay255
		movlw	b'00000010'
		movwf	GRD_PORT
		call	Delay255
		goto	Main			;loop for ever

For what I need to do, something that simple will not work, unfortunately.
 
Have you tried NOT reading the output port?

I have not tried not reading the port. Or by NOT do you mean btfsc? Because I have tried that. I wasn't actually sure what you meant, haha.

I'm using a flag register instead, and that works, but I still want to know why I can't just use the SEG_PORT register.

Code:
Main	btfss	flag,0
		goto	Next
		movlw	b'00000001'
		movwf	GRD_PORT
		call	Delay255
		bcf		flag,0
		goto	Main

Next		movlw	b'00000010'
		movwf	GRD_PORT
		call	Delay255
		bsf		flag,0
		goto	Main
 
You must be putting too much load on the pin(s). This is why I asked about the resistors. If you increase the value of the resistors it will work correctly.

What value resistors are you using at present?

Mike.
 
Last edited:
You must be putting too much load on the pin(s). This is why I asked about the resistors. If you increase the value of the resistors it will work correctly.

What value resistors are you using at present?

Mike.

They were 500 ohm resistors. I just grabbed something that I knew wouldn't blow the LED, but I wasn't being precise about anything.

My problem now is that there is a 'ghost image' on the 7 segment displays.

For example:
Segment 1 is displaying a 3 brightly, and segment 2 is displaying a 5 brightly, but segment 1 is also displaying a faint 5 and segment 2 is displaying a faint 3.

So I'm guessing it's the same issue I had with the resistors and the LEDs. So each segment is connected to a NPN transistor, and I'm providing a HIGH value from the MCU to the transistor to ground the segments (common anode). So I started increasing the resistance between the MCU pins and the transistors, all the way up to 4K. And although the ghost image fades, so does the bright image. What should I do?
 
Here ya go:
7segment.png
 
You need to turn off the segments before switching the transistor outputs. I'm guessing you switch outputs and then set the segment data or the other way around.

It it still ghosts then you need to post your code.

Mike.
 
You need to turn off the segments before switching the transistor outputs. I'm guessing you switch outputs and then set the segment data or the other way around.

It it still ghosts then you need to post your code.

Mike.

Don't think that is the issue. The segments are switched via the transistors before the new data is moved to the displays:

Code:
INT
		movwf	w_temp		; Save W register
		swapf	STATUS,W	; Swap status to be saved into W
		movwf	s_temp		; Save STATUS register
		movfw	PCLATH
		movwf	p_temp		; Save PCLATH 
	
		btfss	PIR1,TMR2IF	; Flag set if TMR2 interrupt
		goto	INTX		; Jump if not timed out

		; Timer (TMR2) timeout every 1 milli second
	

		bcf	PIR1,TMR2IF	; Clear the calling flag


		btfss	flag, 0	;check which LED was last
		goto	Do_tens
		movlw	b'00000001'
		movwf	GRD_PORT
		movf	ones,w
		;andlw	0x0F		;make sure in range of table
		call	LED_Table
		movwf	SEG_PORT
		bcf		flag,0
		goto	INTX

Do_tens		
		movlw	b'00000010'
		movwf	GRD_PORT
		movf	tens,w
		andlw	0x0F		;make sure in range of table
		call	LED_Table
		movwf	SEG_PORT
		bsf		flag,0




INTX
		movfw	p_temp
		movwf	PCLATH		; Restore PCLATH
		swapf	s_temp,W
		movwf	STATUS		; Restore STATUS register - restores bank
		swapf	w_temp,F
		swapf	w_temp,W	; Restore W register
 
Don't think that is the issue. The segments are switched via the transistors before the new data is moved to the displays:

That's excatly the problem. Like Pommie said, you must turn segments off before switching digits.

Imagine it, old segment info is active, you switch digit, the second digit gets this old data, then you change segment data and only now second digit gets this new data.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top