
- •Chapter 1. Introduction
- •Support for all 8051 Variants
- •Books About the C Language
- •Chapter 2. Compiling with the Cx51 Compiler
- •Environment Variables
- •Running Cx51 from the Command Prompt
- •ERRORLEVEL
- •Cx51 Output Files
- •Control Directives
- •Directive Categories
- •Reference
- •Chapter 3. Language Extensions
- •Keywords
- •Memory Areas
- •Program Memory
- •Internal Data Memory
- •External Data Memory
- •Far Memory
- •Special Function Register Memory
- •Memory Models
- •Small Model
- •Compact Model
- •Large Model
- •Memory Types
- •Explicitly Declared Memory Types
- •Implicit Memory Types
- •Data Types
- •Bit Types
- •Special Function Registers
- •sbit
- •Absolute Variable Location
- •Pointers
- •Generic Pointers
- •Pointer Conversions
- •Abstract Pointers
- •Function Declarations
- •Function Parameters and the Stack
- •Passing Parameters in Registers
- •Function Return Values
- •Specifying the Memory Model for a Function
- •Specifying the Register Bank for a Function
- •Register Bank Access
- •Interrupt Functions
- •Reentrant Functions
- •Chapter 4. Preprocessor
- •Directives
- •Stringize Operator
- •Predefined Macro Constants
- •Chapter 5. 8051 Derivatives
- •Analog Devices MicroConverter B2 Series
- •Atmel 89x8252 and Variants
- •Dallas 80C320, 420, 520, and 530
- •Arithmetic Accelerator
- •Data Pointers
- •Library Routines
- •Philips 8xC750, 8xC751, and 8xC752
- •Philips 80C51MX Architecture
- •Philips and Atmel WM Dual DPTR
- •Customization Files
- •STARTUP.A51
- •INIT.A51
- •XBANKING.A51
- •Basic I/O Functions
- •Memory Allocation Functions
- •Optimizer
- •General Optimizations
- •Options for Code Generation
- •Segment Naming Conventions
- •Data Objects
- •Program Objects
- •Interfacing C Programs to Assembler
- •Function Parameters
- •Parameter Passing in Registers
- •Parameter Passing in Fixed Memory Locations
- •Function Return Values
- •Using the SRC Directive
- •Register Usage
- •Overlaying Segments
- •Example Routines
- •Small Model Example
- •Compact Model Example
- •Large Model Example
- •Data Storage Formats
- •Bit Variables
- •Signed and Unsigned Long Integers
- •Generic and Far Pointers
- •Floating-point Numbers
- •Accessing Absolute Memory Locations
- •Absolute Memory Access Macros
- •Linker Location Controls
- •The _at_ Keyword
- •Debugging
- •Chapter 7. Error Messages
- •Fatal Errors
- •Actions
- •Errors
- •Syntax and Semantic Errors
- •Warnings
- •Chapter 8. Library Reference
- •Intrinsic Routines
- •Library Files
- •Standard Types
- •va_list
- •Absolute Memory Access Macros
- •CBYTE
- •CWORD
- •DBYTE
- •DWORD
- •FARRAY, FCARRAY
- •FVAR, FCVAR,
- •PBYTE
- •PWORD
- •XBYTE
- •XWORD
- •Routines by Category
- •Buffer Manipulation
- •Character Conversion and Classification
- •Data Conversion
- •Math Routines
- •Memory Allocation Routines
- •Stream Input and Output Routines
- •String Manipulation Routines
- •Miscellaneous Routines
- •Include Files
- •8051 Special Function Register Include Files
- •ABSACC.H
- •ASSERT.H
- •CTYPE.H
- •INTRINS.H
- •MATH.H
- •SETJMP.H
- •STDARG.H
- •STDDEF.H
- •STDIO.H
- •STDLIB.H
- •STRING.H
- •Reference
- •Compiler-related Differences
- •Library-related Differences
- •Appendix B. Version Differences
- •Version 6.0 Differences
- •Version 5 Differences
- •Version 4 Differences
- •Version 3.4 Differences
- •Version 3.2 Differences
- •Version 3.0 Differences
- •Version 2 Differences
- •Appendix C. Writing Optimum Code
- •Memory Model
- •Variable Location
- •Variable Size
- •Unsigned Types
- •Local Variables
- •Other Sources
- •Appendix D. Compiler Limits
- •Appendix E. Byte Ordering
- •Recursive Code Reference Error
- •Problems Using the printf Routines
- •Uncalled Functions
- •Using Monitor-51
- •Trouble with the bdata Memory Type
- •Function Pointers
- •Glossary
- •Index

Keil Software — Cx51 Compiler User’s Guide |
101 |
|
|
Special Function Registers
The 8051 family of microcontrollers provides a distinct memory area for accessing Special Function Registers (SFRs). SFRs are used in your program to control timers, counters, serial I/Os, port I/Os, and peripherals. SFRs reside from address 0x80 to 0xFF and can be accessed as bits, bytes, and words. For more information about Special Function Registers, refer to the Intel 8-Bit Embedded Controllers handbook or other 8051 data books.
Within the 8051 family, the number and type of SFRs vary. Note that no SFR |
|
names are predefined by the Cx51 compiler. However, declarations for SFRs |
|
are provided in include files. |
3 |
The Cx51 compiler provides you with a number of include files for various 8051 |
derivatives. Each file contains declarations for the SFRs available on that derivative. See “8051 Special Function Register Include Files” on page 228 for more information about include files.
The Cx51 compiler provides access to SFRs with the sfr, sfr16, and sbit data types. The following sections describe each of these data types.
sfr
SFRs are declared in the same fashion as other C variables. The only difference is that the data type specified is sfr rather than char or int. For example:
sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0;
/* Port-0, address 80h */ /* Port-1, address 90h */ /* Port-2, address 0A0h */ /* Port-3, address 0B0h */
P0, P1, P2, and P3 are the SFR name declarations. Names for sfr variables are defined just like other C variable declarations. Any symbolic name may be used in an sfr declaration.
The address specification after the equal sign (=) must be a numeric constant. (Expressions with operators are not allowed.) Classic 8051 devices support the SFR address range 0x80 to 0xFF. The Philips 80C51MX provides an additional extended SFR space with the address range 0x180 to 0x1FF.

102 Chapter 3. Language Extensions
sfr16
Many of the newer 8051 derivatives use two SFRs with consecutive addresses to specify 16-bit values. For example, the 8052 uses addresses 0xCC and 0xCD for the low and high bytes of timer/counter 2. The Cx51 compiler provides the sfr16 data type to access 2 SFRs as a 16-bit SFR.
Access to 16-bit SFRs is possible only when the low byte immediately precedes the high byte. The low byte is used as the address in the sfr16 declaration. For example:
3 |
|
sfr16 T2 = 0xCC; |
/* Timer 2: T2L 0CCh, T2H 0CDh */ |
|
sfr16 RCAP2 = 0xCA; |
/* RCAP2L 0CAh, RCAP2H 0CBh */ |
|
|
In this example, T2 and RCAP2 are declared as 16-bit special function registers. |
||
|
|
|
|
The sfr16 declarations follow the same rules as outlined for sfr declarations. Any symbolic name can be used in an sfr16 declaration. The address specification after the equal sign (‘=’) must be a numeric constant. Expressions with operators are not allowed. The address must be the low byte of the SFR low-byte, high-byte pair.
sbit
With typical 8051 applications, it is often necessary to access individual bits within an SFR. The Cx51 compiler makes this possible with the sbit data type which provides access to bit-addressable SFRs and other bit-addressable objects. For example:
sbit EA = 0xAF;
This declaration defines EA to be the SFR bit at address 0xAF. On the 8051, this is the enable all bit in the interrupt enable register.
NOTE
Not all SFRs are bit-addressable. Only those SFRs whose address is evenly divisible by 8 are bit-addressable. The lower nibble of the SFR’s address must be 0 or 8. For example, SFRs at 0xA8 and 0xD0 are bit-addressable, whereas SFRs at 0xC7 and 0xEB are not. To calculate an SFR bit address, add the bit position to the SFR byte address. So, to access bit 6 in the SFR at 0xC8, the SFR bit address would be 0xCE (0xC8 + 6).

Keil Software — Cx51 Compiler User’s Guide |
103 |
|
|
Any symbolic name can be used in an sbit declaration. The expression to the right of the equal sign (=) specifies an absolute bit address for the symbolic name. There are three variants for specifying the address:
Variant 1: |
sfr_name ^ int_constant |
|
||
|
This variant uses a previously declared sfr (sfr_name) as the |
|
||
|
base address for the sbit. The address of the existing SFR |
|
||
|
must be evenly divisible by 8. The expression following the |
|
||
|
carat symbol (^) specifies the position of the bit to access |
|
||
|
with this declaration. The bit position must be a number in |
|
||
|
the 0 to 7 range. For example: |
|
||
|
|
|
3 |
|
|
sfr |
PSW = 0xD0; |
|
|
|
sfr |
IE = 0xA8; |
|
|
|
sbit OV = PSW ^ 2; |
|
||
|
sbit CY = PSW ^ 7; |
|
||
|
sbit EA = IE ^ 7; |
|
|
|
Variant 2: |
int_constant ^ int_constant |
|
||
|
This variant uses an integer constant as the base address for |
|
||
|
the sbit. The base address value must be evenly divisible by |
|
||
|
8. The expression following the carat symbol (‘^’) specifies |
|
||
|
the position of the bit to access with this declaration. The |
|
||
|
bit position must be a number in the 0 to 7 range. For |
|
||
|
example: |
|
||
|
|
|
||
|
sbit OV = 0xD0 ^ 2; |
|
|
|
|
sbit CY = 0xD0 ^ 7; |
|
|
|
|
sbit EA = 0xA8 ^ 7; |
|
|
|
Variant 3: |
int_constant |
|
||
|
This variant uses an absolute bit address for the sbit. For |
|
||
|
example: |
|
sbit OV = 0xD2; sbit CY = 0xD7; sbit EA = 0xAF;
NOTE
Special function bits represent an independent declaration class that may not be interchangeable with other bit declarations or bit fields.
The sbit data type declaration may be used to access individual bits of variables declared with the bdata memory type specifier. Refer to “Bit-addressable Objects” on page 99 for more information.