第4章 80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)課件_第1頁(yè)
第4章 80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)課件_第2頁(yè)
第4章 80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)課件_第3頁(yè)
第4章 80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)課件_第4頁(yè)
第4章 80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)課件_第5頁(yè)
已閱讀5頁(yè),還剩50頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

2023/10/261第4章80C51單片機(jī)C語(yǔ)言程序設(shè)計(jì)C51對(duì)標(biāo)準(zhǔn)C的擴(kuò)展4.1C51的指針4.2C51的函數(shù)4.3C51與匯編程序的接口4.4編譯器能自動(dòng)完成變量的存儲(chǔ)單元的分配對(duì)常用功能模塊和算法編制相應(yīng)的函數(shù),方便移植采用C51的優(yōu)點(diǎn)C語(yǔ)言具有良好的可讀性、可移植性和基本的硬件操作能力。

對(duì)單片機(jī)內(nèi)部資源的操作直接簡(jiǎn)捷生成的代碼緊湊匯編語(yǔ)言的特點(diǎn)2023/10/2634.1C51對(duì)標(biāo)準(zhǔn)C的擴(kuò)展4.1.1C51的數(shù)據(jù)類型數(shù)據(jù)是計(jì)算機(jī)操作的對(duì)象,包含常量和變量。C51擴(kuò)展了ANSIC,以適應(yīng)單片機(jī)的結(jié)構(gòu)和特點(diǎn)。

數(shù)據(jù)類型就是數(shù)據(jù)的格式,它決定數(shù)據(jù)的值域范圍、占用存儲(chǔ)單元的個(gè)數(shù)及能參與哪種運(yùn)算。編寫C51程序,先要確定數(shù)據(jù)類型、存儲(chǔ)分區(qū)應(yīng)盡可能采用無(wú)符號(hào)格式(unsigned)

C51中,多字節(jié)數(shù)據(jù)采用“大端對(duì)齊”格式數(shù)據(jù)起始字節(jié)置于高地址端2023/10/264數(shù)據(jù)類型長(zhǎng)度(位)取值范圍字符型signedchar8-128~127unsignedchar80~255整型signedint16-32768~32767unsignedint160~65535長(zhǎng)整型signedlong32-21474883648~21474883647unsignedlong320~4294967295浮點(diǎn)型float32±1.75494E-38~±3.402823E+38位型bit10,1sbit10,1訪問SFRsfr80~255sfr16160~65535C51數(shù)據(jù)類型表2023/10/265bit定義位變量名字,編譯器在位尋址區(qū)自動(dòng)分配該位變量;Sbit聲明位變量的名字和地址,地址是確定的(SFR區(qū)確定位、位尋址區(qū)變量的某確定位)。幾點(diǎn)說明:sbitCY=0xD7;bitflag1=0;含義:賦值含義:聲明unsigned

charbdataibase;sbitmybitf=ibase^0;2023/10/2664.1.2C51數(shù)據(jù)的存儲(chǔ)分區(qū)存儲(chǔ)器類型長(zhǎng)度(位)對(duì)應(yīng)單片機(jī)存儲(chǔ)器bdata1片內(nèi)RAM位尋址區(qū),共128位。(亦能字節(jié)訪問)data8直接尋址,共128字節(jié)。idata8間接尋址,共256字節(jié)。pdata8片外

RAM分頁(yè)間址,共256字節(jié)。(MOVX@Ri)xdata16間接尋址,共64k字節(jié)。(MOVX@DPTR)code16ROM間接尋址,共64k字節(jié)。(MOVCA,@A+DPTR)經(jīng)常使用的變量應(yīng)該置于片內(nèi)RAM中,要用bdata、data、idata來(lái)定義不常使用的變量或規(guī)模較大的變量應(yīng)該置于片外RAM中,要用pdata、xdata來(lái)定義bitbdataflags;

//位變量flags定位在片內(nèi)位尋址區(qū)chardatavar;

//字符變量var定位在片內(nèi)RAM區(qū)floatidatax,y;

//實(shí)型變量x,y定位在片內(nèi)間址RAM區(qū)unsignedcharpdataz;

//無(wú)符號(hào)字符變量z定位在片外分頁(yè)間址RAM區(qū)2023/10/268編譯模式默認(rèn)存儲(chǔ)分區(qū)特點(diǎn)SMALLdata小模式。變量默認(rèn)在片內(nèi)RAM??臻g小,速度塊。COMPACTpdata緊湊模式。變量默認(rèn)在片外RAM的頁(yè)(256字節(jié),頁(yè)號(hào)由P2口決定)。LARGExdata大模式。變量默認(rèn)在片外RAM的64KB范圍??臻g大,速度慢。編譯模式默認(rèn)的變量存儲(chǔ)分區(qū)4.1.3C51的編譯模式未對(duì)變量存儲(chǔ)分區(qū)定義時(shí),C51編譯器采用默認(rèn)存儲(chǔ)分區(qū)。例如:charvar;

//SMALL模式時(shí),var定位于data存儲(chǔ)區(qū)

//COMPACT模式時(shí),var定位于pdata存儲(chǔ)區(qū)

//LARGE模式時(shí),var定位于xdata存儲(chǔ)區(qū)2023/10/26104.1.4用_at_定義變量絕對(duì)地址用關(guān)鍵字“_at_”定義變量存放的首地址idatainty_at_0x30;//idata區(qū)域整型變量y的首地址為0x30例如:又如:xdatacharstring[20]_at_0x3000;//xdata中字符型數(shù)組string的首地址為0x3000

注意,C51編程時(shí)不要輕易使用絕對(duì)地址定位變量。2023/10/2611補(bǔ)充1:80C51硬件結(jié)構(gòu)的C51定義特殊功能寄存器的聲明sfr

特殊功能寄存器名=地址常數(shù);格式:例如:sfrSCON=0x90;/*串行口控制寄存器地址為90H*/sfrP0=0x80;/*P0口,地址為80H*/2023/10/2612特殊功能寄存器中特定位的聲明sbit位變量名=特殊功能寄存器名^位的位置(0~7)例如:

sfrPSW=0xD0;sbitOV=PSW^2;

sbit位變量名=字節(jié)地址^位的位置(0~7)例如:

sbitOV=0xD0^2;sbitCY=0xD0^7;sbit位變量名=位地址

例如:

sbitOV=0xD2;sbitCY=0xD7;

注:字節(jié)地址做基地址,必須位于80H~FFH之間

,位地址也必須位于80H~FFH2023/10/2613內(nèi)部RAM中可位尋址對(duì)象的定義先定義變量的數(shù)據(jù)類型和存儲(chǔ)類型例如:

intbdataibase;charbdataarray[4];

再利用sbit進(jìn)行聲明

例如:

sbitmybit0=ibase^0;

sbitmybit15=ibase^15;

sbitary07=array[0]^7;注意:不能定義bit類型指針,也不能定義bit類型數(shù)組

訪問示例:ibase=-1;array[2]=‘a(chǎn)’;ary07=0;

2023/10/2614算術(shù)運(yùn)算符和算術(shù)表達(dá)式補(bǔ)充2:C51的運(yùn)算符和表達(dá)式基本算術(shù)運(yùn)算符例如:

+加法運(yùn)算符;

-減法(取負(fù))運(yùn)算符;*乘法運(yùn)算符;/除法運(yùn)算符;%取余數(shù)運(yùn)算符。

如:a+b*(10-a),(x+9)/(y-a)示例:25.0/20.0=1.2525/20=125%20=5

取負(fù)運(yùn)算優(yōu)先級(jí)最高。2023/10/2615自增、自減運(yùn)算符(僅能用于變量)例如:

++自增運(yùn)算符;

--自減運(yùn)算符;++i和i++類型轉(zhuǎn)換運(yùn)算符自動(dòng)轉(zhuǎn)換,順序:bit→char→int→long→float

強(qiáng)制類型轉(zhuǎn)換,如:(double)a

2023/10/2616關(guān)系運(yùn)算符和關(guān)系表達(dá)式關(guān)系運(yùn)算符

<小于;<=小于等于;>大于;>=大于等于;==等于;!=不等于。關(guān)系表達(dá)式關(guān)系表達(dá)式的值為邏輯值:真(1)和假(0)2023/10/2617邏輯運(yùn)算符和邏輯表達(dá)式邏輯運(yùn)算符

||邏輯或;&&邏輯與;

!邏輯非。邏輯表達(dá)式邏輯表達(dá)式的值為邏輯值:真(1)和假(0)例:5||0結(jié)果為1,2&&0結(jié)果為02023/10/2618位運(yùn)算符對(duì)硬件直接進(jìn)行操作&按位與;|按位或;^按位異或;~按位取反;<<左移;>>右移。例:P1=P1<<1表示對(duì)P1口的所有位左移1位temp=P1|0xFF

如:sbitst=P1^0;sbitled=P2^0;if(st==0){led=~led;}2023/10/2619賦值和復(fù)合賦值運(yùn)算符復(fù)合賦值運(yùn)算符+=加法賦值;-=減法賦值;*=乘法賦值;/=除法賦值;%=取模賦值;符號(hào)“=”稱為賦值運(yùn)算符

<<=左移位賦值;>>=右移位賦值;&=邏輯與賦值;|=邏輯或賦值;^=邏輯異或賦值;~=邏輯非賦值

例:a*=5相當(dāng)于a=a*5;b&=0x80相當(dāng)于b=b&0x80。2023/10/2620補(bǔ)充3:C51流程控制語(yǔ)句3.1C51選擇語(yǔ)句

條件語(yǔ)句if(條件表達(dá)式)語(yǔ)句

例如:if(p1!=0){c=20;}

if(條件表達(dá)式)語(yǔ)句1else語(yǔ)句2例如:if(p1!=0){c=20;}else{c=0;}

2023/10/2621if(條件表達(dá)式1)語(yǔ)句1elseif(條件表達(dá)式2)語(yǔ)句2elseif(條件表達(dá)式3)語(yǔ)句3

…elseif(條件表達(dá)式n)語(yǔ)句nelse語(yǔ)句n+1

例如:if(a<=1){c=10;}elseif(a<=2){c=20;}

elseif(a<=3){c=30;}elseif(a<=4){c=40;}elsec=0;

2023/10/2622開關(guān)語(yǔ)句switch(表達(dá)式){case常量表達(dá)式1:語(yǔ)句1;break;case常量表達(dá)式2:語(yǔ)句2;break;

…case常量表達(dá)式n:語(yǔ)句n;break;default:語(yǔ)句n+1;}2023/10/26233.2C51循環(huán)語(yǔ)句while語(yǔ)句一般形式為:

while(條件表達(dá)式)語(yǔ)句;如果條件表達(dá)式的結(jié)果一開始就為假,則后面的語(yǔ)句一次也不能執(zhí)行。do-while語(yǔ)句一般形式為:

do語(yǔ)句

while(條件表達(dá)式);任何條件下,循環(huán)體語(yǔ)句至少會(huì)被執(zhí)行一次。2023/10/2624for語(yǔ)句一般形式為:for([初值表達(dá)式];[條件表達(dá)式];[更新表達(dá)式])語(yǔ)句if語(yǔ)句與goto語(yǔ)句結(jié)合

當(dāng)型循環(huán)

形式為:

loop:if(表達(dá)式)

{語(yǔ)句

gotoloop;

}2023/10/2625直到型循環(huán)

形式為:

loop:{語(yǔ)句

if(表達(dá)式)gotoloop;

}continue是一種循環(huán)中斷語(yǔ)句,它并不跳出循環(huán)體;break語(yǔ)句只能跳出它所處的那一層循環(huán);goto語(yǔ)句可以用于跳出多重循環(huán)(從內(nèi)層到外層)。注意:示例:開關(guān)控制LED程序:開關(guān)控制LED#include<reg52.h>sbitS1=P1^0;sbitS2=P1^1;sbitLED1=P0^0;sbitLED2=P0^1;voidmain(){while(1) { LED1=S1; LED2=S2; }}示例:從左到右的流水燈程序:從左到右的流水燈#include<reg52.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedintvoidDelayMS(uintx){uchari; while(x--) {for(i=120;i>0;i--);}}voidmain(){P0=0xFE;while(1) { P0=_crol_(P0,1); DelayMS(150); }}2023/10/26304.2

C51的指針對(duì)于一個(gè)變量a,利用&a表示變量a的地址。則語(yǔ)句

p=&a;表明把a(bǔ)的地址賦給了指針變量p,則“p指向了變量a”。

可以用*P表示變量a指針變量的定義

char*p;//定義指針變量P

p=30H;//指針變量賦值,30H為片內(nèi)RAM地址x=*p;//30H單元的內(nèi)容送給變量x*P指針變量數(shù)據(jù)變量4.2.1已定義數(shù)據(jù)存儲(chǔ)分區(qū)的指針定義時(shí)就指定了所指向數(shù)據(jù)的存儲(chǔ)分區(qū)。

該指針占1個(gè)字節(jié)(idata*,data*,pdata*)或2個(gè)字節(jié)(code*,xdata*)

示例:char

data*str;

//指針str指向的char型數(shù)據(jù)存于data空間int

xdata*num;

//指針num指向的int型數(shù)據(jù)存于xdata

空間

基于存儲(chǔ)器的指針長(zhǎng)度比通用指針短,可以節(jié)省存儲(chǔ)器空間,運(yùn)行速度快,但它所指對(duì)象具有確定的存儲(chǔ)器空間,兼容性不好。數(shù)據(jù)數(shù)據(jù)存儲(chǔ)分區(qū)2023/10/2632定義時(shí)未指定所指向的數(shù)據(jù)的存儲(chǔ)分區(qū)。也稱通用指針。4.2.2未定義數(shù)據(jù)存儲(chǔ)分區(qū)的指針---通用指針通用指針占3個(gè)字節(jié)第一字節(jié)存放該指針的默認(rèn)存儲(chǔ)器類型編碼(見表)第二字節(jié)存放該指針的高位地址偏移量第三字節(jié)存放該指針的低位地址偏移量

存儲(chǔ)器類型編碼存儲(chǔ)器類型bdata/data/idataxdatapdatacode編碼0x000x010xfe0xff2023/10/2633通用指針定義示例:char*xdatastrptr;

//指針本身存于xdata空間,它指向char型數(shù)據(jù)int*datanumber;

//指針本身存于data空間,它指向int型數(shù)據(jù)由于指向?qū)ο蟮拇鎯?chǔ)空間在編譯時(shí)無(wú)法確定(運(yùn)行時(shí)確定),因此必須生成通用代碼以保證對(duì)任意空間的對(duì)象進(jìn)行存取。所以通用指針生成的代碼速度較慢。指針char型數(shù)據(jù)指針分區(qū)2023/10/26344.2.3利用指針進(jìn)行絕對(duì)地址訪問unsignedchardata*p;p=0x40;*p=0x55;//數(shù)據(jù)0x55送入內(nèi)部RAM的0x40單元

例如:

C51編譯器提供了一組宏定義實(shí)現(xiàn)對(duì)80C51絕對(duì)地址的訪問。這組宏定義原型放在absacc.h文件中,形如:

#defineDBYTE((unsignedcharvolatiledata*)0)從而使DBYTE用于以字節(jié)形式對(duì)data區(qū)訪問,可以寫成:*(DBYTE)=0x55H;或

DBYTE[0]=0x55H;

與此類似:CBYTE用于以字節(jié)形式對(duì)code區(qū)進(jìn)行訪問;PBYTE用于以字節(jié)形式對(duì)pdata區(qū)進(jìn)行訪問;XBYTE用于以字節(jié)形式對(duì)xdata區(qū)進(jìn)行訪問。CWORD、DWORD、PWORD和XWORD用于以字形式對(duì)code區(qū)、data區(qū)、pdata區(qū)和xdata區(qū)進(jìn)行訪問。4.2.4C51程序編寫示例【例4-1】將30H至3FH共16個(gè)RAM單元初始化為“55H”。#include<reg52.h>#include<absacc.h>voidmain(void){ unsignedchari; for(i=0;i<=15;i++) { DBYTE[0x30+i]=0x55; } while(1);}C:0x0000020011LJMPC:0011C:0x0003E4CLRAC:0x0004FFMOVR7,AC:0x00057430MOVA,#0x30C:0x00072FADDA,R7C:0x0008F8MOVR0,AC:0x00097655MOV@R0,#0x55C:0x000B0FINCR7C:0x000CBF10F6CJNER7,#0x10,C:0005C:0x000F80FESJMPC:000FC:0x0011787FMOVR0,#0x7FC:0x0013E4CLRAC:0x0014F6MOV@R0,AC:0x0015D8FDDJNZR0,C:0014C:0x0017758107MOVSP,#0x07C:0x001A020003LJMPC:0003反匯編如下:編譯系統(tǒng)自動(dòng)連接了startup.a51生成代碼一是將內(nèi)部RAM的00H~7FH清0;二是設(shè)置堆棧指針SP。

2023/10/26394.3

C51的函數(shù)4.3.1C51函數(shù)的定義一般形式:返回值類型函數(shù)名(形式參數(shù)列表)[編譯模式][reentrant][interruptn][usingn]{

函數(shù)體}編譯模式為SMALL、COMPACT或LARGEreentrant用于定義可重入函數(shù)interruptn用于定義中斷函數(shù),n為中斷號(hào),可以為0~31usingn確定工作寄存器組,取值為0~3

【例4-2】延時(shí)nMs函數(shù)示例(晶振11.0592MHz)。voidDelayMs(unsignedintn)//延時(shí)函數(shù){ unsignedcharj; while(n--) { for(j=0;j<113;j++); }}調(diào)試:Registers窗口中的sec值。

4.3.2C51函數(shù)定義的選項(xiàng)編譯模式

SMALL模式:變量默認(rèn)在片內(nèi)RAM;COMPACT模式:變量默認(rèn)在片外RAM的頁(yè)內(nèi);LARGE模式:變量默認(rèn)在片外RAM的64KB范圍。reentrant定義為重入函數(shù)

ANSIC中,函數(shù)默認(rèn)都是可重入的

C51函數(shù)默認(rèn)是不可重入的,使用可重入函數(shù)會(huì)消耗較多的存儲(chǔ)器資源,應(yīng)該盡量少用。interruptn定義中斷函數(shù)常用的中斷源對(duì)應(yīng)的中斷號(hào)usingn確定中斷服務(wù)函數(shù)所使用的工作寄存器組中斷源外中斷0定時(shí)器0外中斷1定時(shí)器1串行口定時(shí)器2中斷號(hào)012345【例4-3】中斷函數(shù)定義示例#include<reg51.h>sbitP10=P1^0;voidIntSrv(void)interrupt0

{ if(INT0==0) //測(cè)開關(guān)狀態(tài)

{ P10=!P10; while(INT0==0); }}示例:INT0中斷控制LED程序:INT0中斷控制LED#include<reg52.h>sbitLED=P0^0;voidmian(){ LED=1; EA=1; EX0=1; TCON=0x01; while(1);}voidExternal_Interrupt_0()interrupt0{ LED=~LED;}4.3.3C51的庫(kù)函數(shù)常用的C51庫(kù)函數(shù)參見附錄B.2

【例4-4】C51庫(kù)函數(shù)調(diào)用示例。#include“intrins.h”//在intrins.h中有對(duì)函數(shù)_nop_()的定義voidDelay(void){inti=5000;while(i--)_nop_();}【例4-5】C51標(biāo)準(zhǔn)輸入輸出函數(shù)調(diào)用示例。#include<reg51.h>#include<stdio.h>voidInitSPort(void){SCON=0x50;//串口方式1,允許接收TMOD=0x20;//T1方式2(自動(dòng)重裝)TH1=0xFD;//波特率9600 TR1=1;//啟動(dòng)T1TI=1;//發(fā)送中斷置1}voidmain(void){InitSPort();

printf("HelloWorld\n");while(1);}標(biāo)準(zhǔn)I/O的重定向!

在調(diào)試狀態(tài):ViewSerialWindowsUART#14.4

C51與匯編程序的接口4.4.1在C51程序中嵌入?yún)R編指令【例4-6】利用預(yù)編譯指令。#include"reg51.h"voidInit(void);voidmain(){while(1){Init();}}voidInit(void){

#pragmaasm MOVR7,#16 MOVR1,#20H MOVA,#55HLP:MOV@R1,A INCR1 DJNZR7,LP

#pragmaendasm return;}要進(jìn)行以下設(shè)置:2023/10/2649將嵌有匯編語(yǔ)句的源文件加入工程文件,將鼠標(biāo)指向該文件,選擇右鍵菜單“optionfor‘insertasm.c’”。將屬性properties書簽下的“GenerateAssemblerSRCFile”與“AssembleSRCFile”選項(xiàng)置成“√”。再加入庫(kù)文件(如C51S.LIB),然后編譯。

4.4.2在C51程序中調(diào)用匯編子

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論