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.

btfsc PORTA, PIN_I trouble

Status
Not open for further replies.

nandrei

Newbie level 4
Joined
Jan 17, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Romania
Activity points
1,357
Hello,

I'm trying to make sort of a pocket calculator using pic16f84a. Right now i got to the stage of using buttons (ra0 --- ra3) and trying to output to PORTB. Later i will use a display

I want to bit-check every pins ra3, ra2, ra1 in this order so that pressing ra3+ra1 = 5 (an operand for my addition) so i want to rotate right PIN_I with every loop :

basic ideea of the code:
PIN_I equ 0Eh
....
begining movlw 0x04
movwf PIN_I
...
btfsc PORTA, PIN_I ; <<<<<<<<<<<<< compiled and simulated the value of PIN_I doesn't change ; with every loop (in gpsim i get a constant)
rrf PIN_I, 1
btfss STATUS, 0
....
goto begining

the compiler gives me this warning
keyboard_leds.asm:63:Warning [202] Argument out of range. Least significant bits used.
(whitch shouldn't bother me, i think, because PIN_I has values 4, 2 or 1)

full source code is attatched.

Thanks, Andrei

Added after 50 seconds:

i can't upload as attatchment, here is the source code

**broken link removed**
 

I *think* the error is PIN_I being defined as 0x0E.

When you use btfsc PORTA,PIN_I it expands to btfsc PORTA,14 (in decimal) which is of course impossible when PORTA only has 5 usable bits.

The warning is telling you it has tried to compile code but discarded any bits outside the valid range.

Wouldn't it be better to use a matrix keypad?

Brian.
 

Hi,

Non of your code actually shows what chip you are using, but assume it is a 16F type.

When you use ' PIN_I equ 0Eh ' it actually places PIN_I at memory location 0x0E which is normally a system register area. Most 16F user registers start much higher.

If you allocate it as a normal user register, then loading in the value 0x04, the idea of rotating it does work.

cblock 0x40 ; - if using a 16F690
PIN_I
endc

If you use the #include pic16Fxxxx statement then there is no need to define your system registers like TRISA etc - assuming you are using Mplab assembler ?

Edit Correction - should be #include pic16fxxxx.inc
 

Incorrect!

The EQU simply creates an alias for the value, it does not reserve or allocate memory.

Brian.
 

Hi,

Well when I tested the code on 18F in Sim the PIN_I label was assigned to 0x0E in the file register window and the 0x04 written into it.

Have just done the same as a 16F chip and it still writes to location 0x0E, but the original TMR1 label is preserved.

Am I missing a point or understanding things wrong.. ?
 

You are misunderstanding, the picture shows what is expected.

It depends on the context you use it in, just imagine for now that whenever you use PIN_I you substitute 0Eh in it's place.

so:
"movwf PIN_I" becomes "movwf 0Eh" which is an instruction that stores the W value in address 0Eh.
and:
"btfsc PORTA, PIN_I" becomes "btfsc PORTA,0eh" which tests bit 0Eh on PORTA.

As PORTA only has bits 0 to 4 and the instruction can only test one bit at a time, it fails. The only numbers allowed in a btfsc instruction are 0 through 7.

The "rrf" instruction you use later is like the movwf one, it expects address as the operand so the contents of address 0Eh are rotated.

Brian.
 

Hi Brian,

You are misunderstanding

Well yes, I can be dim at times ! - and am still missing the point.

I understand the point about addressing the port with the correct number of bits ok.

What I cannot see, or find any reference to, is what determines what the expression value is, a substitution value or a ram address ?


Think this has always been a blank for me, just quoting, verbatim, 3 lines from one book that does show my confused ? point.

thanks,


CNTR EQU 0C ; USER REGISTER ( pic16C71)
STATUS EQU 03 ; EXISTING SYSTEM REGISTER
Z EQU 2 ; ZERO BIT OF STATUS REGISTER
 

Hello everybody, thanks for your posts.
(sorry for neglecting to say that i am using pic16f84a, gpasm assembler and gpsim simulator)

the line "PIN_I equ 0eh" means that the character string "PIN_I" actually means "the number stored at 0Eh location"
after that, i load PIN_I with value 04h or whatever, then
movlw 04h
movwf PIN_I; means that location 0Eh contains the value 04h
(i've seen this in the simulator) and the warning is about the fact that the number 04h is a byte and PORTA is less bits long. It discards the most significant bits, whitch are 0, so i don't care.

To try to make my problem clearer, the standard usage of condition branches is something like
ex: btfsc PORTA, 3 ; this tests bit 3 from PORTA register.

i just want to use a variable instead of "3", so in one loop i have "4", then i'd have "2", "1", when it reaches "0" start again and load the variable with number 4 again.
btfsc PORTA, VAR ; problem is this actually means something like btfsc PORTA, 00000100b (?)

I know from the simulator that my single problem is
btfsc PORTA, PIN_I
if i replace with (for example)
btfsc PORTA, 1
my program works as i want it (i get input from portA and get output to portB)
i just want to test PORTA against a variable number, and i don't know how.

Thanks for your replyes, everyone
 

Hi Nandrei,

Sorry for having given you the wrong info , hopefully we can both learn !

Have never seen or used Gpasm, wondered why you prefer to use it over the more popular Mplab assembler ? - assume it offers some benefits over Mplab .
 

Hi Nandrei

After a bit of help think I can hopefully make things clearer for you.

When you btfss PORTA - it is PORTA that is the instructions File Register and anything following that can only refer to PORTA bits 0 -7 , eg PORTA,2
You cannot use 2 file registers in most instructions.

The EQU statement simply substitutes PIN_I for the number 0Eh.

So when you PORTA, PIN_I it compiles as PORTA,0Eh - which is a totally invalid number.

You are saying that you have put 04h into the file register PIN_I, yes, but translated that means the memory location 0Eh contains 04h , PIN_I still Equates to 0Eh

So afraid , unless anyone can come in with another way, you can only circle around the input pins by addressing them individually - porta,1, porta,2 etc or using EQU as shown in this example.



Code:
KEY_PORT	Equ	PORTB		;keypad port
KEY_TRIS	Equ	TRISB

Col1		Equ	0			;pins used for keypad inputs
Col2		Equ	1
Col3		Equ	2
Col4		Equ	3


          	btfss   KEY_PORT, Col4
           	goto    Press
           	incf    key, f
           	btfss   KEY_PORT, Col3
           	goto    Press
           	incf    key, f
           	btfss   KEY_PORT, Col2
           	goto    Press
           	incf    key, f
           	btfss   KEY_PORT, Col1
           	goto    Press
           	incf    key, f
           	decfsz  rows, f
           	goto    Scan
 

There is an easier way!

Suppose address 0Eh (aka PIN_I) contains 04h,

movf PIN_I,w
andwf PORTA,w

will set or reset the Z flag in the STATUS register depending on whether the bit in PIN_I and the same bit in PORTA are the same. You still have to put a valid bit mask in PIN_I rather than the actual bit number though.

Brian.
 

evrika! (i think :)) )

you've all been very helpfull, Brian's solution is the what i have been looking for. I don't really know how to put that in to code yet, but if i have my varibale PIN_I from 04h to 01h, and substract if from PORTA, at some point i will have Z set. This has to work, i haven't coded it and tested it yet.... maybe that's just the same thing... Anyway, it's like solved.

About btfsc: (From PICmicro mid-range MCU family reference manual)

BTFSC Bit Test, Skip if Clear
[ label ] BTFSC f,b
Syntax:
0 ≤ f ≤ 127
Operands:
0≤b≤7
Operation: skip if (f) = 0
Status Affected: None
Encoding: 01 10bb bfff ffff
Description: If bit 'b' in register 'f' is '0' then the next instruction is skipped.
If bit 'b' is '0' then the next instruction (fetched during the current instruction execu-
tion) is discarded, and a NOP is executed instead, making this a 2 cycle instruction.

So, btfsc and btfss can use only a 3 bit number (as b) ! I tried setting PIN_I to EEh to see if it truncates most significant bits -- it doesn't. it simply can't handle anything else than 3 bits.

PS: i use gpasm because mplab doesn't run on linux. And i'm trying to learn linux also.

Andrei
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top