版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
單片機的C語言應用程序設計1C51數據類型及在51中的存儲方式
2C51數據的存儲類型與51存儲結構351特殊功能寄存器(SFR)的C51定義451并行接口的C51定義5位變量的C51定義6中斷應用的C語言編程7定時器/計數器的應用編程851片外擴展的C語言編程951機串行通信的C語言編程10鍵盤和數碼顯示人機交互的C語言編程1.C51數據類型及在51中的存儲方式1.1C51的數據類型C51編譯器具體支持的數據類型有:位型(bit)、無符號字符(unsignedchar)、有符號字符(singedchar)、無符號整型(unsignedint)、有符號整型(signedint)、無符號長整型(unsignedlong)、有符號長整型(signedlong)、浮點型(float)和指針類型等。C51的數據類型數據類型長度(bit)長度(byte)值域bit110,1unsignedchar810~255signedchar81–128~127unsignedint1620~65535signedint162–32768~32767unsignedlong3240~4294967295signedlong324–2147483648~2147483647float324±1.176E–38~±3.40E+38(6位數字)double648±1.176E–38~±3.40E+38(10位數字)一般指針243存儲空間0~655351.2C51數據的存儲類型與51存儲結構C51存儲類型與MCS-51存儲空間的對應關系存儲類型與存儲空間的對應關系data直接尋址片內數據存儲區(qū),訪問速度快(128字節(jié))bdata可位尋址片內數據存儲區(qū),允許位與字節(jié)混合訪問(16字節(jié))idata間接尋址片內數據存儲區(qū),可訪問片內全部RAM地址空間(256字節(jié))pdata分頁尋址片外數據存儲區(qū)(256字節(jié))由MOV@Ri訪問(i=0,1)xdata片外數據存儲區(qū)(64KB)由MOVX@DPTR訪問code程序存儲器64KB空間,由MOVC@DPTR訪問C51存儲類型及其數據長度和值域存儲類型長度(bit)長度(byte)值域范圍data810~255idata810~255pdata810~255xdata1620~65535code1620~65535帶存儲類型的變量的定義的一般格式為數據類型存儲類型變量名帶存儲類型的變量定義舉例:chardatavar1;bitbdataflags;floatidatax,y,z;unsignedintpdatavar2;unsignedcharvector[3][4];1.351特殊功能寄存器(SFR)的C51定義MCS-51單片機中,除了程序計數器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器(SFR),分散在片內RAM區(qū)的高128字節(jié)中,地址范圍為80H~0FFH。SFR中有11個寄存器具有位尋址能力,它們的字節(jié)地址都能被8整除,即字節(jié)地址是以8或0為尾數的。為了能直接訪問這些SFR,C51提供了一種自主形式的定義方法,這種定義方法與標準C語言不兼容,只適用于對MCS-51系列單片機進行C語言編程。特殊功能寄存器C51定義的一般語法格式如下: sfrsfr-name=intconstant;"sfr"是定義語句的關鍵字,其后必須跟一個MSC-51單片機真實存在的特殊功能寄存器名,"="后面必須是一個整型常數,不允許帶有運算符的表達式,是特殊功能寄存器"sfr-name"的字節(jié)地址,這個常數值的范圍必須在SFR地址范圍內,位于0x80~0xFF。例如:sfrSCON=0x98; /*串口控制寄存器地址98H*/sfrTMOD=0x89; /*定時器/計數器方式控制寄存器地址89H*/對于位尋址的SFR中的位,C51的擴充功能支持特殊位的定義,像SFR一樣不與標準C兼容,使用“sbit”來定義位尋址單元。有三種表達方式第一種格式:sbitbit-name=sfr-name^intconstant;"sbit"是定義語句的關鍵字,后跟一個尋址位符號名(該位符號名必須是MCS-51單片機中規(guī)定的位名稱),"="后的"sfr-name"必須是已定義過的SFR的名字,"^"后的整常數是尋址位在特殊功能寄存器"sfr-name"中的位號,必須是0~7范圍中的數。例如:sfrPSW=0xD0; /*定義PSW寄存器地址為D0H*/sbitOV=PSW^2; /*定義OV位為PSW.2,地址為D2H*/sbitCY=PSW^7; /*定義CY位為PSW.7,地址為D7H*/第二種格式:sbitbit-name=intconstant^intconstant;"="后的intconstant為尋址地址位所在的特殊功能寄存器的字節(jié)地址,"^"符號后的intconstant為尋址位在特殊功能寄存器中的位號。例如:sbitOV=0XD0^2; /*定義OV位地址是D0H字節(jié) 中的第2位*/sbitCY=0XD0^7; /*定義CY位地址是D0H字節(jié)中 的第7位*/第三種格式:sbitbit-name=intconstant;"="后的intconstant為尋址位的絕對位地址。例如:sbitOV=0XD2; /*定義OV位地址為D2H*/sbitCY=0XD7; /*定義CY位地址為D7H*/特殊功能位代表了一個獨立的定義類,不能與其它位定義和位域互換。1.451并行接口的C51定義MCS-51系列單片機并行I/O接口除了芯片上的4個I/O口(P0~P3)外,還可以在片外擴展I/O口。MCS-51單片機I/O口與數據存儲器統(tǒng)一編址,即把一個I/O口當作數據存儲器中的一個單元來看待。對于MCS-51片內I/O口按特殊功能寄存器方法定義。例如:sfrP0=0x80;/*定義P0口,地址為80H*/sfrP1=0x90;/*定義P1口,地址為90H*/對于片外擴展I/O口,則根據硬件譯碼地址,將其視作為片外數據存儲器的一個單元,使用#define語句進行定義。例如#include<absacc.h>#definePORTAXBYTE[0xFFC0]absacc.h是C51中絕對地址訪問函數的頭文件,將PORTA定義為外部I/O口,地址為FFC0H,長度為8位。一旦在頭文件或程序中對這些片外I/O口進行定義后,在程序中就可以自由使用變量名與其實際地址的聯(lián)系,以便使程序員能用軟件模擬51的硬件操作。1.551內部資源使用的C語言編程(1)中斷應用的C語言編程C51編譯器支持在C源程序中直接開發(fā)中斷程序。中斷服務程序是通過按規(guī)定語法格式定義的一個函數。中斷服務程序的函數定義的語法格式如下:返回值函數名([參數])interruptm[usingn]{
}…MCS-51中斷源編號編號中斷源入口地址0外部中斷00003H1定時器/計數器0000BH2外部中斷10013H3定時器/計數器1001BH4串行口中斷0023H
usingn選項用于實現工作寄存器組的切換,n是中斷服務子程序中選用的工作寄存器組號(0~3)。在許多情況下,響應中斷時需保護有關現場信息,以便中斷返回后,能使中斷前的源程序從斷點處繼續(xù)正確地執(zhí)行下去。這在MCS-51單片機中,能很方便地利用工作寄存器組的切換來實現。即在進入中斷服務程序前的程序中使用一組工作寄存器,進入中斷服務程序后,由"usingn"切換到另一組寄存器,中斷返回后又恢復到原寄存器組。這樣互相切換的兩組寄存器中的內容彼此都沒有被破壞。擴展多個中斷源例下圖示是利用優(yōu)先權解碼芯片,在單片機8031的一個外部中斷INT1上擴展多個中斷源的原理電路圖。圖中是以開關閉合來模擬中斷請求信號。當有任一中斷源產生中斷請求,能給8031的INT1引腳送一個有效中斷信號,由P1的低3位可得對應中斷源的中斷號。在中斷服務程序中僅設置標志,并保存I/O口輸入狀態(tài)。C51編譯器提供定義特定MCS-51系列成員的寄存器頭文件。MCS-51頭文件為reg51.h。C51程序如下:#include<reg51.h>unsignedcharstatus;bitflag;voidservice_int1()interrupt2using2 /*INT1中斷服務程序,使用第2組工 作寄存器*/{flag=1; /*設置標志*/status=p1; /*存輸入口狀態(tài)*/}voidmain(void){IP=0x04; /*置INT1為高優(yōu)先級中斷*/IE=0x84; /*INT1開中斷,CPU開中斷*/for(;;){if(flag) /*有中斷*/{switch(status) /*根據中斷源分支*/{case0:break; /*處理IN0*/case1:break; /*處理IN1*/case2:break; /*處理IN2*/case3:break; /*處理IN3*/…default:;}flag=0; /*處理完成清標志*/}}}
1.6定時器/計數器(T/C)應用的C語言編程例設單片機的fosc=12MHz晶振,要求在P1.0腳上輸出周期為2ms的方波。周期為2ms的方波要求定時時間隔1ms,每次時間到P1.0取反。機器周期=12/fosc=1μs需計數次數=1000/(12/fosc)=1000/1=1000由于計數器是加1計數,為得到1000個計數之后的定時器溢出,必須給定時器置初值為-1000(即1000的補數)。(1)用定時器0的方式1編程,采用查詢方式,程序如下:
#include<reg51.h>sbitP1_0=P1^0;voidmain(void){TMOD=0x01; /*設置定時器1為非門控制方式1*/TR0=1; /*啟動T/C0*/for(;;){TH0=-(1000/256); /*裝載計數器初值*/TL0=-(1000%256);while(!TF0); /*查詢等待TF0置位*/P1_0=!P1_0; /*定時時間到P1.0反相*/TF0=0; /*軟件清TF0*/}}(2)用定時器0的方式1編程,采用中斷方式。程序如下:#include<reg51.h>sbitP1_0=P1^0;voidtime(void)interrupt1using1/*T/C0中斷服務程序入口*/{P1_0=!P1_0; /*P1.0取反*/TH0=-(1000/256);
TL0=-(1000%256); /*重新裝載計數初值*/}voidmain(void){TMOD=0x01; /*T/C0工作在定時器非門控制方式1*/P1_0=0;TH0=-(1000/256); /*預置計數初值*/TL0=-(1000%256);EA=1; /*CPU中斷開放*/ET0=1; /*T/C0中斷開放*/TR0=1; /*啟動T/C0開始定時*/do{}while(1); /*等待中斷*/}例采用10MHz晶振,在P1.0腳上輸出周期為2.5s,占空比20%的脈沖信號。10MHz晶振,使用定時器最大定時幾十毫秒。取10ms定時,周期2.5s需250次中斷,占空比20%,高電平應為50次中斷。10ms定時,晶振fosc=10MHz。#include<reg51.h>#defineucharunsignedcharucharperiod=250;ucharhigh=50;timer0()interrupt1using1 /*T/C0中斷服務程序*/{TH0=-8333/256; /*重置計數值*/TL0=-8333%256;if(++time==high)P1=0; /*高電平時間到變低*/elseif(time==period) /*周期時間到變高*/{time=0;P1=1;}}main(){TMOD=0x01; /*定時器0方式1*/TH0=-8333/256; /*預置計數初值*/TL0=-8333%256;EA=1; /*開CPU中斷*/ET0=1; /*開T/C0中斷*/TR0=1; /*啟動T/C0*/P1=1;do{}while(1);}中斷服務程序流程圖
1.751數據采集的C語言編程例ADC0809與8031接口的數據采集程序舉例。程序如下:#include<absacc.h>#include<reg51.h>#defineucharunsignedchar#defineIN0XBYTE[0x7ff8] /*設置AD0809的通道0地址*/sbitad_busy=P3^3; /*即EOC狀態(tài)*/voidad0809(ucharidata*x) /*采樣結果放指針中的A/D采集函數*/{uchari;ucharxdata*ad_adr;ad_adr=&IN0;for(i=0;i<8;i++) /*處理8通道*/{*ad_adr=0; /*啟動轉換*/ i=i; /*延時等待EOC變低*/i=i;while(ad_busy==0);/*查詢等待轉換結束*/x[i]=*ad_adr; /*存轉換結果*/ad_adr++; /*下一通道*/}}voidmain(void){staticucharidataad[10];ad0809(ad); /*采樣AD0809通道的值*/}1.851輸出控制的C語言編程例8031與DAC0832雙緩沖接口的數據轉換程序舉例。將data1和data2數據同時轉換為模擬量的C51程序如下:#include<absacc.h>#include<reg51.h>#defineINPUTR1XBYTE[0x8fff]#defineINPUTR2XBYTE[0xa7ff]#defineDACRXBYTE[0x2fff]#defineucharunsignedcharvoiddac2b(data1,data2)uchardata1,data2;{INPUTR1=data1; /*送數據到一片0832*/INPUTR2=data2; /*送數據到另一片0832*/DACR=0; /*啟動兩路D/A同時轉換*/}例8031與DAC0832單緩沖區(qū)接口的數據轉換舉例。按片選線確定FFFEH為DAC0832的端口地址。使運行輸出端輸出一個鋸齒波電壓信號的C51程序如下:#include<reg51.h>#defineDA0832XBYTE[0xfffe]#defineucharunsignedchar#defineuintunsignedintvoidmain(void){uchari;while(1){for(i=0;i<=255;i++) /*形成鋸齒波輸出值,最大值為255*/DA0832=i; /*D/A轉換輸出*/}}1.951機間通信的C語言編程點對點的串行異步通信1.通信雙方的硬件連接圖7.178031間RS—232C電平信號的傳2.通信雙方的約定3.點對點通信編程點對點通信雙方基本等同,只是人為規(guī)定一個為發(fā)送,一個為接收。要求兩機串行口的波特率相同,因而發(fā)送和接收方串行口的初始化相同。可編制含有初始化函數、發(fā)送函數接收函數的程序,在主函數中根據程序的發(fā)送、接收設置TR,采用條件判別決定使用發(fā)送函數還是接收函數。這樣點對點通信的雙方都可運行此程序,只需在程序運行之前人為設置選擇TR,一個令TR=0,一個令TR=1,然后分別編譯,在兩機上分別裝入,同時運行。點對點通信的程序如下:#include<reg51.h>#defineucharunsignedchar#defineTR1 /*發(fā)送接收差別值TR=0發(fā)送*/ucharidatabuf[10];ucharpf;voidinit(void) /*串行口初始化*/{TMOD=0x20; /*設T/C1為定時方式2*/TH1=0xe8; /*設定波特率*/TL1=0xe8;PCON=0x00;TR1=1; /*啟動T/C1*/SCON=0x50; /*串行口工作在方式1*/}voidsend(ucharidata*d){uchari;do{SBUF=0xaa; /*發(fā)送聯(lián)絡信號*/while(TI==0); /*等待發(fā)送出去*/TI=0;while(RI==0); /*等待B機回答*/RI=0;}while((SBUF^0xbb)!=0); /*B機未準備好,繼續(xù)聯(lián)絡*/do{pf=0; /*清校驗和*/for(i=0;i<16;i++){SBUF=d[i]; /*發(fā)送一個數據*/pf+=d[i]; /*求校驗和*/while(TI==0);TI=0;}SBUF=pf; /*發(fā)送校驗和*/while(TI==0);TI=0;while(RI==0);RI=0; /*等待B機回答*/}while(SBUF!=0); /*回答出錯,則重發(fā)*/}
voidreceive(ucharidata*d){uchari;do{while(RI==0);RI=0;} while((SBUF^0xaa)!=0); /*判A機請求否*/SBUF=0xbb; /*發(fā)應答信號*/ while(TI==0);TI=0;while(1){pf=0; /*清校驗和*/for(i=0;i<16;i++){while(RI==0);RI=0;d[i]=SBUF; /*接收一個數據*/pf+=d[i]; /*求校驗和*/}while(RI==0);RI=0; /*接收A機校驗和*/if((SBUF^pf)==0) /*比較校驗和*/{SBUF=0x00;break;} /*校驗和相同發(fā)"00"*/else{SBUF=0xff; /*出錯發(fā)"FF",重新接收*/ while(TI==0);TI=0;}}}voidmain(void){init();if(TR==0){send(buf);}else{receive(buf);}}1.10鍵盤和數碼顯示人機交互的C語言編程1行列式鍵盤與8031的接口鍵盤輸入信息的主要過程是:(1)單片機判斷是否有鍵按下。(2)確定按下的是哪一個鍵。(3)把此步驟代表的信息翻譯成計算機所能識別的代碼,如ASCII或其它特征碼。8031與行列式鍵盤的接口例174×4鍵盤的掃描程序。掃描程序查詢的內容為:(1)查詢是否有鍵按下。首先單片機向行掃描P1.0~P1.3輸出全為"0"掃描碼F0H,然后從列檢查口P1.4~P1.7輸入列掃描信號,只要有一列信號不為"1",即P1口不為F0H,則表示有鍵按下。接著要查出按下鍵所在的行、列位置。(2)查詢按下鍵所在的行列位置。單片機將得到的信號取反,P1.4~P1.7中的為1的位便是鍵所在的列。接下來要確定鍵所在的行,需要進行逐行掃描。單片機首先使P1.0為"0",P1.1~P1.7為"1",即向P1口發(fā)送掃描碼FEH,接著輸入列檢查信號,若全為"1",表示不在第一行。接著使P1.1接地,其余為"1",再讀入列信號……這樣逐行發(fā)"0"掃描碼,直到找到按下鍵所在的行,將該行掃描碼取反保留。當各行都掃描以后仍沒有找到,則放棄掃描,認為是鍵的誤動作。(3)對得到的行號和列號譯碼,得到鍵值。(4)鍵的抖動處理。當用手按下一個鍵時,往往會出現所按鍵在閉合位置和斷開位置之間跳幾下才穩(wěn)定到閉合狀態(tài)的情況。在釋放一個鍵時,也會出現類似的情況,這就是鍵抖動,抖動的持續(xù)時間不一,通常不會大于10ms,若抖動問題不解決,就會引起對閉合鍵的多次讀入,對于鍵抖動最方便的解決方法就是當發(fā)現有鍵按下后,不是立即進行逐行掃描,而是延時10ms后再進行。由于鍵按下的時間持續(xù)上百毫秒,延時后再也不遲。掃描函數的返回值為鍵特征碼,若無鍵按下,返回值為0。程序如下:#include<reg51.h
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年手機行業(yè)退貨三包服務規(guī)范合同樣本3篇
- 2025年物流運輸掛靠車輛運輸合同范本3篇
- 砌塊工程施工方案
- 2025年行政訴訟上訴狀編寫規(guī)范:全面指導版3篇
- 二零二五版科技園區(qū)研發(fā)樓租賃續(xù)約4篇
- 二零二五版門店合伙人風險管理與責任承擔合同4篇
- 2024年中級經濟師考試題庫含答案(輕巧奪冠)
- 浮筏施工方案
- 2025年度養(yǎng)老產業(yè)項目貸款擔保合同范文3篇
- 2025年度個人網絡安全服務買賣合同(數據保護)4篇
- 《健康體檢知識》課件
- 部編版語文五年級下冊 第一單元 專項訓練課外閱讀(含答案)
- 蘇少版七年級美術下冊 全冊
- 名表買賣合同協(xié)議書
- JTG-T-F20-2015公路路面基層施工技術細則
- 2024年遼寧石化職業(yè)技術學院單招職業(yè)適應性測試題庫附答案
- 中西方校服文化差異研究
- 《子宮肉瘤》課件
- 《準媽媽衣食住行》課件
- 給男友的道歉信10000字(十二篇)
- 客人在酒店受傷免責承諾書范本
評論
0/150
提交評論