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

📄 c5112.txt

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

标  题: C51 Primer (11) Some C51 Tricks 

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

  

  

11 Some C51 Programming Tricks 

11.1 Accessing R0 etc. directly from C51 

A C51 user was using existing assembler routines to perform a specific task. 

 For historical reasons the 8 bit return value from the assembler was left i 

n R0 of register bank 3. Ordinarily C51 would return chars in R7 and therefo 

re simply equating a variable to the assembler function call would not work. 

  

The solution was to declare an uncommitted memory specific pointer to the DA 

TA area. At run time the absolute address of the register (here 0x18) was as 

signed to the pointer. The return value was then picked up via the pointer a 

fter exiting the assembler section. 

/*** Example Of Accessing Specific Registers In C ***/ 

char data *dptr ;  // Create pointer to DATA location 

/* Define Address Of Register */ 

#define R0_bank3 0x40018L   /* Address of R0 in */ 

                            /* bank 3, 4 => DATA space */ 

char x,y ; 

/* Execute */ 

main() { 

dptr = (char*) R0_bank3 ;  // Point at R0, bank3 

x = 10 ; 

dptr[0] = x ;   // Write x into R0, bank3 

y = *dptr ;     // Get value of R0, bank3 

} 

An alternative might have been to declare a variable to hold the return valu 

e in a separate module and to use the linker to fix that module's DATA segme 

nt address at 0x18. This method is more robust and code efficient but is con 

siderably less flexible. 

11.2 Making Use Of Unused Interrupt Sources 

One problem with the 8051 is the lack of a TRAP or software interrupt instru 

ction. While C166 users have the luxury of real hardware support for such th 

ings, 8051 programmers have to be more cunning. 

A situation arose recently where the highest priority interrupt function in 

a system had to run until a certain point, from which lesser interrupts coul 

d then come in. Unfortunately, changing the interrupt priority registers par 

t way through the interrupt function did not work, the lesser interrupts sim 

ply waiting until the RETI. The solution was to hijack the unused A/D conver 

ter interrupt, IADC, and attach the second section of the interrupt function 

 to it. Then by deliberately setting the IADC pending flag just before the c 

losing "}", the second section could be made to run immediately afterwards. 

As the priority of the ADC interrupt had been set to a low level, it was int 

erruptable. 

/* Primary Interrupt Attached In CC0 Input Capture */ 

tdc_int() interrupt 8 { 

/* High priority section - may not be interrupted */ 

/* Enable lower priority section attached to */ 

                            /* ADC interrupt */ 

IADC = 1 ; // Force ADCinterrupt 

EADC = 1 ; // Enable ADC interrupt 

} 

/* Lower priority section attached to ADC interrupt */ 

tdc_int_low_priority() interrupt 10 

IADC = 0 ; // Prevent further calls 

EADC = 0 ; 

/* Low priority section which must be interruptable and */ 

    /* guaranteed to follow high priority section above */ 

} 

11.3 Code Memory Device Switching 

This dodge was used during the development of a HEX file loader for a simple 

 8051 monitor. After receiving a hexfile into a RAM via the serial port, the 

 new file was to be executed in RAM starting from 0000H. A complication was 

that the memory map had to be switched immediately prior to hitting 0000H. 

The solution was to place the map switching section at 0xfffd so that the ne 

xt instruction would be fetched from 0x0000, thus simulating a reset. Ideall 

y all registers and flags should be cleared before this. 

"reg.h" 

#include "cemb537.h" 

#include  <stdio.h> 

   main() 

      { 

      unsigned char tx_char,rx_char,i ; 

      P4 = map2 ; 

#include 

      v24ini_537() ; 

      timer0_init_537() ; 

      hexload_ini() ; 

      EAL = 1 ; 

      while(download_completed == 0) 

         { 

         while(char_received_fl == 0) 

            { receive_byte() ; } 

         tx_byte = rx_byte ; /* Echo */ 

         hexload() ; 

         send_byte(tx_byte) ; 

         char_received_fl = 0 ; 

         } 

      real_time_count = 0 ; 

      while(real_time_count < 200) 

         { ; } 

      i = ((unsigned char (code*)(void)) 0xFFFD) () ; 

                       // Jump to absolute address. 

      } 

//^^^^^^^^^^^^^^^^^^^^^^^ End of Module 

; 

   NAME SWITCH 

; 

; Cause PC to roll-over at FFFFH to simulate reset 

; 

   P4      DATA 0E8H 

; 

   CSEG AT 0FFFDH 

; 

   MOV  P4,#02Fh  ; 

; 

   END 

//^^^^^^^^^^^^^^^^^^^^^^^ End of Module "MAPCON" 

There are other ways of doing this. For instance the code for the MAPCON mod 

ule could be located at link time thus: CODE(SWITCH(0FFFDH)), so dispensing 

with the "CSEG AT". 

11.4 Simulating A Software Reset 

In a similar vein to the above, the 8051 does not possess a software reset i 

nstruction, unlike the 80C166 etc.. This method uses abstract pointers to cr 

eate a call to address zero, thus simulating a software reset. 

However it should be remembered that all internal locations must be cleared 

before the CPU can be considered properly reset! The return address must be 

reset as the stack still contains the return address from the call. 

; 

; 

; void main(void) { 

    RSEG  ?PR?main?T1 

    USING    0 

main: 

            ; SOURCE LINE # 9 

; 

; ((void (code*) (void)) 0x0000) () ; 

            ; SOURCE LINE # 11 

    LCALL    00H       ; Jump to address ZERO! 



; 

; } 

            ; SOURCE LINE # 13 

    RET 

; END OF main 

11.5 The Compiler Preprocessor - #define 

This is really just a text replacement device. 

It can be used to improve program readability by giving constants meaningful 

 names, for example: 

    #define fuel_constant 100 * 2 

so that the statement temp = fuel_constant will assign the value 200 to temp 

. 

Note that the preprocessor only allows integer calculations. 

Other more sophisticated examples are given in the C51 manual, pages 4-2. 

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

---- 

  

-- 

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

  

⌨️ 快捷键说明

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