ChipCenter Questlink
SEARCH CHIPCENTER
Search Type:
Search for:




Knowledge Centers
Product Reviews
Data Sheets
Guides & Experts
News
International
Ask Us
Circuit Cellar Online
App Notes
NetSeminars
Careers
Resources
FAQ
EE Times Network
Electronics Group Sites

THE ULTIMATE 16-BIT MICROCONTROLLER


Circuit Cellar Online
THE MAGAZINE FOR COMPUTER APPLICATIONS
Circuit Cellar Online offers articles illustrating creative solutions
and unique applications through complete projects, practical
tutorials, and useful design techniques.

THE ULTIMATE 16-BIT MICROCONTROLLER

Lessons from the Trenches by Robbert Maris

Start ý 16-bit Preselection ý Compiler Issues ý The RISC Challenge ý Sources and PDF

When establishing a migration path from 8-bit applications into more demanding applications using 16- or 32-bit controllers, there are numerous factors that must be considered for an optimum choice. Despite C language optimized chips, there is one factorýs affect on efficiency that is not emphasized by any of the chip vendorsýmemory organization. You will see that, especially in applications incorporating user interface or extensive communications, this is one of the main factors affecting code density and speed. In this article, an approach is worked out to make a basic selection of controllers that allow good performance in a wide application spectrum, thus potentially reducing controller diversity in particular companies and reducing tool investments for several projects.

Anyone whoýs done large 8051-target projects in C language will admit that the handling of pointer arguments in functions requires careful attention. The pointers are naturally associated with the individual memory types in the 8051 because they are internal RAM, external RAM, page (external) RAM, and code memory, and they are also shared for constant data and strings. However, a general access scheme must be incorporated within the compiler because individual functions must be capable of working with pointer arguments pointing to RAM data, as well as ROM data. A classic example is the printf function. The printf format string (actually, a pointer) must work with strings in ROM (e.g., text strings), as well as variables or strings in RAM. Other standard functions requiring generic pointers are string manipulation functions.

The overhead is enormous. Any character access by a generic pointer in 8051 requires a library function call, which contains a switch statement (spoken in C-terms) that selects one of six memory targets defined by the third pointer byte (the other two form the 16-bit pointer). Within this function, the appropriate assembler command is invoked to indirectly read the byte from the specific memory and then return this to the caller. This library function scheme is not code intensive, but it is speed impacting.

Listing i shows most of the assembler codings of pointer usage. For each instance, a global variable is used to store an indirectly accessed character. The assembler output is not intermixed with the C source code, a feature that is standard on most compilers. Therefore, some comments are added by hand at this point.

Another approach is to put the memory access code inline. This is accomplished with the PIC compiler from Hi-Tech Software. This solution is also code and time consuming, but compromises with a time overhead that is not as big as with the 8051. Moreover, bit 15 is assigned as type identification within the 16-bit pointer, not as an extra byte.

In order to not waste time and code, the 8051 and PIC compilers support memory-specific pointers. This is where the types used in the 8051 can get confusing. I taught a microcontroller course a few years ago, and the target was the 8051. It took hours for the average student to understand the meaning of the storage memory type of the pointer and the memory type of the object to which it points. And, letýs not forget the regularly appearing compiler errors like "conflicting memory types." This is an important topic when dealing with the 8051. Storing a pointer pointing to external RAM in external RAM yields inefficient code because the 8051 requires DPTR indirect addressing for XRAM accesses. This is one reason why I use a small compiler memory model instead of a large model and specify only bigger variable blocks like arrays with an XRAM specifier (xdata or far, which are compiler dependent).

Does this mean that Harvard is not C friendly? By no means! Harvard is still a good design approach that allows code fetching separately from the data bus and, thus, speeds up processing when the code memory is on-chip by using a code data bus. The crux is in the instruction set. When an examination of a particular instruction set shows that separate instructions for indirect (pointer) code memory accesses exist, the processor should be disqualified when demanding applications are in mind. In another case, the addressing mechanism treats the whole address space as a linear space, where CPU hardware takes care of loading code data over the internal data bus.

Another crux lies in the position of memory segments (i.e., are far pointers necessary to access ROM or RAM?). This factor will be examined later.

A MODERN 8-BIT EXAMPLE

It is often stated that the PIC architecture is not a real RISC architecture. A better approach is the AVR architecture. It is important to note the presence of three 16-bit pointers, as well as the register array itself. Alas, the AVR supports indirect code memory access, using only a special instruction. Therefore, there is no value in the fact that the pointer locations are shared for ROM and RAM targets. That means, a bit in the pointer needs to identify the memory type. And upon access, this bit is tested, and the appropriate indirection function is carried out.

This fact shows that the AVR family is not an optimum choice for applications with massive "generic" pointer utilization, besides the fact that itýs an 8-bit controller.

Even though 8-bit controllers may be powerful today, they can never eliminate the following disadvantageýreading 16-bit variables requires that interrupts be disabled temporarily in the case of updating such variables within interrupts. Using the volatile keyword does not automatically arrange this. This must be tested with the individual compiler being used. Moreover, additional interrupt disable intervals increase latency time. Note that 16-bit integer processing in interrupts becomes more evident as more peripheral functions have 10-, 12-, or 16-bit registers. A 16-bit processor would reduce any Murphy-like spurious errors in this respect.

NEXT


Circuit Cellar provides up-to-date information for engineers. Visit www.circuitcellar.com for more information and additional articles.
For subscription information, call (860) 875-2199, subscribe@circuitcellar.com or subscribe online. ýCircuit Cellar, the Magazine for Computer Applications. Posted with permission.
Click here to get your listing up.

Copyright © 2003 ChipCenter-QuestLink
About ChipCenter-Questlink  Contact Us  Privacy Statement   Advertising Information  FAQ