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

📄 c5111.txt

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

标  题: C51 primer (10) Miscellaneous Points 

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

  

  

10 Miscellaneous Points 

10.1 Tying The C Program To The Restart Vector 

This is achieved by the assembler file STARTUP.A51. This program simply plac 

es a LJMP STARTUP at location C0000 (Lowest EPROM location 

The startup routine just clears the internal RAM and sets up the stack point 

er. Finally it executes a LJMP to "main", (hopefully) the first function in 

the C program. 

    LJMP main 

        . 

        . 

        . 

        . 

        main() 

        { 

        } 

In fact this need be the only assembler present in a C51 program. 

10.2 Intrinsic Functions 

There are a number of special 8051 assembler instructions which are not norm 

ally used by C51. For the sake of speed it is sometimes useful to get direct 

 access to these. 

Unlike the normal C51 '>>' functions, _cror_ allows direct usage of an 8051 

instruction set feature, in this case the "RR A" (rotate accumulator). This 

yields a much faster result than would be obtained by writing one using bits 

 and the normal >> operator. There are also _iror_ and _lror_ intrinsic func 

tions for integer and long data as well. 

The _nop_ function simply adds an in-line NOP instruction to generate a shor 

t and predictable time delay. Another function, _testbit_, makes use of the 

JBC instruction to allow a bit to be tested, a branch taken and the bit clea 

red if set. The only extra step necessary is to include "intrins.h" in the C 

51 source file. 

Here is an example of how the _testbit_() intrinsic function is used to save 

 a CLR instruction: 

; #include <intrins.h> 

; 

; 

; unsigned int shift_reg = 0 ; 

; 

; bit test_flag ; 

; 

; void main(void) { 

    RSEG  ?PR?main?T 

    USING    0 

main: 

            ; SOURCE LINE # 12 

; 

; /* Use Normal Approach */ 

; 

;    test_flag = 1 ; 

            ; SOURCE LINE # 14 

    SETB     test_flag 

; 

;    if(test_flag == 1) { 

            ; SOURCE LINE # 16 

    JNB      test_flag,?C0001 

;       test_flag = 0 ; 

            ; SOURCE LINE # 17 

    CLR      test_flag 

;       P1 = 0xff     ; 

            ; SOURCE LINE # 18 

    MOV      P1,#0FFH 

;       } 

            ; SOURCE LINE # 19 

?C0001: 

; 

; /* Use Intrinsic Function */ 

; 

;    test_flag = 1 ; 

            ; SOURCE LINE # 21 

    SETB     test_flag 

; 

;   if(!_testbit_(test_flag)) { 

            ; SOURCE LINE # 23 

    JBC      test_flag,?C0003 

;       P1 = 0xff     ; 

            ; SOURCE LINE # 24 

    MOV      P1,#0FFH 

;       } 

            ; SOURCE LINE # 25 

; 

;    } 

            ; SOURCE LINE # 27 

?C0003: 

    RET 

; END OF main 

    END 

See pages 9-17 in the C51 Manual 

10.3 EA Bit Control #pragma 

Whilst the interrupt modifier for function declarations remains unchanged a 

new directive, DISABLE, allows interrupts to be disabled for the duration of 

 a function. Note that this can be individually applied to separate function 

s within a module but is given as a #pragma rather than as part of the funct 

ion declaration. Although not verified yet, DISABLE gives the user some cont 

rol over the EA or EAL bit. 

10.4 16 Bit sfr Support 

Another new feature is the 16bit sfr type. Within expanded 8051 variants in 

particular, many 16 bit timer and capture registers exist. Rather than havin 

g to load the upper and lower bytes individually with separate C statements, 

 the sfr16 type is provided. The actual address declared for a 16 bit sfr in 

 the header file is always the low byte of the sfr. Now to load a 16 bit sfr 

 from C, only a single int load is required. Be warned - 8-bit instructions 

are still used, so the 16 bit load/read is not indivisible - odd things can 

happen if you load a timer and it overflows during the process! Note that us 

ually only timer 2 or above has the high/low bytes arranged sequentially. 

10.5 Function Level Optimisation 

Optimisation levels of 4 and above are essentially function optimisations an 

d, as such, the whole function must be held in PC memory for processing. If 

there is insufficient memory for this, a warning is issued and the additiona 

l optimisation abandoned. Code execution will still be correct however. See 

p1-8 in the C51 manual. 

10.6 In-Line Functions In C51 

One of the fundamentals of C is that code with a well-defined input, output 

and job is placed into a function i.e. a subroutine. This involves placing p 

arameters into a passing area, whether a stack or a register, and then execu 

ting a CALL. It is unavoidable that the call instruction will use two bytes 

of stack. 

In most 8051 applications this not a problem, as there is generally 256 on-c 

hip RAM potentially available as stack. Even after allowing for a few regist 

erbanks, there is normally sufficient stack space for deeply nested function 

s. 

However in the case of the 8031 and reduced devices such as the 87C751, ever 

y byte of RAM is critical. In the latter case there are only 64 bytes! 

A trick which can both save stack and reduce run time is to use macros with 

parameters to act like "in-line" functions. The ability to create macros wit 

h replaceable parameters is not commonly used but on limited RAM variants it 

 can be very useful. 

Here a strcpy() function created as a macro named "Inline_Strcpy", whilst it 

 looks like a normal function, it does not actually have any fixed addresses 

 or local data of its own. The '\' characters serve to allow the macro defin 

ition to continue to a new line, in this case to preserve the function-like 

appearance. 

It is "called" like a normal function with the parameters to be passed enclo 

sed in ( ). However no CALL is used and the necessary code is created in-lin 

e. The end result is that a strcpy is performed but no new RAM or stack is r 

equired. 

Please note however, the drawback with this very simple example is that the 

source and destination pointers are modified by the copying process and so i 

s rather suspect! 

A further benefit in this example is that the notional pointers s1 and s2 ar 

e automatically memory-specific and thus very efficient. Thus in situations 

where the same function must operate on pointer data in a variety of memory 

spaces, slow generic pointers are not required. 

#define Inline_Strcpy(s1,s2)  {\ while((*s1 = *s2) != 0)}\ 

                     {\*s1++ ; *s2++; }\ 

                               } 

char xdata *out_buffx = { "                           " } ; 

char xdata *in_buffx = { "Hello" } ; 

char idata *in_buffi = { "Hello" } ; 

char idata *out_buffi = { "                           " }  ; 

char code *in_buffc = { "Hello" } ; 

void main(void) { 

   Inline_Strcpy(out_buffx,in_buffx)  // In line functions 

   Inline_Strcpy(out_buffi,in_buffi) 

   Inline_Strcpy(out_buffx,in_buffc) 

   } 

Another good example of how a macro with parameters can be used to aid sourc 

e readability is in the optimisation feature in Appendix D. The interpolatio 

n calculation that originally formed a subroutine could easily be redefined 

as a macro with 5 parameters, realising a ram and run time saving at the exp 

ense of code size. 

Note that 'r', the fifth parameter, represents the return value which has to 

 be "passed" to the macro so that it has somewhere to put the result! 

#define interp_sub(x,y,n,d,r)  y -= x ; \ 

if(!CY) { r = (unsigned char) (x +(unsigned char)(((unsigned 

            int)(n * y))/d)) ;\ 

} else { r = (unsigned char) (x - (unsigned char)(((unsigned int)(n * -y))/d 

)) ; } 

This is then called by: 

/*Interpolate 2D Map Values */ 

/*Macro With Parameters Used*/ 

interp_sub(map_x1y1,map_x2y1,x_temp1,x_temp2,result_y1) 

and later it is reused with different parameters thus: 



interp_sub(map_x1y2,map_x2y2,x_temp1,x_temp2,result_y2) 

To summarise, parameter macros are a good way of telling C51 about a general 

ised series of operations whose memory spaces or input values change in prog 

rams where speed or RAM usage is critical. 

---------------------------------------------------------------------------- 

---- 

  

-- 

Ours is essentially a tragic age, so we refuse to take it tragically. 

  

⌨️ 快捷键说明

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