⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c5110.txt

📁 dsp&c51的编程,从小百合上down的
💻 TXT
字号:
发信人: reflection (似水流年), 信区: EEtechnology 

标  题: C51 Primer (9) Other C51 Extentions 

发信站: 南京大学小百合站 (Wed Nov 24 12:02:32 1999), 转信 

  

  

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. 

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -