Hi! I hope you can help me with this. I have a 8051 C146 Error in the uvision keil compiler inside Silicon labs IDE. The error is *** ERROR C146 IN LINE 320 OF C8051F020.H: 'P4' invalid base address The line of code giving the error is: sbit InputTrayCoverSen =P4^0; I think I have the P74Out setup right and P4 is 0x84. It is almost like Port 4 oesn't even exist or get recognized by the assembler. I have looked through your support webages and cannot even find this error C146 is not invalid base address. C166 is. I'm a bit confused. The entire code segments and setups are below: Many Thanks if you can help with this problem in any way! Richard Howes Continuing Engineering Manager 702-358-5714 /*--------------------------------------------------------------------------- ; ; ; ; ; FILE NAME : C8051F020.H ; TARGET MCUs : C8051F020, 'F021, 'F022, 'F023 ; DESCRIPTION : Register/bit definitions for the C8051F02x product family. ; ; REVISION 1.1 ; ;---------------------------------------------------------------------------*/ #ifndef __REGISTERS #define __REGISTERS /* BYTE Registers */ sfr P0 = 0x80; /* PORT 0 */ sfr SP = 0x81; /* STACK POINTER */ sfr DPL = 0x82; /* DATA POINTER - LOW BYTE */ sfr DPH = 0x83; /* DATA POINTER - HIGH BYTE */ sfr P4 = 0x84; /* PORT 4 */ sfr P5 = 0x85; /* PORT 5 */ sfr P6 = 0x86; /* PORT 6 */ sfr PCON = 0x87; /* POWER CONTROL */ sfr TCON = 0x88; /* TIMER CONTROL */ sfr TMOD = 0x89; /* TIMER MODE */ sfr TL0 = 0x8A; /* TIMER 0 - LOW BYTE */ sfr TL1 = 0x8B; /* TIMER 1 - LOW BYTE */ sfr TH0 = 0x8C; /* TIMER 0 - HIGH BYTE */ sfr TH1 = 0x8D; /* TIMER 1 - HIGH BYTE */ sfr CKCON = 0x8E; /* CLOCK CONTROL */ sfr PSCTL = 0x8F; /* PROGRAM STORE R/W CONTROL */ sfr P1 = 0x90; /* PORT 1 */ sfr TMR3CN = 0x91; /* TIMER 3 CONTROL */ sfr TMR3RLL = 0x92; /* TIMER 3 RELOAD REGISTER - LOW BYTE */ sfr TMR3RLH = 0x93; /* TIMER 3 RELOAD REGISTER - HIGH BYTE */ sfr TMR3L = 0x94; /* TIMER 3 - LOW BYTE */ sfr TMR3H = 0x95; /* TIMER 3 - HIGH BYTE */ sfr P7 = 0x96; /* PORT 7 */ sfr SCON0 = 0x98; /* SERIAL PORT 0 CONTROL */ sfr SBUF0 = 0x99; /* SERIAL PORT 0 BUFFER */ sfr SPI0CFG = 0x9A; /* SERIAL PERIPHERAL INTERFACE 0 CONFIGURATION */ sfr SPI0DAT = 0x9B; /* SERIAL PERIPHERAL INTERFACE 0 DATA */ sfr ADC1 = 0x9C; /* ADC 1 DATA */ sfr SPI0CKR = 0x9D; /* SERIAL PERIPHERAL INTERFACE 0 CLOCK RATE CONTROL */ sfr CPT0CN = 0x9E; /* COMPARATOR 0 CONTROL */ sfr CPT1CN = 0x9F; /* COMPARATOR 1 CONTROL */ sfr P2 = 0xA0; /* PORT 2 */ sfr EMI0TC = 0xA1; /* EMIF TIMING CONTROL */ sfr EMI0CF = 0xA3; /* EXTERNAL MEMORY INTERFACE (EMIF) CONFIGURATION */ sfr P0MDOUT = 0xA4; /* PORT 0 OUTPUT MODE CONFIGURATION */ sfr P1MDOUT = 0xA5; /* PORT 1 OUTPUT MODE CONFIGURATION */ sfr P2MDOUT = 0xA6; /* PORT 2 OUTPUT MODE CONFIGURATION */ sfr P3MDOUT = 0xA7; /* PORT 3 OUTPUT MODE CONFIGURATION */ sfr IE = 0xA8; /* INTERRUPT ENABLE */ sfr SADDR0 = 0xA9; /* SERIAL PORT 0 SLAVE ADDRESS */ sfr ADC1CN = 0xAA; /* ADC 1 CONTROL */ sfr ADC1CF = 0xAB; /* ADC 1 ANALOG MUX CONFIGURATION */ sfr AMX1SL = 0xAC; /* ADC 1 ANALOG MUX CHANNEL SELECT */ sfr P3IF = 0xAD; /* PORT 3 EXTERNAL INTERRUPT FLAGS */ sfr SADEN1 = 0xAE; /* SERIAL PORT 1 SLAVE ADDRESS MASK */ sfr EMI0CN = 0xAF; /* EXTERNAL MEMORY INTERFACE CONTROL */ sfr P3 = 0xB0; /* PORT
well, how do you propose that the compiler will do something the hardware is incapable of. The SFR address of P4 is 0x84! Erik
Yeah. I got it. I found other people's posts. Non-8 divisible port addresses are not bit assignable. What genious decided that would be a good idea?
What genious decided that would be a good idea? the 'genius' realized that with only 256 bit addresses available there needed to be some prioritizing. Now, a 'genius' at SILabd (naah, that would be Cygnal) could have decided to locate P4 at a bit addressable address in another page, but I will not even attempt to judge whether that would have been advantageois (a page switch vs using an and) Erik
A genius at 'SILabd'/Cygnal could of found a solution that was more 'advantageois'.
such as?
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.
I see. Thanks. I kinda figured that it was the hardware engineers. Too bad they can't/won't update the 8051.
"Too bad they can't/won't update the 8051." Who is "they"? What is "the 8051"? There must be literally hundreds of manufacturers producing literally thousands of chips based on the 8051 architecture: http://www.keil.com/dd/chips/all/8051.htm If you changed the bit-addressing scheme, you would effectively not have an 8051 any more! You would break the compatibility throughout this vast range of products - you would need a whole new toolset!
See also: http://www.keil.com/support/docs/1916.htm
It would be helpful if the description of the C146 error message referenced the restriction on bit-addressable SFR addresses: http://www.keil.com/support/man/docs/c51/c51_c146.htm