8051的位寻址 ERROR C146
扫描二维码
随时随地手机看文章
SFR定义:
sfr P5 = 0x85; /* PORT 5 */
位寻址定义:
sbit st_rs = P5^0;
编译错误:
*** ERROR C146 IN LINE 320 OF C8051F020.H: 'P5' invalid base address
KEIL FAQ:( http://www.keil.com/support/docs/1916.htm )
*QUESTION :
When I compile my program, I receive the following error message:
Error 146: Invalid Base Address
How do I fix this?
*ANSWER :
This error message indicates that the byte base address specified for an SBIT is not valid. The byte address of an SBIT must be an SFR whose least
significant nibble must be 0 or 8. For example:
sfr P1 = 0x90;
sbit P1_0 = P1^0; // This is valid
sfr P4 = 0xD1;
sbit P4_0 = P4^0; // This is NOT valid since P4 is not an a 0 or 8 boundary
For SFR addresses that are not bit-addressable, you might use standard AND and OR operations to access the indivitual SFR bits.
Example:
sfr P4 = 0xD1;
void test (void) {
if (P4 & 0x01) { // if bit 0 set
P4 |= 0x80; // set bit 7
}
else {
P4 &= ~0x02; // reset bit 1
}
}
原因:
( http://www.keil.com/forum/docs/thread7997.asp )
Non-8 divisible port addresses are not bit assignable. What genious decided that would be a good idea?
Goes all the way back to the original 8051 architecture decisions at Intel.
Bit instructions take one byte of address. Notice that there are 0x10 bytes of bit-addressable memory. The other addressable bits are in SFRs. You can
practically see the hardware guys tapping off the high bit in their address decoder. 0 -> RAM, 1 -> SFR.
Then, you have to decode the next 7 bits to an actual SFR. It's very simple to take bits 6:3 as the SFR address, and use bits 2:0 to select the
individual bit from that byte. That means the bits appear in every eighth SFR address, which is to say the addresses ending in 0 or 8.
Really simple circuit, even at the expense of strangeness at the software level. That's classic Intel design philosophy for you. Save gates where you can
and let the programmers deal with it.
解读:
在SFR空间地址只有可被8整除的寄存器才可以进行位寻址。
位寻址指令代码使用一个字节表示,bit7= 1:片内RAM,0:SFR,bit6~bit3= SFR寄存器地址,bit2~bit0=寄存器内的位地址。
SFR空间内只有16个寄存器是可以位寻址的,其它寄存器的位操作只能用(与)、(或)来操作。