- •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 |
379 |
|
|
Function Pointers
Function pointers are one of the most difficult aspects of C to understand and to properly utilize. Most problems involving function pointers are caused by improper declaration of the function pointer, improper assignment, and improper dereferencing.
The following brief example demonstrates how to declare a function pointer (f), how to assign function addresses to it, and how to call the functions through the pointer. The printf routine is used for example purposes when running DS51 to simulate program execution.
#pragma code symbols debug oe |
|
|
|||
#include <reg51.h> |
/* special function register declarations */ |
|
|||
#include <stdio.h> |
/* prototype declarations for I/O functions */ |
|
|||
void func1(int d) { |
/* function #1 */ |
|
|||
printf("In FUNC1(%d)\n", d); |
|
|
|||
} |
|
|
|
|
|
void func2(int i) { |
/* function #2 */ |
|
|||
printf("In FUNC2(%d)\n", i); |
|
|
|||
} |
|
|
|
|
|
void main(void) { |
|
|
|
||
void (*f)(int i); |
/* Declaration of a function pointer */ |
|
|||
|
|
/* that takes one integer arguments */ |
|
||
|
|
/* and returns nothing */ |
|
||
SCON |
= 0x50; |
/* SCON: mode 1, 8-bit UART, enable rcvr */ |
|
||
TMOD |= 0x20; |
/* TMOD: timer 1, mode 2, 8-bit reload */ |
F |
|||
TH1 |
= 0xf3; |
/* TH1: |
reload value for 2400 baud */ |
||
|
|||||
TR1 |
= 1; |
/* TR1: |
timer 1 run */ |
|
|
TI |
= 1; |
/* TI: |
set TI to send first char of UART */ |
|
|
while( 1 ) { |
|
|
|
||
f = (void *)func1; |
/* f points to function #1 */ |
|
|||
f(1); |
|
|
|
||
f = (void *)func2; |
/* f points to function #2 */ |
|
|||
f(2); |
|
|
|
}
}
NOTE
Because of the limited stack space of the 8051, the linker overlays function variables and arguments in memory. When you use a function pointer, the linker cannot correctly create a call tree for your program. For this reason, you may have to correct the call tree for the data overlaying. Use the OVERLAY directive with the linker to do this. Refer to the Ax51 Macro Assembler User’s Guide for more information.
380 |
Appendix F. Hints, Tips, and Techniques |
|
|
F
Keil Software — Cx51 Compiler User’s Guide |
381 |
|
|
F