?? c5110.txt
字號:
發(fā)信人: reflection (似水流年), 信區(qū): EEtechnology
標(biāo) 題: C51 Primer (9) Other C51 Extentions
發(fā)信站: 南京大學(xué)小百合站 (Wed Nov 24 12:02:32 1999), 轉(zhuǎn)信
9 Other C51 Extensions
9.1 Special Function Bits
.v.A frustration for assembler programmers with the old C51 version was the
need to use bit masks when testing for specific bits with chars and ints, de
spite there being a good set of bit-orientated assembler instructions within
the 8051. In version 3, however, it is possible to force data into the bit-
addressable area (starting at 0x20) where the 8051's bit instructions can be
used.
An example is testing the sign of a char by checking for bit = 1.
Here the char is declared as "bdata" thus:
bdata char test_char ;
sign_bit is defined as:
sbit sign_bit = test_char ^ 7 ;
to use this:
test_char = counter ;
if(sign_bit) { /* test_char is negative */ }
the opcodes executed are:
MOV A,counter ;
MOV test_char,A ;
JNB 0,DONE ;
/* Negative */
All of which is a lot faster than using bit masks and &'s!
The important points are that the "bdata" tells C51 and L51 that this variab
le is to be placed in the bit-addressable RAM area and the "sbit sign_bit =
test_char ^ 7" tells C51 to assume that a bit called sign_bit will be locate
d at position 7 in the test_char byte.
Byte Number: test_char 20H Start Of BDATA area
Bit Number: 0,1,2,3,4,5,6,7<_ sign_bit
Byte Number: 21H
Bit Number: 8,9,10,11,12,13,14,15
Byte Number: 22H
Bit Number: 16,17,18,19,20,21,22,23,24.....
The situation with ints is somewhat more complicated. The problem is that th
e 8051 does not store things as you first expect. The same sign test for an
int would require bit 7 to be tested. This is because the 8051 stores int's
high byte at the lower address. Thus bit 7 is the highest bit of the higher
byte and 15 is the highest bit of the lower.
Byte Number: test_int(high) 20H
Bit Number: 0,1,2,3,4,5,6,7
Byte Number: test_int+1(low) 21H
Bit Number: 8,9,10,11,12,13,14,15
Bit locations in an integer
9.2 Support For 80C517/537 32-bit Maths Unit
The Siemens 80C537 and 80C517A group have a special hardware maths unit, the
MDU, aimed at speeding-up number-crunching applications.
9.2.1 The MDU - How To Use It
To allow the 8051 to cope with 16 and 32-bit ("int" and "long") multiplicati
on and division, the Siemens 80C517 variant has a special maths co-processor
(MDU) integrated on the cpu silicon. A 32-bit normalise and shift is also i
ncluded for floating point number support. It also has 8 data pointers to ma
ke accessing external RAM more efficient.
The compiler can take advantage of these enhancements if the "MOD517" switch
is used, either as a #pragma or as a command line extension. This will resu
lt in the use of the MDU to perform > 8 bit multiplies and divides. However
a special set of runtime libraries is required from Keil for linking.
Using the MDU will typically yield a runtime improvement of 6 to 9 times the
basic 8051 cpu for 32 bit unsigned integer arithmetic.
Optionally the blanket use of the 80C517 enhancements after MOD517 can be se
lectively disabled by the NOMDU and NODP pragmas. Predictably NOMDU will inh
ibit the use of the maths unit, while NODP will stop the eight data pointers
being used.
9.2.2 The 8 Datapointers
To speed up block data moves between external addresses, the 517A has 8 data
pointers. These are only used by C51 in the memcpy() and strcpy() library fu
nctions.
The general "MOD517" switch will enable their use. Note that the strcat() ro
utine does not use the additional data pointers.
If the extra pointers are to be used both in background and interrupt functi
ons, the DPSEL register is automatically stacked on entry to the interrupt a
nd a new DPSEL value allocated for the duration of the function.
9.2.3 80C517 - Things To Be Aware Of
The 80C517 MDU is used effectively like a hardware subroutine, as it is not
actually part of the 8051 cpu. As such it is subject to normal sub-routine r
ules regarding re-entrancy. If, as an example, both a background program and
an interrupt routine try to use the MDU simultaneously, the background calc
ulation will be corrupted. This is because the MDU input and output register
s are fixed locations and the interrupt will simply overwrite the background
values.
To allow the background user to detect corruption of the MDU registers, the
MDEF bit is provided within the ARCON register. After any background use of
the MDU, a check should be made for this flag being set. If so, the calculat
ion must be repeated. Appropriate use of the NOMDU pragma could be used inst
ead.
Note: the compiler does not do this - the user must add the following code t
o overcome the problem:
#pragma MOD517
#include "reg517.h"
long x,y,z ;
func()
{
while(1)
{
x = y / z ; /* 32-bit calculation */
if(MDEF == 0) /* If corruption has */
{ break ; } /* occurred then repeat */
} /* else exit loop */
}
9.3 87C751 Support
The Philips 87C751 differs from the normal 8051 CPU by having a 2k code spac
e with no option for external ROM. This renders the long LJMP and LCALL inst
ructions redundant. To cope with this the compiler must be forced to not gen
erate long branch instructions but to use AJMPs and ACALLs instead
9.3.1 87C751 - Steps To Take
Invoke C51 with C51 myfile.c ROM(SMALL) NOINTVECTOR or use "#pragma ROM(SMAL
L)"
Use the INIT751.A51 startup file in the LIB directory.
Do not use floating point arithmetic, integer or long divides, printf, scanf
etc., as they all use LCALLs.
A special 87C751 library package is available which will contain short call
versions of the standard library routines.
9.3.2 Integer Promotion
Automatic integer promotion within IF statements is incorporated in version
>= 3.40 to meet recent ANSI stipulations in this area. This makes porting co
de from Microsoft or Borland PC C compilers much easier. Thus any char(s) wi
thin a conditional statement are pre-cast to int before the compare is perfo
rmed. This makes some sense on 16 bit machines where int is as efficient as
char but, in the 8051, char is the natural size for data and so some loss of
efficiency results. Fortunately Keil have provided "#pragma NOINTPROMOTE" t
o disable this feature! In this case explicit casts should be used if anothe
r data type might result from an operation.
To show why this #pragma is important, this C fragment's code sizes are infl
uenced thus:
char c ; unsigned char c1, c2 ; int i ;
main() {
if((char)c == 0xff) c = 0 ;
if((char)c == -1) c = 1 ;
i = (char)c + 5 ;
if((char)c1 < (char)c2 + 4) c1 = 0 ;
}
Code Sizes
47 bytes - C51 v3.20
49 bytes - C51 v3.40 (INTPROMOTE)
63 bytes - C51 v3.40 (NOINTPROMOTE)
Again this goes to show that C portability compromises efficiency in 8051 pr
ograms...
----------------------------------------------------------------------------
----
--
Ours is essentially a tragic age, so we refuse to take it tragically.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -