2) ABOUT THE 8051

2.1) The 8051 microcontroller

    The 8051 is an 8 bit microcontroller originally developed by Intel in
    1980.  It is the world's most popular microcontroller core, made by
    many independent manufacturers (truly multi-sourced).  There were 126
    million 8051s (and variants) shipped in 1993!!

    A typical 8051 contains:
       - CPU with boolean processor
       - 5 or 6 interrupts: 2 are external
                            2 priority levels
       - 2 or 3 16-bit timer/counters
       - programmable full-duplex serial port
         (baud rate provided by one of the timers)
       - 32 I/O lines (four 8-bit ports)
       - RAM
       - ROM/EPROM in some models

    The 8051 architecture is a tad bizarre, but then so are the
    architectures of most microcontrollers due to their specialization
    (check out the PIC for creativity).  One vexing problem with the 8051
    is its very non-orthogonal instruction set - especially the
    restrictions on accessing the different address spaces.  However,
    after some time programming the chip, you can get used to it - maybe
    even appreciate it.

    One strong point of the 8051 is the way it handles interrupts.
    Vectoring to fixed 8-byte areas is convenient and efficient.  Most
    interrupt routines are very short (or at least they should be), and
    generally can fit into the 8-byte area.  Of course if your interrupt
    routine is longer, you can still jump to the appropriate routine from
    within the 8 byte interrupt region.

    The 8051 instruction set is optimized for the one-bit operations so
    often desired in real-world, real-time control applications.  The
    boolean processor provides direct support for bit manipulation.  This
    leads to more efficient programs that need to deal with binary input
    and output conditions inherent in digital-control problems.  Bit
    addressing can be used for test pin monitoring or program control

2.2) 8051 Flavors

    The 8051 has the widest range of variants of any embedded controller
    on the market.  The smallest device is the Atmel 89c1051, a 20 Pin
    FLASH variant with 2 timers, UART, 20mA.  The fastest parts are from
    Dallas, with performance close to 10 MIPS!  The most powerful chip is
    the Siemens 80C517A, with 32 Bit ALU, 2 UARTS, 2K RAM, PLCC84
    package, 8 x 16 Bit PWMs, and other features.

    Among the major manufacturers are:
        AMD      Enhanced 8051 parts (no longer producing 80x51 parts)
        Atmel    FLASH and semi-custom parts
        Dallas   Battery backed, program download, and fastest variants
        Intel    8051 through 80c51gb / 80c51sl
        Matra    80c154, low voltage static variants
        OKI      80c154, mask parts
        Philips  87c748 thru 89c588 - more variants than anyone else
        Siemens  80c501 through 80c517a, and SIECO cores
        SMC      COM20051 with ARCNET token bus network engine
        SSI      80x52, 2 x HDLC variant for MODEM use

    Advanced Micro Devices (AMD)

       AMD was one of the first manufacturers of enhanced variants
       including such features as:  dual data pointers, slave interface
       with arbitration unit, dual port RAM, FIFO buffers, and others.
       They are now out of the 8051 business.


       The smallest current device is the ATMEL 89c1051, a 20 Pin FLASH
       variant with 2 timers, UART, 20mA.  ATMEL was the first with
       standard pinout FLASH, and with more program cycles than other
       custom pinout FLASH.  These parts compete with OTP and MASK
       product on price, but eliminate inventory problems and the hidden
       costs of OTP development.  This will put real pressure on
       "vanilla" micros like PIC and ST6.

    Dallas Soft Microcontrollers - DS5000(T), DS5001(T), DS2250(T)

       The Dallas Soft Microcontrollers have standard 8051 cores with
       on-chip non-volatile RAM instead of ROM.  This gives the user the
       ability to easily alter the system and is perfect for data
       logging.  These processors are available in both chip and module
       solutions.  Among the features included in this family of
          - on-chip non-volatile RAM
          - loader in ROM for downloading programs (eliminates the hassle
            of EPROM erase/program/install cycle)
          - built in real time clock option
          - watchdog timer
          - software security (program and data encryption)

       The DS500x is a standard 40 pin DIP package (well, mostly
       standard, it is really a BOX which is about double the height of a
       normal chip).  The DS225x is a SIP version which is functionally
       identical to the DS5000 but usually a bit less expensive.

       The nice thing about having the RAM on-chip, is that the I/O ports
       are unaffected.  When the RAM is configured as CODE memory, the
       DS5000 behaves exactly as a single-chip 8051.  The NV-RAM is
       static with a built-in lithium battery, and has no limitations on
       the number of writes.  You can download your code as many times as
       you like without damaging the device.  The DS5000 also includes a
       loader in ROM, which permits you to bootstrap code into the RAM to
       get underway.  The loader and on-chip RAM have an encryption
       feature with which you can protect your code from being read back
       from the device if you wish.

    Dallas High-Speed Micros - DS80c320, DS87c520, DS87c530

       Real barn-burners - performance up to 10 MIPS!  Dallas was the
       first to speed up the core.  Wasted clock and memory cycles have
       been removed using a redesigned processor core.  As a result,
       every 8051 instruction is executed up to 3 times faster than the
       original for the same crystal speed.  Clock speeds from DC to

       High performance doesn't just mean speed.  High integration gives
       the user 2 full-duplex hardware serial ports, 13 total interrupt
       sources (6 external), watchdog timer, power management, power-fail
       reset, and other features.

    Intel MCS-51

       Introduced in 1980, it has become the industry standard for
       embedded control.  Intel offers a wide variety of 8051 versions
       with different configurations of on-board EPROM/ROM.  Also low
       power, high integration, and specialized parts are also offered.


       OKI makes an 85c154 piggyback - an 8751 but with an EPROM socket
       on top!  Great with an EPROM emulator.


       Philips has more 8051 variants than anyone else.  Among the
       derivatives that they have:  40MHz, 24 pin skinny DIP, low
       voltage, quad flat pack (QFP) versions for saving board space,
       OTP, I2C bus, and so on.

       The c5xx line features high integration, with many built-in
       features including built-in EMI/RFI suppression.

       The c7xx series are very low-end, inexpensive micros.  They are
       offered with less memory (1k, 2k, etc.) and fewer features.  In
       fact the 83c750 sells for only $1 in very high OEM volumes.

    Siemens sab80c517a

       The 80c517a is one of the most powerful 8051 variants available.
       It features high clock speed (40 MHz), and high integration with
       32 Bit ALU, 2 UARTS, 2K RAM, PLCC84 package, 8x16 bit PWMs, and

    Standard Microsystems Corporation SMC COM20051
       The COM20051 is an integrated microcontroller and network
       interface which features:
         -  high performance and low cost
         -  based on popular 8051 architecture
         -  drop-in replacement for 80C32 PLCC
         -  network supports up to 255 nodes
         -  powerful network diagnostics
         -  maximum 512 byte packets
         -  duplicate node ID detection
         -  self-configuring network protocol
         -  retains all 8051 peripherals including Serial I/O and
            2 Timers
         -  utilizes ARCNET(R) Token Bus Network Engine
         -  requires no special emulators
         -  5 Mbps to 156 Kbps data rate
         -  network interface supports RS-485, twisted pair,
            coaxial, and fiber optic interfaces
         -  "receive all" mode allows any packet to be received

    Silicon Systems Inc. SSI73M2910/2910A

       The SSI73M2910 is a high performance microcontroller designed for
       modem and communications applications.
         - 8052 Compatible Instruction set.
         - 34 MHz Operation @ 4.5 - 5.5V
         - 44 MHz Operation @ 4.75 - 5.5.V (2910A)
         - 22 MHz Operation @ 3.3 - 5.5.V
         - HDLC Support Logic (Packetizer, 16 and 32 CRC, zero ID)
         - 24 pins for user programmable I/O ports
         - 8 pins programmable chip select logic or I/O for memory mapped
           peripherals eliminating glue logic
         - 3 external interrupt sources (programmable polarity)
         - 16 dedicated latched address pins
         - Multiplexed latched/address bus
         - Instruction cycle time identical to 8052
         - Buffered oscillator (or OSC/2) output pin
         - 1.8432 MHz UART clock available
         - Bank select circuitry to support up to 128K of external
           program memory
         - 100-Lead TQFP package available for PCMCIA applications
         - Also available in 100-Lead QFP package

2.3) 16-bit 8051 parts

    A joint project between Intel and Philips Semiconductors has resulted
    in two new excting products - 16 bit 8051s!  Due to a disagreement
    between the parties, they each went their separate ways.  Intel
    developed the MCS-251, which was originally called the ZX (this name
    can still be found on one of the Intel slide shows).  Philips came
    out with the eXtended Architecture (XA) line.

    The Intel MCS-251 is a drop-in replacement for the 8051, and is also
    binary compatible.  The XA is more of a 16 bit micro which also
    happens to be source code compatible.  One can argue the merits of
    which approach is better.

    Pin compatible parts allow instant performance upgrades for existing
    designs, and the binary compatibility truly preserves users
    investment in code and tools.  By staying firmly in the 80x51 camp,
    Intel allows users transparent access to an enormous horsepower
    range.  To further improve throughput in numerically intensive areas,
    users can use INTEGER, LONGINT, and FLOAT libraries written for the
    MCS-251.  The Philips XA is not a drop-in replacement for the 8051.

    Binary code compatibility is nice, you can move right up to a more
    powerful engine without having to bust a gut (We all know the Intel
    binary compatible success story with their 80x86 microprocessors).
    But if you're working on a new design, how necessary is binary
    compatibility?  If you're just looking for a souped up '51, Dallas
    already has the 320.  If you need the advanced features, you'll need
    to recompile or rewrite your software anyhow.  You'll also have to
    drag along some compatibility baggage with you in order to use the 16
    bit operations - these are preceded by an escape code (A5H), the only
    instruction not used in the 8051 instruction set.

    With source code compatibility, you have to recompile your code (with
    a new set of development tools), since the instruction set has been
    recrafted to allow the biggest bang for the buck.  This process isn't
    100% transparent, but then again, binary compatibility isn't either.

    If you're upgrading an existing design, the 251 is probably your only
    reasonable choice (although you might also want to consider the
    Dallas 320).  On new designs, you'll have a tough decision to make.
    Whichever path you choose to take, the 8051 will never be the same

    Intel MCS-251

       The Intel MCS-251 is 100% binary and pin compatible with the 8051,
       but with a 5-15 times boost in horsepower.  This is achieved by a
       six fold gain in bus cycles, and further hardware improvements to
       avoid wasted bus cycles.

       Further performance gains are possible by recoding critical
       sections to take advantage of the new features:  powerful 8/16/32
       bit instructions, flexible 8/16/32 registers, 16MB linear address
       space, 16-bit stack pointer, enhanced BIT manipulations, and
       improved control instructions.  In addition to extra 16/32 bit
       instructions, the 251 includes 40 registers with Accumulator and
       Index functions overlayed as 16x8, 16x16, 10x32.

    Philips 8051XA

       By tossing compatibility out the window, Philips was able to
       develop a true 16 microcontroller while at the same time
       preserving the basic 8051 instruction set (source).  The benefits
       of this break with tradition result in a chip that has dual 16MB
       address spaces (data and code), multitasking support with task
       protected memory segments, a separate SFR bus, fast context
       switching, and optimized code efficiency.  Other features include:
       hardware divide and multiply (over 100 times faster than an 8051),
       32 vectored interrupts, 16 hardware exceptions, and 16 trap

2.4) 8051 representatives and approximate prices (in USD $)

    There are many, many varieties of 8051 out there.  This is only a
    small sampling of typical prices on Intel chips.

        8031 (128 bytes RAM)...................................3.59
        80C31 (CMOS version of previous).......................6.95
        8051AH (256 bytes RAM).................................6.95
        8051AHBASIC (w/Basic interpreter built in)............29.95
        8751 (4K EPROM, 128 bytes RAM)........................26.95
        87C51 (CMOS version of previous)......................39.95

2.5) Common and New 80x51 variants

    Thanks to Jim Granville of Mandeno Granville Electronics, Ltd. for
    this nice summary.

    Variant Pins  Mfg    RAM  CODE XRAM  Notes
    MCS251  40    Intel   1K  16K   0    16 Bit 80x51FX Prelim
    51C806  100   Siemens 256 64Kx  64b  SIECO+CAN+appx 517A, faster
    80C537A 84    Siemens 256 64Kx  2K   ALU, 8 PWM, CaptComp 2UART,
                                         10b A/D
    80C517A 84    Siemens 256 32K   2K   ALU, 8 PWM, CaptComp 2UART,
                                         10b A/D
    80537   84    Siemens 256 64Kx  0    ALU, 8 PWM, CaptComp 2UART,
                                         8b A/D
    80517   84    Siemens 256  8K   0    ALU, 8 PWM, CaptComp 2UART,
                                         8b A/D
    73D2910 100qfp SSI    256 128Kx  0   80C52+Ports+HDLC
    80C535A 68    Siemens 256 64Kx  1K   515+10bA/D, 1K XRAM, BRG, OWD
    80CE558 80qfp Philips 256 64Kx  768  Enhanced 80C552, Sep i2c, RSO
    80C515A 68    Siemens 256  32K  1K   515+10bA/D, 1K XRAM, BRG, OWD
    80535   68    Siemens 256 64Kx  0    Timer2, CaptComp, 6 ports,
                                         8/10b A/D
    80515   68    Siemens 256  8K   0    Timer2, CaptComp, 4 ports,
                                         8b A/D
    80C535  68    Siemens 256 64Kx  0    Timer2, CaptComp, 5 ports
                                         8b A/D
    80C51GB 68    Intel   256 64Kx  0    8051FA+PCA, 8b A/D, SPI
    87C51GB 68    Intel   256  8K   0    8051FA+PCA, 8b A/D, SPI
    80C592  68    Philips 256 64Kx  256  552-i2c+CAN+XRAM
    87C592  68    Philips 256  16K  256  552-i2c+CAN+XRAM
    87C598  80    Philips 256  32K  256  552-i2c+CAN+XRAM
    80C552  68    Philips 256 64Kx  0    10b A/D, i2c, CaptComp, PWM
    87C552  68    Philips 256  8K   0    10b A/D, i2c, CaptComp, PWM
    80C562  68    Philips 256 64Kx  0    8b A/D, i2c, CaptComp, PWM
    87C451  68    Philips 128  4K   0    7 Ports, 1 Handshake
    80C451  68    Philips 128 64Kx  0    7 Ports, 1 Handshake
    87C453  68    Philips 256 8K    0    7 Ports, 1 Handshake
    83CL580 56,64 Philips 256  6K   0    LV 8052+ADC+i2c+More INTs, WDOG
    SABC503 44    Siemens 256 64Kx  0    80C52+8Ch, 10bA/D, BRG, WD, OWD
    80C320  40    Dallas  256 64Kx  0    FAST, 2 DPTR 2 UART VRST
    80C310  40    Dallas  256 64Kx  0    Simpler 80C320 e62Mhz
    87C520  40    Dallas  256  16K  1K   16K OTP enhanced 80C320
    80C51FX 40    Intel   256 64Kx  0    80C58i+PCA, AsRST
    87C51FA 40    Intel   256  8K   0    8052+PCA, Enh Serial, Automotive
    87C51FB 40    Intel   256  16K  0    8052+PCA, Enh Serial, Automotive
    87C51FC 40    Intel   256  32K  0    8052+PCA, Enh Serial, Automotive
    8XC51FB 40    Philips 256  16K  0    87C51FB with ALE RFI mode
    87C51FXL40    Intel   256  32K  0    3v3 80C51FC
    80C152JD68    Intel   256 64Kx  0    HDLC/SDLC Serial
    80C152  48    Intel   256 64Kx  0    SDLC Serial
    8044    40    Intel   192 64Kx  0    RUPI Serial
    80C575  40    Philips 256 64Kx  0    8052+PCA, AnalogComp, WDOG,
    87C575  40    Philips 256  8K   0    8052+PCA, AnalogComp, WDOG,
    80C576  40    Philips 256  8K   0    8052+PCA, UPI, A/D, PWM,
                                         WDOG, VRSTLo
    87C576  40    Philips 256  8K   0    8052+PCA, UPI, A/D, PWM,
                                         WDOG, VRSTLo
    SABC501 40    Siemens 256 64Kx  0    40MHz Enhanced 8052 U/D
    SABC502 40    Siemens 256 64Kx  256  8052+XRAM+8DP+WD+BRG+OWD
    80C528  40    Philips 256 64Kx  256  8052+Wdog, XRAM
    87C528  40    Philips 256  32K  256  8052+Wdog, XRAM
    89CE528 44    Philips 256  32KF 256  Flash 528
    87C524  40    Philips 256  16K  256  16K 87C528
    80C550  40    Philips 128  4K   0    8b A/D WDog
    80CL781 40    Philips 256 64Kx  0    Low Voltage 8052, More INTs,
    83CL781 40    Philips 256 16K   0    Low Voltage 8052, More INTs,
    80CL782 40    Philips 256 64Kx  0    Low Voltage, faster 781
    89C52   40,44 Atmel   256  8KF  0    FLASH, Fast,LV 87C52
    87C54   40    Intel   256  16K  0    16K 87C52i
    87C58   40    Intel   256  32K  0    32K 87C52i
    87C52   40    Intel   256  8K   0    8052+U/D+OscO+4Li
    80C154  40    Matra   256 64Kx  0    Enhanced 8052 (also OKI)
    83C154D 40    Matra   256  32K  0    Enhanced 8052
    83C154  40    OKI     256  16K  0    Enhanced 8052
    80C654  40    Philips 256 64Kx  0    i2c
    87C652  40    Philips 256  8K   0    i2c
    87C654  40    Philips 256  16K  0    i2c
    83CE654 44qfp Philips 256 16K   0    i2c, low RFI 654
    DS5000  40    Dallas  128 32KR  32K  80x51 Secure + NV support,
    DS2250  40sim Dallas  128  32K  32K  As 5000, but smarter package
    DS5001  80qfp Dallas  128 64Kx  64K  Better 5000, + RPC + BatSw
    80C851  40    Philips 128 64Kx  0    8051+256B EEPROM
    83C852  6     Philips 256  6K   0    2K EEPROM SmartCard 80x51,
                                         Die, ALU
    8052    40    All     256 64Kx  0    8051+Timer2
    8752    40    Intel   256  8K   0    8051+Timer2
    80C52   40    Siemens 256 64Kx  0    8051+Timer2, Philips, Oki, Matra
    88SC54C 8     Atmel   256 64Kx  512  8052+PublicKey,prelim
    80CL410 40    Philips 128 64Kx  0    Low Voltage, More INTs, i2c-UART
    80CL31  40    Philips 128 64Kx  0    Low Voltage, More Ints, 80x51
    80CL610 40    Philips 256 64Kx  0    Low Voltage, More INTs, i2c-UART
    83CL411 40    Philips 256 64Kx  0    80CL31 with 256 RAM, No T2
    89C51   40,44 Atmel   128  4KF  0    FLASH,Fast,LV 87C51
    8751    40    All     128  4K   0    Core processor, UART, Tmr0, Tmr1
    87C51   40    All     128  4K   0    Core processor, UART, Tmr0, Tmr1
    8031    40    All     128 64Kx  0    Core processor, UART, Tmr0, Tmr1
    8051    40    All     128  4K   0    Core processor, UART, Tmr0, Tmr1
    80C31L  40    Matra   128 64Kx  0    Low Voltage 80x51
    87C752  28    Philips  64  2KE  0    87751+ A/D, PWM
    87C749  28    Philips  64  2KE  0    87C752 - i2c
    87C751  24    Philips  64  2KE  0    Small size, bit i2c
    87C748  24    Philips  64  2KE  0    87C751 - i2c
    87C750  24    Philips  64  1KE  0    Small size,
    89C2051 20    Atmel   128  2KF  0    20Pin 89C51,+AnaComp+LED
    89C1051 20    Atmel    64  1KF  0    20Pin 2051 -uart,timer1

        --------------- FLASH summary ---------------
    80C509F 100qf Siemens 256 128KF 3K   FLASH Super ClkDbled 517A
    80C517AF84    Siemens 256 64KF  2K   FLASH 517A
    80C515AF68    Siemens 256 64KF  1K   FLASH 515A
    89C558  80qf  Philips 256 32KF  1K   effectively a FLASH 552
    88SC54C 68    Atmel   256 16KFE 512  FLASH 8052+PublicKey 8KF + 8KEE
    89C52   40,44 Atmel   256  8KF  0    FLASH, Fast,LV 87C52
    89C51   40,44 Atmel   128  4KF  0    FLASH,Fast,LV 87C51
    89C2051 20    Atmel   128  2KF  0    FLASH 20 Pin 89C51,+ AnaComp+LED
    89C1051 20    Atmel    64  1KF  0    FLASH 20Pin 2051 - uart, timer1

    Special - DECT Phones, imagine what you could control with this...
    PCA5097 100qf Philips 256  64KF 3K   FLASH+CODEC+1K DSP+ADPCM

2.6) Advantages realized in implementing control applications on this

      family of microcontrollers

    Popular - readily available and widely supported, a full range of
    free and commercial support products is available

    Fast and effective - the architecture correlates closely with the
    problem being solved (control systems), specialized instructions mean
    that fewer bytes of code need to be fetched and fewer conditional
    jumps are processed

    Low cost - high level of system integration within one component,
    only a handful of components needed to create a working system

    Wide range -  ONE set of tools covers the greatest horsepower range
    of any microcontroller family, other suppliers handle a number of
    DIFFERENT and INCOMPATIBLE (and often single-sourced) cores to cover
    the same power range as the 80x51, the 8051 provides a real cost
    savings in tools, training, and software support

    Compatibility - opcodes and binaries are the SAME for all 80x51
    variants (unlike most other microcontroller families)

    Multi-sourced - over 12 manufacturers, hundreds of varieties,
    something for everyone with the security of ready availability

    Constant improvements - improvements in silicon/design increase speed
    and power annually, 16 bit models coming from several manufacturers,
    low cost skinny DIP models now available

2.7) Technical Questions and Answers

    Q:  Why are ports P0 and P2 unavailable for I/O when using external

    A:  The output drivers of ports 0 and 2, and the input buffers of
        port 0, are used to access external memory.  Port 0 outputs the
        low byte of the external memory address, time-multiplexed with
        the byte being read/written.  Port 2 outputs the high byte of the
        external memory address when the address is 16 bits wide.
        Otherwise, the port 2 pins continue to emit the P2 SFR contents.
        Therefore, when external memory is being used, ports 0 and 2 are
        unavailable for their primary use as general I/O lines.

    Q:  Is there anything I can do to use these ports for I/O when using
        external memory?

    A1: Not really.

    A2: If you really want to make your life miserable, you can try to
        use P2 for output when it isn't being used for memory access.
        The contents of the SFR latch for port 2 are not modified during
        the execution of a Data Memory fetch cycle on the Expanded Bus.
        If an instruction requiring a cycle on the Expanded Bus is not
        followed by another instruction requiring a cycle on the Expanded
        Bus, then the original contents of the port 2 SFR latch will
        appear during the next machine cycle.  That is, when PSEN, RD and
        WR are all inactive, you can use port 2 for output (check the
        timing charts in the data book).  The chip will emit the contents
        of the P2 SFR at that time.  Do you REALLY want to bother with
        this though?

    A3: By including the external RAM "on-chip", the Dallas DS5000 makes
        these ports available for I/O.  The SLIC2E from Xicor does the
        same thing for other 8051 parts.

    A4: If you really need the extra I/O ports, there are number of 8051
        variants that have additional ports.  Philips and Siemens are two
        such manufacturers that have these parts in their product lines.

    Q:  I'm outputting a 1 to a pin on port 0, but I'm not getting a 1
        out.  If I use a pin on port 1 instead, it works fine.  What am I
        doing wrong?

    A:  Port 0 has open drain outputs.  Ports 1, 2, and 3 have internal
        pullups.  What does this mean?  See the next question and answer.

    Q:  Port 0 has open drain outputs.  Ports 1, 2, and 3 have internal
        pullups. What does this mean, and why should I care?

    A:  When used as outputs, all port pins will drive the state to which
        the associated SFR latch bit has been set.  Except for port 0,
        which will only drive low (not high).  When a 0 is written to a
        bit in port 0, the pin is pulled low (0).  But, when a 1 is
        written to a bit in port 0, the pin goes into a high impedance
        state - or in other words, "disconnected", no value.  To be able
        to get a 1 as output, you need an external pullup resistor to
        pull up the port (to 1) when the port is in its high impedence
        state.  Typical values for pullups might be 470 ohm to drive a
        LED, and 4.7K or higher to drive logic circuits.

    C:  Any port pin may be used as a general purpose input simply by
        writing a 1 into the associated SFR latch bit.  Since ports 1, 2,
        and 3 have internal pull-up devices they will pull high and will
        source current when pulled low.  When a port 0 bit is programmed
        for input (set to 1) it will go to a high impedance state.

    Q:  Why is such an oddball crystal frequency of 11.0592 MHz used so
        often for 8051 designs.

    A1: 11.0592 MHz crystals are often used because it can be divided to
        give you exact clock rates for most of the common baud rates for
        the UART, especially for the higher speeds (9600, 19200).
        Despite the "oddball" value, these crystals are readily available
        and commonly used.

    A2: When Timer 1 is used as the baud rate generator, the baud rates
        in Modes 1 and 3 are determined by the Timer 1 overflow rate and
        the value of SMOD (PCON.7 - double speed baud rates) as follows:

           Baud rate =   ------   x (Timer 1 overflow rate)

        Most typically, the timer is configured in the auto-reload mode
        (mode 2, high nibble of TMOD = 0100B).  In this case, the baud
        rate is given as:

                           2        Oscillator frequency
           Baud rate =   -------  x --------------------
                           32         12 x (256 - TH1)

        Some typical baud rates for an 11.0592 crystal:

           Baud rate  SMOD   TH1
             19200      1   0FDH
              9600      0   0FDH
              4800      0   0FAH
              2400      0   0F4H
              1200      0   0E8H
               300      0   0A0H

        Another way to look at it, would be to rework the formula to give
        us the crystal frequency that we need for the desired baud rate:

        Minimum crystal frequency =  Baud rate x 384 / 2

        This gives us the minimum crystal frequency possible for the
        desired baud rate.  The frequency can be evenly multiplied to
        obtain higher clock speeds.

        As an example, the minimum crystal frequency for 19.2K baud is:
              3.6864 = 19200 x 384 / 2 (smod is 1 for 19.2K baud)

              11.0592 = 3.6864 x 3

        To determine the timer reload value needed, the formula can be
        changed to factor in the multiplier:
        Crystal frequency = Baud rate x (256 - TH1) x 384 / 2

        From the example above, the multiplier (3) is used to determine
              TH1 = 256 - 3 = 253 = 0FDH

        The crystal frequency for 19.2K baud is:
              11.0592 = 19200 x (256 - 0FDH) x 384 / 2
                      (smod is 1 for 19.2K baud)

        Other values can also give good results, but 11.0592 is one of
        the higher speed crystals that allows high baud rates.

    Q:  How do I decrement the data pointer (DPTR)?  Where did the DEC
        DPTR instruction go?

    A1: You can't decrement DPTR.  Although there is an INC DPTR
        instruction, there is no DEC DPTR.  In fact, there is no other
        way to change the contents of DPTR except for MOV and INC.

    A2: You can use the accumulator as an offset if you need to perform
        "calculations" on the DPTR.  As an example:
              MOV   DPTR,#9000         ; load base address into DPTR
              MOV   A,#10              ; load desired offset
              MOVC  A,@A+DPTR          ; retrieve desired data

    A3: Another method would be to use indirect addressing.  Instructions
        such as MOVX A,@Ri can address a 256 byte "page" of external RAM.
        The value represented by @Ri (@R0 or @R1) is emitted to Port 0,
        which is the low byte of the external RAM address bus.  In
        addition, the contents of the P2 register is emitted to Port 2,
        which is the high byte of the external memory address bus.  The
        indirect addressing register together with the P2 register, which
        specifies the "current page number", gives us a 16 bit pointer
        into the external memory address space.

        This technique can make moving data in external memory much
        faster than reloading DPTR every time.  The indirect addressing
        register can be manipulated much easier than DPTR which can only
        be loaded and incremented.  Just remember to make sure that P2
        contains the proper value for the high byte of the address.

    Q:  I'm trying to PUSH and POP the accumulator, but my assembler
        complains about the instruction  PUSH  A.  What's wrong with

    A:  In instructions that are accumulator specific, A is used to
        represent the accumulator.  However, PUSH and POP have no
        accumulator specific forms, only direct addressing forms.
        Therefore, you need to specify the correct accumulator "address"
        - ACC.  Use the instruction PUSH ACC.

    Q:  The 8052 AH-BASIC interpreter seems to work OK when I perform
        simple interpreted commands.  For example:
             > PRINT "HELLO"
        However, when I try to enter a [numbered] statement, I get an
             > 10 PRINT "HELLO"
             INVALID LINE NUMBER..!!
        I get the same error when I try LIST.  No matter what value I set
        a variable to, it returns a 0.  What's my problem?

    A:  Faulty memory decoding or addressing is the most common cause for
        this error message.  Your address decoding might also indicate
        that there is more memory than really exists.  Go over your
        circuit design and inspect your wiring carefully.

    Q:  Can I use C for time critical code?

    A:  The code produced by many of the excellent compilers today, is
        remarkably efficient - for both speed and size.  Modern compilers
        are quite adept at keeping track of register and variable usage.
        Further optimization techiniques result in code that can be as
        good or better than hand written assembler.  Even for ISRs
        (interrupt service routines), C should be acceptable for all but
        the most time critical routines.

        Makes you think twice about breaking your head over assembly