




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
單片機(jī)原理及應(yīng)用
曲鳳娟,計(jì)算機(jī)應(yīng)用(10615)
課件郵箱:assemb@126.com,password
第11章單片機(jī)
C51程序設(shè)計(jì)C51語言概述在學(xué)會(huì)使用匯編語言后,學(xué)習(xí)C語言編程是一件比較容易的事。下面是一個(gè)簡單的例子:89S52的P1引腳上接8個(gè)發(fā)光二極管,我們的任務(wù)是讓接在P1引腳上的發(fā)光二極管按要求發(fā)光。
11.1簡單的C程序介紹例1-1:
讓接在P1.0引腳上的LED發(fā)光。
/**********************************/
單燈閃爍程序
/**********************************/
#include
“reg51.h”
sbit
P1_0=P1^0;
void
main()
{
P1_1=0;
}
這個(gè)C語言程序包含了哪些信息
1.“文件包含”處理所謂“文件包含”是指一個(gè)文件將另外一個(gè)文件的內(nèi)容全部包含進(jìn)來,所以這里的程序雖然只有4行,但C編譯器在處理的時(shí)候卻要處理幾十或幾百行。這里程序中包含REG51.h文件的目的是為了要使用P1這個(gè)符號(hào),即通知C編譯器,程序中所寫的P1是指80C51單片機(jī)的P1端口而不是其它變量。reg51.h文件包含以下內(nèi)容:/*-----------------------------------------REG51.H
Header
file
for
generic
80C51
and
80C31
microcontroller.
Copyright
(c)
1988-2001
Keil
Elektronik
GmbH
and
Keil
Software,
Inc.
All
rights
reserved.
--------------------------------------------*/
/*
BYTE
Register
*/
sfr
P0
=
0x80;
sfr
P1
=
0x90;
sfr
P2
=
0xA0;
sfr
P3
=
0xB0;
sfr
PSW
=
0xD0;
sfr
ACC
=
0xE0;
sfr
B
=
0xF0;
sfr
SP
=
0x81;
sfr
DPL
=
0x82;
sfr
DPH
=
0x83;
sfr
PCON
=
0x87;
sfr
TCON
=
0x88;
sfr
TMOD
=
0x89;
sfr
TL0
=
0x8A;
sfr
TL1
=
0x8B;
sfr
TH0
=
0x8C;
sfr
TH1
=
0x8D;
sfr
IE
=
0xA8;
sfr
IP
=
0xB8;sfr
SCON
=
0x98;
sfr
SBUF
=
0x99;
/*
BIT
Register
*/
/*
PSW
*/
sbit
CY
=
0xD7;
sbit
AC
=
0xD6;
sbit
F0
=
0xD5;
sbit
RS1
=
0xD4;
sbit
RS0
=
0xD3;
sbit
OV
=
0xD2;
sbit
P
=
0xD0;
/*
TCON
*/
sbit
TF1
=
0x8F;
sbit
TR1
=
0x8E;
sbit
TF0
=
0x8D;
sbit
TR0
=
0x8C;
sbit
IE1
=
0x8B;
sbit
IT1
=
0x8A;
sbit
IE0
=
0x89;
sbit
IT0
=
0x88;
/*
IE
*/
sbit
EA
=
0xAF;
sbit
ES
=
0xAC;
sbit
ET1
=
0xAB;
sbit
EX1
=
0xAA;
sbit
ET0
=
0xA9;
sbit
EX0
=
0xA8;
/*
IP
*/
sbit
PS
=
0xBC;
sbit
PT1
=
0xBB;
sbit
PX1
=
0xBA;
sbit
PT0
=
0xB9;
sbit
PX0
=
0xB8;
/*
P3
*/
sbit
RD
=
0xB7;
sbit
WR
=
0xB6;
sbit
T1
=
0xB5;
sbit
T0
=
0xB4;
sbit
INT1
=
0xB3;
sbit
INT0
=
0xB2;
sbit
TXD
=
0xB1;
sbit
RXD
=
0xB0;
/*
SCON
*/
sbit
SM0
=
0x9F;
sbit
SM1
=
0x9E;
sbit
SM2
=
0x9D;
sbit
REN
=
0x9C;
sbit
TB8
=
0x9B;
sbit
RB8
=
0x9A;
sbit
TI
=
0x99;
sbit
RI
=
0x98;
注意:sfr
P1
=
0x90;
這樣的一行(上文中用黑體表示),即定義P1與地址0x90對(duì)應(yīng),P1口的地址就是0x90(0x90是C語言中十六進(jìn)制數(shù)的寫法,相當(dāng)于匯編語言中寫90H)。
sfr是標(biāo)準(zhǔn)C語言的關(guān)鍵字,而是Keil為能直接訪問80C51中的SFR而提供了一個(gè)新的關(guān)鍵詞,其用法是:
sfrt
變量名=地址值。2.符號(hào)P1_0來表示P1.0引腳
在C語言里,如果直接寫P1.0,C編譯器并不能識(shí)別,而且P1.0也不是一個(gè)合法的C語言變量名,所以得給它另起一個(gè)名字,這里起的名為P1_0,可是P1_0是不是就是P1.0呢?你這么認(rèn)為,C編譯器可不這么認(rèn)為,所以必須給它們建立聯(lián)系,這里使用了Keil
C的關(guān)鍵字sbit來定義,sbit的用法有三種:
第一種方法:sbit
位變量名=地址值
第二種方法:sbit
位變量名=SFR名稱^變量位地址值
第三種方法:sbit
位變量名=SFR地址值^變量位地址值
如定義PSW中的OV可以用以下三種方法:sbit
OV=0xd2
(1)說明:0xd2是OV的位地址值
sbit
OV=PSW^2
(2)說明:其中PSW必須先用sfr定義好
sbit
OV=0xD0^2
(3)說明:0xD0就是PSW的地址值
因此這里用sfr
P1_0=P1^0;就是定義用符號(hào)P1_0來表示P1.0引腳,如果你愿意也可以起P10一類的名字,只要下面程序中也隨之更改就行了。3.main稱為“主函數(shù)”。
每一個(gè)C語言程序有且只有一個(gè)主函數(shù),函數(shù)后面一定有一對(duì)大括號(hào)“{}”,在大括號(hào)里面書寫其它程序。
從上面的分析我們了解了部分C語言的特性,下面再看一個(gè)稍復(fù)雜一點(diǎn)的例子。例1-2
讓接在P1.0引腳上的LED閃爍發(fā)光
/*********************************單燈閃爍程序
**********************************/
#include
"reg51.h"
#define
uchar
unsigned
char
#define
uint
unsigned
int
sbit
P10=P1^0;
/*延時(shí)程序由Delay參數(shù)確定延遲時(shí)間*/
void
mDelay(unsigned
int
Delay)
{
unsigned
int
i;
for(;Delay>0;Delay--)
{
for(i=0;i<124;i++)
{;}
}
}void
main(){
for(;;)
{
P10=!P10;
//取反P1.0引腳
mDelay(1000);
}
}程序分析:程序第二行是“P1_0=!P1_0;”,在P1_0前有一個(gè)符號(hào)“!”,符號(hào)“!”是C語言的一個(gè)運(yùn)算符,就像數(shù)學(xué)中的“+”、“-”一樣,是一種運(yùn)算任號(hào),意義是“取反”,即將該符號(hào)后面的那個(gè)變量的值取反。
注意:
取反運(yùn)算只是對(duì)變量的值而言的,并不會(huì)自動(dòng)改變變量本身??梢哉J(rèn)為C編譯器在處理“!P1_0”時(shí),將P1_0的值給了一個(gè)臨時(shí)變量,然后對(duì)這個(gè)臨時(shí)變量取反,而不是直接對(duì)P1_0取反,団此取反完畢后還要使用賦值符號(hào)(“=”)將取反后的值再賦給P1_0,這樣,如果原來P1.0是低電平(LED亮),那么取反后,P1.0就是高電平(LED滅),反之,如果P1.0是高電平,取反后,P1.0就是低電平,這條指令被反復(fù)地執(zhí)行,接在P1.0上燈就會(huì)不斷“亮”、“滅”。
for(;;),這行程序連同其后的一對(duì)大括號(hào)“{}”構(gòu)成了一個(gè)無限循環(huán)語句,該大括號(hào)內(nèi)的語句會(huì)被反復(fù)執(zhí)行。
第三行程序是:“mDelay(1000);”,這行程序的用途是延時(shí)1s時(shí)間。這里mDelay(1000)并不是由Keil
C提供的庫函數(shù)。在下面的程序中有void
mDelay(…)一段,如果你的程序中沒有這么一段程序行,那就不能使用mDelay(1000)了。
mDelay后面有一個(gè)小括號(hào),小括號(hào)里有數(shù)據(jù)(1000),這個(gè)1000被稱之“參數(shù)”,用它可以在一定范圍內(nèi)調(diào)整延時(shí)時(shí)間的長短,這里用1000來要求延時(shí)時(shí)間為1000毫秒。C語言的一些特點(diǎn)1、C程序是由函數(shù)構(gòu)成的,一個(gè)C源程序至少包括一個(gè)函數(shù),一個(gè)C源程序有且只有一個(gè)名為main()的函數(shù),也可能包含其它函數(shù),因此,函數(shù)是C程序的基本單位。主程序通過直接書寫語句和調(diào)用其它函數(shù)來實(shí)現(xiàn)有關(guān)功能,這些其它函數(shù)可以是由C語言本身提供給我們的,這樣的函數(shù)稱之為庫函數(shù),也可以是用戶自己編寫的,這樣的函數(shù)稱之為用戶自定義函數(shù)。那么庫函數(shù)和用戶自定義函數(shù)有什么區(qū)別呢?簡單地說,任何使用Keil
C語言的人,都可以直接調(diào)用C的庫函數(shù)而不需要為這個(gè)函數(shù)寫任何代碼,只需要包含具有該函數(shù)說明的相應(yīng)的頭文件即可;而自定義函數(shù)則是完全個(gè)性化的,是用戶根據(jù)自己需要而編寫的。Keil
C提供了100多個(gè)庫函數(shù)供我們直接使用。2、一個(gè)函數(shù)由兩部份組成:(1)函數(shù)的首部、即函數(shù)的第一行。包括函數(shù)名、函數(shù)類型、函數(shù)屬性、函數(shù)參數(shù)(形參)名、參數(shù)類型。
例如:void
mDelay
(unsigned
int
DelayTime)
一個(gè)函數(shù)名后面必須跟一對(duì)圓括號(hào),即便沒有任何參數(shù)也是如此。
(2)函數(shù)體,即函數(shù)首部下面的大括號(hào)“{}”內(nèi)的部份。如果一個(gè)函數(shù)內(nèi)有多個(gè)大括號(hào),則最外層的一對(duì)“{}”為函數(shù)體的范圍。
函數(shù)體一般包括:
聲明部份:在這部份中定義所用到的變量,
執(zhí)行部份:由若干個(gè)語句組成。
C51的一般格式如下:類型
函數(shù)名(參數(shù)表)參數(shù)說明;{
數(shù)據(jù)說明部分;執(zhí)行語句部分;}在某此情況下也可以沒有聲明部份,甚至即沒有聲明部份,也沒有執(zhí)行部份,如:
void
mDelay()
{}
這是一個(gè)空函數(shù),什么也不干,但它是合法的。
通過上述的幾個(gè)例子,可以得出一些結(jié)論:
在編寫程序時(shí),可以利用空函數(shù),比如主程序需要調(diào)用一個(gè)延時(shí)函數(shù),可具體延時(shí)多少,怎么個(gè)延時(shí)法,暫時(shí)還不清楚,我們可以主程序的框架結(jié)構(gòu)弄清,先編譯通過,把架子搭起來再說,至于里面的細(xì)節(jié),可以在以后慢慢地填,這時(shí)利用空函數(shù),先寫這么一個(gè)函數(shù),這樣在主程序中就可以調(diào)用它了。
3、一個(gè)C語言程序,總是從main函數(shù)開始執(zhí)行的,而不管物理位置上這個(gè)main()放在什么地方。
4、主程序中的mDelay如果寫成mdelay就會(huì)編譯出錯(cuò),即C語言區(qū)分大小寫,這一點(diǎn)往往讓初學(xué)者非常困惑,尤其是學(xué)過一門其它語言的人,有人喜歡,有人不喜歡,但不管怎樣,你得遵守這一規(guī)定。
5、C語言書寫的格式自由,可以在一行寫多個(gè)語句,也可以把一個(gè)語句寫在多行。沒有行號(hào)(但可以有標(biāo)號(hào)),書寫的縮進(jìn)沒有要求。但是建議讀者自己按一定的規(guī)范來寫,可以給自己帶來方便。
6、每個(gè)語句和資料定義的最后必須有一個(gè)分號(hào),分號(hào)是C語句的必要組成部份。
7、可以用/*…..*/的形式為C程序的任何一部份作注釋。
Keil
C也支持C++風(fēng)格的注釋,就是用“//”引導(dǎo)的后面的語句是注釋,例:P1_0=!P1_0;
//取反P1.0
這種風(fēng)格的注釋,只對(duì)本行有效,所以不會(huì)出現(xiàn)上面的問題,而且書寫比較方便,所以在只需要一行注釋的時(shí)候,我們往往采用這種格式。但要注意,只有Keil
C支持這種格式,早期的Franklin
C以及PC機(jī)上用的TC都不支持這種格式的注釋,用上這種注釋,編譯時(shí)通不過,會(huì)報(bào)告編譯錯(cuò)誤。
11.2C51的數(shù)據(jù)結(jié)構(gòu)C51的常量與變量
其值不能改變的量稱為常量。常量可以有不同的數(shù)據(jù)類型。如0,1,2,-3為整型常量;4.6,-1.23等為實(shí)型常量;’a’、‘、’為字符型常量。可以用一個(gè)標(biāo)識(shí)符號(hào)代表一個(gè)常量。在程序運(yùn)行中,其值可以改變的量稱為變量。一個(gè)變量主要由兩部分構(gòu)成:一個(gè)是變量名,一個(gè)是變量值。每個(gè)變量都有一個(gè)變量名,在內(nèi)存中占據(jù)一定的存儲(chǔ)單元(地址),并在該內(nèi)存單元中存放該變量的值。
#defineCONST60main(){intvar,res;var=20;res=var*CONSTprintf(“res=%d\n”,res);}程序運(yùn)行結(jié)果:res=1200在程序開頭#defineCONST60這一行定義了一個(gè)符號(hào)常量CONST,其值為60。這樣在后面的程序中,凡是出現(xiàn)CONST的地方,都代表常量60。
常量變量11.3C51的運(yùn)算符和表達(dá)式1.賦值運(yùn)算符和表達(dá)式變量=表達(dá)式;例如:tmp=9; /*將常數(shù)9賦給變量tmp*/i=j(luò)=8; /*將常數(shù)8同時(shí)賦給變量i和j*/C51提供了10種復(fù)合運(yùn)算符:+=、-=、*=、/=、%=、<<=、>>=、&=、^=、!=。
2.算術(shù)運(yùn)算符和算術(shù)表達(dá)式C51有+、-、*、/、%五種運(yùn)算符3.關(guān)系運(yùn)算符
4.邏輯運(yùn)算符C語言中有3種邏輯運(yùn)算符:(1)邏輯非(?。?(2)邏輯與(&&) (3)邏輯或(||) 5.逗號(hào)運(yùn)算符在C51語言中,逗號(hào)“,”是一個(gè)特殊的運(yùn)算符,可以用它將兩個(gè)(或多個(gè))表達(dá)式連接起來,稱為逗號(hào)表達(dá)式。6.條件運(yùn)算符表達(dá)式“?:”是C51中唯一的三目運(yùn)算符,要求有3個(gè)運(yùn)算對(duì)象,它將三個(gè)表達(dá)式連接構(gòu)成一個(gè)條件表達(dá)式。7.自增和自減運(yùn)算符C51語言中,除了基本的加、減、乘、除運(yùn)算符之外,還提供一種特殊的運(yùn)算符:“++”自增運(yùn)算符;“--”自減運(yùn)算符。8.指針和地址運(yùn)算符指針在C51語言中指示變量的地址,另外,還可以定義一個(gè)指向某個(gè)變量的指針變量。為了表示指針變量和它所指向的變量地址之間的關(guān)系,C51語言提供了兩個(gè)專門的運(yùn)算符:取內(nèi)容(﹡)和取地址(&)。9.位運(yùn)算符位運(yùn)算符的作用是按位對(duì)變量進(jìn)行運(yùn)算,并不改變參與運(yùn)算的變量的值。
10.強(qiáng)制類型轉(zhuǎn)換運(yùn)算符強(qiáng)制類型轉(zhuǎn)換運(yùn)算符的作用是將表達(dá)式或變量的類型強(qiáng)制轉(zhuǎn)換成所指定的類型。在C51程序中進(jìn)行算術(shù)運(yùn)算時(shí),編譯器自動(dòng)處理數(shù)據(jù)類型轉(zhuǎn)換。當(dāng)自動(dòng)類型轉(zhuǎn)換不能實(shí)現(xiàn)目的時(shí),可以使用強(qiáng)制類型轉(zhuǎn)換。強(qiáng)制類型轉(zhuǎn)換的一般格式為:(類型名)(表達(dá)式)例如: (double)a /*將a轉(zhuǎn)換成double類型*/(int)(x+y) /*將x+y的值轉(zhuǎn)換成整型*/11.3.2運(yùn)算符的優(yōu)先級(jí)和結(jié)合性在表達(dá)式中,不同運(yùn)算符連接的對(duì)象的運(yùn)算順序不完全按照表達(dá)式中書寫的先后順序進(jìn)行的,各運(yùn)算符參與運(yùn)算的先后順序不僅要遵守運(yùn)算符優(yōu)先級(jí)別的規(guī)定,還要受運(yùn)算符結(jié)合性的制約。
11.4C51的存儲(chǔ)結(jié)構(gòu)11.4.1存儲(chǔ)區(qū)域8051單片機(jī)有4個(gè)存儲(chǔ)空間:片內(nèi)程序存儲(chǔ)空間,片外程序存儲(chǔ)空間,片內(nèi)數(shù)據(jù)存儲(chǔ)空間和片外數(shù)據(jù)存儲(chǔ)空間。11.4.2存儲(chǔ)模式1.Small模式2.緊湊模式(Compact)模式3.Large模式4.混合存儲(chǔ)模式11.5C51的基本程序結(jié)構(gòu)1.If語句
(1)If(條件表達(dá)式)
{動(dòng)作}
如果條件表達(dá)式的值為真(非零的數(shù)),則執(zhí)行{}內(nèi)的動(dòng)作,如果條件表達(dá)式為假,則略過
該動(dòng)作繼續(xù)往下執(zhí)行。
(2)If(條件表達(dá)式)
{動(dòng)作1}
else
{動(dòng)作2}
如果條件表達(dá)式的值為真(非零的數(shù)),則執(zhí)行動(dòng)作1,(則略過else)如果條件表達(dá)式為假,則執(zhí)行動(dòng)作2。
(3)If(條件表達(dá)式1)
{
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)生評(píng)教與反饋實(shí)施方案計(jì)劃
- 靜脈治療報(bào)告
- 統(tǒng)編版小學(xué)語文二年級(jí)下冊(cè)《語文園地三》精美課件
- 第四單元 《平行四邊形的認(rèn)識(shí)》教學(xué)設(shè)計(jì)-2024-2025學(xué)年四年級(jí)數(shù)學(xué)上冊(cè)青島版(五四學(xué)制)
- 養(yǎng)老床位建設(shè)服務(wù)方案(技術(shù)方案)
- 老年骨折手術(shù)護(hù)理
- 放射科護(hù)理相關(guān)知識(shí)課件
- 培訓(xùn)課件知識(shí)產(chǎn)權(quán)保護(hù)
- 2025年湛江道路客貨運(yùn)輸從業(yè)資格證模擬考試下載
- 2025年上海貨運(yùn)從業(yè)資格證模擬試題答案大全
- 課題申報(bào)書:湖北教育援疆在文化潤疆中的作用發(fā)揮研究
- 巨量千川營銷師(初級(jí))認(rèn)證考試復(fù)習(xí)題及答案
- 《佛跳墻英文介紹》課件
- 《特斯拉報(bào)告分析》課件
- 2025年小學(xué)五年級(jí)數(shù)學(xué)(北京版)-家庭生活中的碳排放-1教案
- 2024年12月管理體系認(rèn)證基礎(chǔ)考試真題及答案
- 抖音直播手冊(cè)【新人必看】
- 延安大學(xué)《算法設(shè)計(jì)與分析》2022-2023學(xué)年期末試卷
- 電力系統(tǒng)信號(hào)分析與處理課程教學(xué)大綱 (一)
- 產(chǎn)品質(zhì)量知識(shí)培訓(xùn)課件
- 醫(yī)療安全升級(jí):2024年安全輸液管理
評(píng)論
0/150
提交評(píng)論