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.

counter problem

Status
Not open for further replies.

josi

New Member
hi! i'm trying build a counter using a pic 16f877, the counter shoul only start when a switch connected to PORTA is pressed! and the counter must stop when the switch is released. so far i can make the pic count but the swicth is not working. can anybody tell me what wrong with my code? thanx.

;*****Configuration****************************************

LIST p=16F877
#include <P16F877.inc>
__config _XT_OSC & _PWRTE_ON & _WDT_OFF &_LVP_OFF
;*****Equates**********************************************
status equ 03h
PortA equ 05h
PortD equ 08h
TRISA equ 85h
TRISD equ 88h
count0 equ 25h
count1 equ 26h
count2 equ 27h
;******Main Program****************************************
org 10h
bsf status,RP0
movlw B'11111111' ; set portA as input
movwf TRISA
movlw B'00000000' ; set PortD as outpout
movwf TRISD
bcf status,RP0

start
btfss PortA,0 ; test if portA bit 0 is set
goto start ; if bot 0 cleared goto start
incf PortD ; if bit 0 se inc portD
call delay
goto start ;do same thing

delay
movlw 05h ;SET DELAY FOR 1 SEC
Movwf count2

Loop
decfsz count0,1

Goto Loop

Decfsz count1,1

Goto Loop

Decfsz count2,1

Goto Loop

Return
end
 
Do you have a pull-up resistor on the I/O pin?, also you need to disable the analogue inputs - check my tutorials.
Thnax nigel! i saw yor tutorials on analog inputs () but i'm still quit confused! can u please tell me exactly wich register (bit) i need to clear or set in order to disable the analog inputs? thanx
 
You need to put 6 into ADCON1 whilst in bank 1.

I.E.
Code:
	org	10h 
	bsf	status,RP0
	movlw	B'11111111'	; set portA as input
	movwf	TRISA
	movlw	B'00000000'	; set PortD as outpout
	movwf	TRISD
[COLOR="Blue"]	movlw	6
	movwf	ADCON1[/COLOR]
	bcf	status,RP0

Mike.
 
Thanx mike! it's working now! can u please show me how to tst two bits simultaneously? let say i want to test RA0 and RA1 at the same time and do sthing if they both set! how would i do it?
 
Thanx mike! it's working now! can u please show me how to tst two bits simultaneously? let say i want to test RA0 and RA1 at the same time and do sthing if they both set! how would i do it?

Read the complete port and AND with the required bits (as you have to for single bit testing on most processors), or test each bit in turn.
 
Will a code like this work??

Code:
	movlw	b'11'
	xorwf	PORTA,W
	btfss	STATUS,Z
	goto	Both_notset
	goto	Both_set

But need to careful with other remaining bits of PORTA or need to mask them.
 
Last edited:
help needed

Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0

decfsz count1 ,f
goto d1
retlw 0x00

Hi Nigel , i went through tutorial 1.3 which has this delay_0 loop that i quite don't understand . what is $ + 2 ! and what is it doing in the program ?
 
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0

decfsz count1 ,f
goto d1
retlw 0x00

Hi Nigel , i went through tutorial 1.3 which has this delay_0 loop that i quite don't understand . what is $ + 2 ! and what is it doing in the program ?

$ is the current address, so it jumps forward two words - it's explained in the MPASM/MPLAB helpfile.
 
To check if two pins are high you can simply do two checks,
Code:
WaitBoth	btfss	PortA,0		; test if portA bit 0 is set
		goto	WaitBoth	; if bit 0 cleared then wait
		btfss	PortA,3		; test if portA bit 3 is set
		goto	WaitBoth	; if bit 3 cleared then wait

; it will only get to here if both PortA,0 and PortA,3 are both high

You can also AND the port,
Code:
WaitBoth	movfw	PortA		;get value on port a
		andlw	b'00001001'	;keep bits 3 and 0
		sublw	b'00001001'	;sub bits 3 and 0
		btfss	STATUS,Z	;will only be zero if both set
		goto	WaitBoth	;if not, wait

; it will only get to here if both PortA,0 and PortA,3 are both high

The first version is shorter and (maybe) easier to understand. The second version will be more versatile when you need to do more complex things or check 3 bits etc.

Please don't get into the habit of using goto $+n, it makes code so unreadable and will be frowned upon by any experienced programmer or lecturer. It takes 2 seconds to type a label and the code then becomes much clearer. You will see it in code that is generated by a code generator and this is OK as there is no (easy) way around it.

Mike.
 
To check if two pins are high you can simply do two checks,
Code:
WaitBoth	btfss	PortA,0		; test if portA bit 0 is set
		goto	WaitBoth	; if bit 0 cleared then wait
		btfss	PortA,3		; test if portA bit 3 is set
		goto	WaitBoth	; if bit 3 cleared then wait

; it will only get to here if both PortA,0 and PortA,3 are both high

You can also AND the port,
Code:
WaitBoth	movfw	PortA		;get value on port a
		andlw	b'00001001'	;keep bits 3 and 0
		sublw	b'00001001'	;sub bits 3 and 0
		btfss	STATUS,Z	;will only be zero if both set
		goto	WaitBoth	;if not, wait

; it will only get to here if both PortA,0 and PortA,3 are both high

The first version is shorter and (maybe) easier to understand. The second version will be more versatile when you need to do more complex things or check 3 bits etc.

Do you need the "sublw b'00001001'"?, doesn't just the ANDLW set the Z flag anyway?.

Please don't get into the habit of using goto $+n, it makes code so unreadable and will be frowned upon by any experienced programmer or lecturer. It takes 2 seconds to type a label and the code then becomes much clearer.

I would disagree entirely - the reason for using it is so you don't need lots of unique pointless labels - although such jumps should only be small, as in the example. I really don't see how it's any less readable either?.
 
Do you need the "sublw b'00001001'"?, doesn't just the ANDLW set the Z flag anyway?.
If we were testing for both being zero then yes, the subtract wouldn't be needed. However, we are testing for both being set.
I would disagree entirely - the reason for using it is so you don't need lots of unique pointless labels - although such jumps should only be small, as in the example. I really don't see how it's any less readable either?.
There are no pointless labels. I spend 10 times longer thinking about code than writing it and therefore I want what I write to be as legible as possible. Saving 2 seconds by typing $+2 is a false economy and will come back to bite you. Look at the questions above, they wouldn't be here had it said goto DelayJump instead of goto $+2.

Mike.
 
Last edited:
If we were testing for both being zero then yes, the subtract wouldn't be needed. However, we are testing for both being set.

Thabnks for that :D

There are no pointless labels. I spend 10 times longer thinking about code than writing it and therefore I want what I write to be as legible as possible. Saving 2 seconds by typing $+2 is a false economy and will come back to bite you. Look at the questions above, they wouldn't be here had it said goto DelayJump instead of goto $+2.

It's not a question of saving typing time, it's a question of not having loads of labels - such as DelayJump1, DelayJump2 etc.
 
It's not a question of saving typing time, it's a question of not having loads of labels - such as DelayJump1, DelayJump2 etc.

There is nothing wrong with lots of labels, it makes code more readable. How else do you explain the questions above which I believe would not have been asked had labels been used in the code. How is goto $+2 acceptable but bsf 3,2 isn't? We need intimate knowledge of the processor to interpret either.

Mike.
 
There is nothing wrong with lots of labels, it makes code more readable. How else do you explain the questions above which I believe would not have been asked had labels been used in the code. How is goto $+2 acceptable but bsf 3,2 isn't? We need intimate knowledge of the processor to interpret either.

You need no knowledge of the processor for goto $+2, just knowledge of a design feature of the assembler (it's an assembler function not a processor one).

The question was asked only because he hadn't read the assembler instructions.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top