This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Setting a port bit in ASM

I've tried a variety of methods for storing a bit address in ASM so I can subsequently SET/CLR that bit but have had no luck. Here's the pseudo-code for what I want to do:

1 - Initialize an 8-bit variable (Addr)
in my ASM module with the bit
address (say 0x97), then
2 - SETB Addr or
CLR Addr

If I hard-code an address, say for P1.7, it works fine:

SETB 0x97

Also if I pass in an offset to a base address it works fine:

MOV ACC,R5
SETB 0x90+ACC

Any suggestions for how I can optimize my code so I just have to use #2 above?

Parents
  • Hi,
    First of all, you should probably read somemore about assemly language. Keil assembler does not help you here; there is no indirect-via-address bit access commands --- there is only command SETB bit, where bit is direct the number of a bit in interanl bitfiled or SFR. So you have no ability to set/clr bits with way you indicated. Anyway, you may create a subroutine which does it for you by ANL/ORL commands, something like:

    ; A - number of bit (0x00...0x7F) to be set in bitfield area (0x20...0x2F)
    SUB_SET_BIT:
    	JB	ACC.7,SUB_SET_BIT_END	; error number...
    	MOV 	B,#8
    	DIV	AB			; result: addr/bitnum
    	ADD	A,#0x20
    	MOV	R0,A			; addr for indirect access
    	INC	B
    	CLR	A
    	SETB	C
    SUB_SET_BIT_0:
    	RLC	A			; get bit mask
    	DJNZ	B,SUB_SET_BIT_0
    	ORL	A,@R0			; set bit
    	MOV	@R0,A
    SUB_SET_BIT_END:
    	RET
    
    Unfortunately, it is not possible to access SFRs via indirect mode so if you need for such subroutine for SFRs then you should write 16 ones for each bit-accessible SFR and select them by address table (JMP @A+DPTR, for example).
    Read Keil ASM docs as well.

    As about last example, MOV ACC,R5 and SETB 0x90+ACC it does completely different result: it will set bit 0x2E.0 because
    mod256(0x90+0xE0) = bit number 0x70 that's 0x2E.0 bit.
    Good days!

Reply
  • Hi,
    First of all, you should probably read somemore about assemly language. Keil assembler does not help you here; there is no indirect-via-address bit access commands --- there is only command SETB bit, where bit is direct the number of a bit in interanl bitfiled or SFR. So you have no ability to set/clr bits with way you indicated. Anyway, you may create a subroutine which does it for you by ANL/ORL commands, something like:

    ; A - number of bit (0x00...0x7F) to be set in bitfield area (0x20...0x2F)
    SUB_SET_BIT:
    	JB	ACC.7,SUB_SET_BIT_END	; error number...
    	MOV 	B,#8
    	DIV	AB			; result: addr/bitnum
    	ADD	A,#0x20
    	MOV	R0,A			; addr for indirect access
    	INC	B
    	CLR	A
    	SETB	C
    SUB_SET_BIT_0:
    	RLC	A			; get bit mask
    	DJNZ	B,SUB_SET_BIT_0
    	ORL	A,@R0			; set bit
    	MOV	@R0,A
    SUB_SET_BIT_END:
    	RET
    
    Unfortunately, it is not possible to access SFRs via indirect mode so if you need for such subroutine for SFRs then you should write 16 ones for each bit-accessible SFR and select them by address table (JMP @A+DPTR, for example).
    Read Keil ASM docs as well.

    As about last example, MOV ACC,R5 and SETB 0x90+ACC it does completely different result: it will set bit 0x2E.0 because
    mod256(0x90+0xE0) = bit number 0x70 that's 0x2E.0 bit.
    Good days!

Children