亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? c516.txt

?? dsp&c51的編程,從小百合上down的
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
發信人: reflection (似水流年), 信區: EEtechnology 

標  題: C51 Primer (5) C Language Extensions for 8051 

發信站: 南京大學小百合站 (Wed Nov 24 11:58:24 1999), 轉信 

  

  

5 C Language Extensions For 8051 

Programming 

8051 programming is mainly concerned with accessing real devices at specific 

 locations, plus coping with interrupt servicing. C51 has made many extensio 

ns to the C language to allow near-assembler code efficiency. The main point 

s are now covered. 

5.1 Accessing 8051 On-Chip Peripherals 

In the typical embedded control application, reading and writing port data, 

setting timer registers and reading input captures etc. are commonplace. To 

cope with this without recourse to assembler, C51 has the special data types 

 sfr and sbit. 

Typical declarations are: 

    sfr P0 0x80 

    sfr P1 0x81 

    sfr  ADCON; 0xDE 

    sbit EA  0x9F 

and so on. 

These declarations reside in header files such as reg51.h for the basic 8051 

 or reg552.h for the 80C552 and so on. It is the definition of sfrs in these 

 header files that customises the compiler to the target processor. Accessin 

g the sfr data is then a simple matter: 

   { 

   ADCON = 0x08 ;   /* Write data to register */ 

   P1 = 0xFF    ;   /* Write data to Port */ 

   io_status = P0 ; /* Read data from Port */ 

   EA = 1       ;   /* Set a bit (enable all interrupts) */ 

   } 

It is worth noting that control bits in registers which are not part of Inte 

l's original 8051 design generally cannot be bit-addressed. 

The rule is usually that addresses that are divisible by 8 are bit addressab 

le. Thus for example, the serial Port 1 control bits in an 80C537 must be ad 

dressed via byte instructions and masking. 

Always check the processor's user manual to verify which sfr register bits c 

an be bit addressed. 

5.2 Interrupts 

Interrupts play an important part in most 8051 applications. There are sever 

al factors to be taken into account when servicing an interrupt: 

The correct vector must be generated so that the routine may be called. C51 

does this automatically. 

The local variables in the service routine must not be shared with locals in 

 the background loop code: the L51 linker will try to re-use locations so th 

at the same byte of RAM will have different significance depending on which 

function is currently being executed. This is essential to make best use of 

the limited internal memory. Obviously this relies on functions being execut 

ed only sequentially. Unexpected interrupts cannot therefore use the same RA 

M. 

5.2.1 The Interrupt Function Type 

To allow C coding of interrupts a special function type is used thus; 

    timer0_int() interrupt 1 using 2 

    { 

    unsigned char temp1 ; 

    unsigned char temp2 ; 

    executable C statements ; 

    } 

Firstly, the argument of the "interrupt" statement, "1" causes a vector to b 

e generated at (8*n+3), where n is the argument of the "interrupt" declarati 

on. Here a "LJMP timer0_int" will be placed at location 0BH in the code memo 

ry. Any local variables declared in the routine are not overlaid by the link 

er to prevent the overwriting of background variables. 

Logically, with an interrupt routine, parameters cannot be passed to it or r 

eturned. When the interrupt occurs, compiler-inserted code is run which push 

es the accumulator, B,DPTR and the PSW (program status word) onto the stack. 

 Finally, on exiting the interrupt routine, the items previously stored on t 

he stack are restored and the closing "}" causes a RETI to be used rather th 

an a normal RET. 

5.2.2 Using C51 With Target Monitor Debuggers 

Many simple 8032 target debuggers place the monitor's EPROM code at 0, with 

a RAM mapped into both CODE and XDATA spaces at 0x8000. The user's program i 

s then loaded into the RAM at 0x8000 and, as the PSEN is ANDed with the RD p 

in, the program is executed. This poses something of a problem as regards in 

terrupt vectors. C51/L51 assume that the vectors can be placed at 0. Most mo 

nitors for the 8032 foresee this problem by redirecting all the interrupt ve 

ctors up to 0x8000 and above, i.e. they add a fixed offset of 0x8000. Thus t 

he timer 0 overflow interrupt is redirected by a vector at C:0x000B to C:0x8 

00B. 

Before C51 v3.40 the interrupt vector generation had to be disabled and asse 

mbler jumps had to be inserted. However now the INTVECTOR control has been i 

ntroduced to allow the interrupt vector area to be based at any address. 

In most cases the vector area will start at 0x8000 so that the familar "8 * 

n + 3" formula outlined in section 5.2.1 effectively becomes: 

8 * n + 3 + INTVECTOR 

To use this: 

#pragma INTVECTOR(0x8000)   /* Set vector area start to 0x8000 */ 

void timer0_int(void) interrupt 1 { 

   /* CODE...*/ 

   } 

This produces an LJMP timer0_int at address C:0x800B. The redirection by the 

 monitor from C:0x000B will now work correctly. 

5.2.3 Coping Interrupt Spacings Other Than 8 

Some 8051's do not follow the normal interrupt spacing of 8 bytes - the '8' 

in the 8 * n + 3 formula. Fortunately the "INTERVAL #pragma" copes with this 

. 

The interrupt formula is, in reality: 

INTERVAL * n + INTVECTOR and so: 

#pragma INTERVAL(6)   /* Change spacing */ 

will allow a 6 byte spacing. 

Please note that for convenience INTERVAL defaults to 8 and INTVECTOR to 0x8 

0000! 

5.2.4 The Using Control 

The "using" control tells the compiler to switch register banks. This is an 

area where the 8051 architecture works for the compiler rather than against 

it; the registers R0 to R7 are used extensively for the temporary storage of 

 library routines and for locals. Ordinarily Bank 1 is used. However, to be 

able to use this standard code in an interrupt the register bank must be swi 

tched to 2 in the above example. Thus the variables of the interrupted routi 

nes are preserved. 

As a rule interrupts of the same priority can share a register bank, since t 

here is no risk that they will interrupt each other. 

If interrupt runtime is not important the USING can be omitted, in which cas 

e C51 examines the registers which are actually used within the routine and 

pushes only these onto the stack. This obviously increases the effective int 

errupt latency. 

5.3 Interrupts, USING, Registerbanks, NOAREGS In C51 

Everything You Need To Know 

Interrupts play an important part in most 8051 applications and fortunately, 

 C51 allows interrupt service routines to be written entirely in C. Whilst y 

ou can write perfectly workable (and safe) programs by using just straight A 

NSI C, you can significantly improve the efficiency of your code by gaining 

an understanding of the following special C51 controls: 

INTERRUPT 

USING 

NOAREGS 

RE-ENTRANT 

REGISTERBANK 

5.3.1 The Basic Interrupt Service Function Attribute 

The correct vector must be generated so that the routine may be called. C51 

does this based on the argument to the interrupt keyword. The linker thereaf 

ter does not allow local data from interrupt routines to be overlaid with th 

at from the background by creating special sections in RAM. C51 special "int 

errupt" function attribute example: 

/*Timer 0 Overflow Interrupt Service Routine */ 

timer0_int() interrupt1 

{ 

unsigned char temp1 ; 

unsigned char temp2 ; 

/* executable C statements ; */ 

} 

The "interrupt 1" causes a vector to be generated at (8*n+3), where n is the 

 argument of the "interrupt" declaration. An "LJMP timer0_int" will be place 

d at location 0BH in the code memory. 

Local variables declared in the routine are not overlaid by the linker to pr 

event the overwriting of background variables. 

When the interrupt occurs, compiler-inserted code is run which pushes the ac 

cumulator, B,DPTR and the PSW (program status word) onto the stack if used i 

n function, along with any registers R0-R7 used in the function. 

A RETI is inserted at the end of the function rather than RET. Taking an emp 

ty interrupt service function for the timer 0 overflow interrupt, this is ho 

w C51 starts off an interrupt routine that uses no registers at all: 

timer0_int Entry Code 

void timer0_int(void) interrupt1 

{ 

RSEG ?PR?timer0_int?TIMER0 

USING 0 

timer0_int: 

; SOURCE LINE # 2 

If a function, here called "sys_interp" is now called from the timer0 servic 

e function, this is how the entry code to the interrupt changes. 

timer0_int Entry Code Now With Called Function 

; void timer0_int(void) interrupt 1 

{ 

RSEG ?PR?timer0_int?TIMER0 

USING 0 

timer0_int: 

PUSH ACC 

PUSH B 

PUSH DPH 

PUSH DPL 

PUSH PSW 

PUSH AR0 

PUSH AR1 

PUSH AR2 

PUSH AR3 

PUSH AR4 

PUSH AR5 

PUSH AR6 

PUSH AR7 

Note that the entire current registerbank is pushed onto the stack when ente 

ring timer0_int() as C51 assumes that all will be used by sys_interp. Sys_in 

terp receives parameters in registers; if the entry to sys_interp is examine 

d, an important compiler trick is revealed: 

sys_interp() Entry Code 

; unsigned char sys_interp(unsigned char x_value, 

RSEG ?PR?_sys_interp?INTERP 

 USING 0 

_sys_interp: 

MOV y_value?10,R5 

MOV map_base?10,R2 

MOV map_base?10+01H,R3 

;--Variable 'x_value?10' assigned to Register 'R1' -- 

MOV R1,AR7 

The efficient MOV of R7 to R1 by using AR7 allows a MOV direct, direct on en 

try to sys_interp(). This is absolute register addressing and is a useful do 

dge for speeding up code. 

5.3.2 The absolute register addressing trick in detail 

The situation often arises that the contents of one Ri register needs to be 

moved directly into another general purpose register. This usually occurs du 

ring a function's entry code when a pointer is passed. Unfortunately, Intel 

did not provide a MOV Reg,Reg instruction and so Keil use the trick of treat 

ing a register as an absolute D: segment address: 

Simulating A MOV Reg,Reg Instruction: 

In registerbank 0 - MOV R0,AR7, is identical to - MOV R0,07H. 

Implementing a "MOV Reg,Reg" instruction the long way: 

XCH A,R1 

MOV A,R1 

The use of this trick means however, that you must make sure that the compil 

er knows which is the current registerbank in use so that it can get the abs 

olute addresses right. If you use the USING control, problems can arise! See 

 the next few sections... 

5.3.3 The USING Control 

"using" tells the compiler to switch register banks on entry to an interrupt 

 routine. This "context" switch is the fastest way of providing a fresh regi 

sterbank for an interrupt routine's local data and is to be preferred to sta 

cking registers for very time-critical routines. Note that interrupts of the 

 same priority can share a register bank, since there is no risk that they w 

ill interrupt each other. 

8051 Register Bank Base Addresses 

R0 AR0 Absolute Addr.0x00 REGISTERBANK 0 

R1 AR1 

R2 AR2 

R3 AR3 

R4 AR4 

R5 AR5 

R6 AR6 

R7 AR7 

R0 Absolute Addr. 0x08 REGISTERBANK 1, "USING 1" 

R1 

R2 

R3 

R4 

R5 

R6 

R7 

R0 Absolute Addr. 0x10 REGISTERBANK 2, "USING 2" 

R1 

R2 

R3 

R4 

R5 

R6 

R7 

R0 Absolute Addr. 0x18 REGISTERBANK 3, "USING 3" 

R1 

R2 

R3 

R4 

R5 

R6 

R7 

If a USING 1 is added to the timer1 interrupt function prototype, the pushin 

g of registers is replaced by a simple MOV to PSW to switch registerbanks. U 

nfortunately, while the interrupt entry is speeded up, the direct register a 

ddressing used on entry to sys_interp fails. This is because C51 has not yet 

 been told that the registerbank has been changed. If no working registers a 

re used and no other function is called, the optimizer eliminiates teh code 

to switch register banks. 

timer0_int Entry Code With USING 

With USING 1 

; void timer0_int(void) interrupt 1 using 1 { 

RSEG ?PR?timer0_int?TIMER0 

USING 1 <--- New register bank now 

timer0_int: 

PUSH ACC 

PUSH B 

PUSH DPH 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久婷婷成人综合色| 日本不卡1234视频| 暴力调教一区二区三区| 国产精品精品国产色婷婷| 成人免费高清视频| 亚洲天堂a在线| 日本高清成人免费播放| 午夜精品影院在线观看| 欧美二区三区91| 国内精品在线播放| 国产日韩视频一区二区三区| 99麻豆久久久国产精品免费优播| 亚洲素人一区二区| 欧美视频第二页| 精品写真视频在线观看| 国产精品午夜免费| 欧美三级视频在线| 久久精品国产77777蜜臀| 国产亚洲欧美日韩日本| 色妞www精品视频| 日韩不卡免费视频| 国产欧美一区二区三区沐欲| 一道本成人在线| 精品一区二区三区在线观看| 国产精品久久精品日日| 欧美老肥妇做.爰bbww| 国产一区在线看| 亚洲精品伦理在线| 精品国产麻豆免费人成网站| 91在线丨porny丨国产| 麻豆久久一区二区| 自拍偷在线精品自拍偷无码专区| 欧美电影一区二区三区| 国产高清在线精品| 午夜伦理一区二区| 国产视频视频一区| 91精品久久久久久久99蜜桃| 成人小视频在线观看| 亚洲综合一区二区| 欧美电影精品一区二区| 高清不卡一区二区在线| 国产精品日产欧美久久久久| 91在线观看视频| 亚洲bt欧美bt精品777| 久久久激情视频| 欧美中文字幕一区| 国产一区二区视频在线播放| 亚洲日本一区二区三区| 日韩欧美色综合| 91久久一区二区| 国产在线不卡一区| 亚洲福利一二三区| 欧美高清在线一区| 日韩三区在线观看| 麻豆视频一区二区| 综合久久给合久久狠狠狠97色 | 美腿丝袜亚洲三区| 成人免费一区二区三区在线观看| 欧美一区二区啪啪| 色一区在线观看| 国产mv日韩mv欧美| 蜜乳av一区二区三区| 亚洲一区二区三区中文字幕| 国产亚洲精品精华液| 欧美一区二区三区免费在线看| 97精品视频在线观看自产线路二| 美女看a上一区| 亚洲成精国产精品女| 久久久精品tv| 99国产精品国产精品久久| 五月综合激情网| 一区二区欧美在线观看| 久久久精品国产免费观看同学| 制服丝袜激情欧洲亚洲| 国产999精品久久久久久| 久久成人免费日本黄色| 婷婷六月综合网| 亚洲国产中文字幕| 亚洲视频一二三区| 欧美国产日本韩| 国产亚洲短视频| 精品国产乱码久久久久久闺蜜| 欧美精品在线视频| 欧美日本在线播放| 欧美丝袜第三区| 欧美日韩久久久一区| 日本伦理一区二区| 国产suv精品一区二区6| 国产精品自拍av| 国产毛片精品视频| 黄色资源网久久资源365| 理论片日本一区| 偷拍一区二区三区四区| 日日嗨av一区二区三区四区| 亚洲国产精品久久久久婷婷884| 国产视频一区二区在线观看| 中文字幕在线不卡| 中文字幕在线不卡| 亚洲欧洲中文日韩久久av乱码| 一区在线中文字幕| 最新日韩在线视频| 亚洲激情在线激情| 午夜久久久影院| 蜜桃视频免费观看一区| 极品少妇一区二区| 国产aⅴ综合色| 国产成人自拍高清视频在线免费播放| 国内精品伊人久久久久影院对白| 九九九精品视频| 成人小视频在线观看| proumb性欧美在线观看| 色天使久久综合网天天| 欧美日韩成人在线一区| 日韩一卡二卡三卡国产欧美| 欧美www视频| 国产精品久久三区| 亚洲国产精品久久人人爱 | 一区二区三区四区五区视频在线观看 | 亚洲三级在线免费观看| 亚洲国产一区在线观看| 麻豆一区二区在线| heyzo一本久久综合| 欧美三级在线看| 国产婷婷色一区二区三区四区| 国产精品福利电影一区二区三区四区| 亚洲一区二三区| 国产原创一区二区| 欧美在线免费观看亚洲| 欧美mv日韩mv| 一区二区三区资源| 久久成人久久爱| 99re这里只有精品首页| 99精品国产视频| 欧美高清hd18日本| 久久精品视频一区二区三区| 一区二区三区丝袜| 美腿丝袜在线亚洲一区| 91农村精品一区二区在线| 91精品免费在线观看| 国产精品传媒在线| 久久精品免费看| 在线看日本不卡| 91精品国产一区二区| 国产喷白浆一区二区三区| 一区二区三区欧美日| 国产一区二区调教| 在线播放日韩导航| 最新不卡av在线| 亚洲aaa精品| 欧美撒尿777hd撒尿| 中文欧美字幕免费| 久久精品久久精品| 欧美视频在线播放| 最新热久久免费视频| 国产乱人伦精品一区二区在线观看| 色88888久久久久久影院野外| 国产性色一区二区| 日韩黄色小视频| 972aa.com艺术欧美| 久久久美女毛片| 精品在线观看免费| 欧美一区二区免费| 亚洲午夜精品网| 91女厕偷拍女厕偷拍高清| 国产欧美日韩另类一区| 日本人妖一区二区| 91黄色在线观看| 中文字幕亚洲区| 丁香一区二区三区| 久久免费美女视频| 裸体健美xxxx欧美裸体表演| 欧美亚洲一区二区三区四区| 国产精品国产a级| 成人激情视频网站| 精品精品欲导航| 日本vs亚洲vs韩国一区三区二区| 欧美色图12p| 亚洲丰满少妇videoshd| 精品视频在线免费| 伊人性伊人情综合网| 91国模大尺度私拍在线视频| 亚洲毛片av在线| 粉嫩一区二区三区在线看| 日韩欧美专区在线| 极品销魂美女一区二区三区| 久久午夜电影网| 狠狠色狠狠色综合日日91app| 337p粉嫩大胆色噜噜噜噜亚洲| 久久精品99国产精品| 欧美v国产在线一区二区三区| 久久精品国产成人一区二区三区| 欧美日韩精品二区第二页| 免费欧美高清视频| 欧美电影免费观看高清完整版在线 | 欧美午夜宅男影院| 日韩精品亚洲专区| 精品精品欲导航| 国产精品99久久久久久久vr| 国产精品久久午夜夜伦鲁鲁| 色婷婷av一区二区三区大白胸|