單片機C語言編程_第1頁
單片機C語言編程_第2頁
單片機C語言編程_第3頁
單片機C語言編程_第4頁
單片機C語言編程_第5頁
已閱讀5頁,還剩56頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、單片機C語言編程主講教師:廉哲QQ:17434548電話公室:綜合樓C31851單片機硬件結(jié)構(gòu)C51基礎(chǔ)知識及其基本程序設(shè)計C51函數(shù)、數(shù)組、指針定義及應用單片機內(nèi)部資源及其C語言編程單片機資源擴展及其C語言編程綜合程序設(shè)計考試課程主要內(nèi)容: 四 C51編程設(shè)計4.1 MCS-51內(nèi)部資源使用的C語言編程4.2 MCS-51片外擴展的C語言編程4.3 頻率量測量的C語言編程4.1 MCS-51內(nèi)部資源使用的C語言編程4.1.1 中斷應用的C語言編程 C51編譯器支持在C源程序中直接開發(fā)中斷程序。中斷服務程序是通過按規(guī)定語法格式定義的一個函數(shù)。 中斷服務程序的函數(shù)定義的

2、語法格式如下: 返回值 函數(shù)名(參數(shù)) interrupt musing n using n 選項用于實現(xiàn)工作寄存器組的切換,n是中斷服務子程序中選用的工作寄存器組號(0 3)。在許多情況下,響應中斷時需保護有關(guān)現(xiàn)場信息,以便中斷返回后,能使中斷前的源程序從斷點處繼續(xù)正確地執(zhí)行下去。這在MCS-51單片機中,能很方便地利用工作寄存器組的切換來實現(xiàn)。即在進入中斷服務程序前的程序中使用一組工作寄存器,進入中斷服務程序后,由using n切換到另一組寄存器,中斷返回后又恢復到原寄存器組。這樣互相切換的兩組寄存器中的內(nèi)容彼此都沒有被破壞。圖 4.1 擴展多個中斷源 例1 圖7.5所示是利用優(yōu)先權(quán)解碼芯

3、片,在單片機8031的一個外部中斷INT1上擴展多個中斷源的原理電路圖。圖中是以開關(guān)閉合來模擬中斷請求信號。當有任一中斷源產(chǎn)生中斷請求,能給8031的INT1引腳送一個有效中斷信號,由P1的低3位可得對應中斷源的中斷號。for(; ;) if(flag) /* 有中斷 */ switch(status) /* 根據(jù)中斷源分支 */ case 0 : break ; /* 處理IN0 */ case 1 : break ; /* 處理IN1 */ case 2 : break; /* 處理IN2 */ case 3 : break; /* 處理IN3 */ default : ; flag=0

4、; /* 處理完成清標志 */ 4.1.2 定時器/計數(shù)器(T/C)應用的C語言編程 例2 設(shè)單片機的fosc=12 MHz晶振,要求在P1.0腳上輸出周期為2 ms的方波。 周期為2 ms的方波要求定時時間隔1 ms,每次時間到P1.0取反。 機器周期=12/fosc=1 s 需計數(shù)次數(shù)=1000/(12/fosc)=1000/1=1000 由于計數(shù)器是加1計數(shù),為得到1000個計數(shù)之后的定時器溢出,必須給定時器置初值為-1000(即1000的補數(shù))。(1) 用定時器0的方式1編程,采用查詢方式,程序如下: # include sbit P1_0=P10 ; void main(void)

5、TMOD=0 x01 ; /* 設(shè)置定時器1為非門控制方式1*/ TR0=1 ; /* 啟動 T/C0 */ for( ; ;) TH0= -(1000/256) ; /* 裝載計數(shù)器初值 */ TL0= -(1000%256) ; do while (!TF0) ; /* 查詢等待TF0置位 */ P1_0=!P1_0; /* 定時時間到P1.0反相 */ TF0=0; /* 軟件清 TF0 */ (2) 用定時器0的方式1編程,采用中斷方式。程序如下: # include sbit P1_0=P10 ; void time (void) interrupt 1 using 1 /* T/C

6、0中斷服務程序入口 */ P1_0=!P1_0 ; /* P1.0取反 */ TH0= -(1000/256); / * 重新裝載計數(shù)初值 */ void main( void ) TMOD=0 x01 ; /* T/C0工作在定時器非門控制方式1 */ P1_0=0; TH0= -(1000/256 ); /* 預置計數(shù)初值 */ TL0= -(1000%256) ; EA=1 ; /* CPU中斷開放 */ ET0= 1 ; /* T/C0中斷開放 */ TR0=1 ; /* 啟動T/C0開始定時 */ do while(1) ; /* 等待中斷 */ 例3 采用10 MHz晶振,在P1.

7、0腳上輸出周期為2.5 s,占空比20%的脈沖信號。 10 MHz晶振,使用定時器最大定時幾十毫秒。取10 ms定時,周期2.5 s需250次中斷,占空比20%,高電平應為50次中斷。 10 ms定時,晶振fosc=10 MHz。 需定時器計數(shù)次數(shù)=1010310/12=8333# include # define uchar unsigned charuchar period=250;uchar high=50;timer0( )interrupt 1 using 1 /* T/C0中斷服務程序 */TH0= - 8333/256 ; /* 重置計數(shù)值 */TL0= - 8333%256 ;

8、 if(+time=high)P1=0; /* 高電平時間到變低 */else if (time=period) /* 周期時間到變高 */time=0 ;P1=1 ; 圖2.2 中斷服務程序流程圖 產(chǎn)生一個占空比變化脈沖信號的程序,它產(chǎn)生的脈寬調(diào)制信號用于電機變速控制。# include # define uchar unsigned char # define uint unsigned int unchar time,status,percent,period;bit one_round;uint oldcount,target=500;void pulse (void) interru

9、pt 1 using 1 /* T/C0中斷服務程序 */ TH0= - 833/256 ; /* 1ms - -10 MHz */ newcount ; newcount. byte. hi=TH1; newcount .byte .lo=TL1 ; period=newcount .word - oldcount ; /* 測得周期 */ oldcount=newcount .word ; one_round=1; /* 每轉(zhuǎn)一圈,引起中斷,設(shè)置標志 */ void main ( void ) IP=0 x04 ; /* 置INT1為高位優(yōu)先級 */ TMOD= 0 x11 ; /* T0

10、,T1 16位方式 */ TCON=0 x54 ; /* T0,T1運行,IT1邊沿觸發(fā) */ TH1=0;TL1=0; /* 設(shè)置初始計數(shù)值 */ IE=0 x86 ; /* 允許中斷EX1,ET0 */ for (; ;) if (one_round ) /* 每轉(zhuǎn)一圈,調(diào)整 */ if ( period target ) if (percent 0 ) - -percent ; / * 占空比減 */ one_round=0 ; 4.1.3 串行口使用的C語言編程 例4 單片機fosc=11.0592 MHz,波特率為9600,各設(shè)置32字節(jié)的隊列緩沖區(qū)用于發(fā)送接收。設(shè)計單片機和終端或另

11、一計算機通信的程序。 單片機串行口初始化成9600波特,中斷程序雙向處理字符,程序雙向緩沖字符。背景程序可以放入和提取在緩沖區(qū)的字符串,而實際傳入和傳出SBUF的動作由中斷完成。 Loadmsg 函數(shù)加載緩沖數(shù)組,標志發(fā)送開始。緩沖區(qū)分發(fā)(t)和收(r)緩沖,緩沖區(qū)通過兩種指示(進in和出out)和一些標志(滿full,空empty,完成done)管理。隊列緩沖區(qū)32字節(jié)接收緩沖(r_buf)區(qū)滿,不能再有字符插入。當t_in=t_out,發(fā)送緩沖區(qū)(t_buf)空,發(fā)送中斷清除,停止UART請求。具體程序如下:# include # define uchar unsigned char uc

12、har xdata r_buf32 ; /* item1 */uchar xdata t_buf32 ;uchar r_in , r_out , t_in , t_done ; /* 隊列指針 */bit r_full , t_empty , t_done ; /* item2 */code uchar m = this is a test program rn ;serial ( ) interrupt 4 using 1 /* item3 */ if( RI & r_full ) r_bufr_in=SBUF ; RI=0 ; r_in= +r_in & ox1f ; if ( r_in=

13、 =r_out ) r_full=1; else if (TI & t_empty ) SBUF=t_buf t_out ; TI=0; t_out = + t_out & 0 x1f ; i f ( t_out= =t_in ) t_empty=1 ; else if (TI ) TI=0; t_done=1 ; void loadmsg (uchar code * msg ) /* item4 */ while (*msg !=0 )& ( t_in+1)t_out ) & 0 x1f ) !=0 ) / *測試緩沖區(qū)滿 */ t_ buf t_in= * msg ; msg+ ; t_i

14、n = + t_in & 0 x1f ; if ( t_done ) TI = 1 ; t_empty =t_done =0 ; /* 完成重新開始 */ main ( ) /* item7 */ TMOD=0 x20 ; /* 定時器1方式2 */ TH1=0 xfd ; /* 9600波特11.0592 MHz */ TCON=0 x40 ; /* 啟動定時器1 */ SCON=0 x50 ; /* 允許接收 */ IE=0 x90 ; /* 允許串行口中斷 */ t_empty=t_done=1 ; r_full =0 ; r_out=t_in =0 ; r_ in=1 ; /* 接收緩

15、沖和發(fā)送緩沖置空 */ for ( ; ; ) loadmsg ( & m ) ; processmsg ( ); item1 :背景程序放入和提取字符隊列緩沖區(qū)。 item2 :緩沖區(qū)狀態(tài)標志。 item3 :串行口中斷服務程序,從RI,TI判別接收或發(fā)送中斷,由軟件清除。判別緩沖區(qū)狀態(tài)(滿full,空empty)和全部發(fā)送完成(done)。 item4 :此函數(shù)把字符串放入發(fā)送緩沖區(qū),準備發(fā)送。 item5 :接受字符的處理程序,實際應用自定義。 item6 :此函數(shù)逐一處理接收緩沖區(qū)的字符。 item7 :主程序即背景程序,進行串行口的初始化,載入字符串,處理接收的字符串。圖4.3 80

16、31擴展8255與打印機接口的電路 向打印機輸出字符串WELCOME的程序如下:# include # include # define uchar unsigned char # define COM8255 XBYTE0 x007f /* 命令口地址 */# define PA8255 XBYTE 0 x007c /* 口A地址 */# define PC8255 XBYTE 0 x007e /* 口C 地址 */void toprn ( uchar *p ) / * 打印字符串函數(shù) */ while ( * p!= 0) while ( 0 x80 & PC8255 )! =0 ) ;

17、/* 查詢等待打印機的BUSY狀態(tài)*/ PA8255 = * p ; /* 輸出字符 */ COM8255 = 0 x00 ; /* 模擬STB脈沖 */ COM8255=0 x01 ; p+ ; void main ( void ) uchar idata prn = WELCOME; /* 設(shè)測試用字符串 */ COM8255=0 x8e ; /* 輸出方式選擇命令 */ toprn ( prn ) ; /* 打印字符串 */ 例6 EPROM編程器。 由8031擴展1片EPROM2716、2片SRAM6116及1片8255構(gòu)成EPROM編程器,編程對象是EPROM2732。擴展編程系統(tǒng)中

18、2716用來存放固化用監(jiān)控程序,用戶的待固化程序放在2片6116中。8255的口A作編程器數(shù)據(jù)口,口B輸出2732的低8位地址,PC3PC0輸出2732高4位地址,PC7作2732啟動保持控制器與PGM連接。 譯碼地址為:6116(1):0800H;6116(2):1000H17FFH;8255的口A:07FCH;口B:07FDH;口C:07FEH;命令口:07FFH。 8255的口A、口B、口C均工作在方式0輸出,方式選擇命令字為80H;2732的啟動編程和停止編程,由PC7的復位/置位控制,當PC7=0時啟動編程,PC7=1時,編程無效。 EPROM編程如下所示,參數(shù)為RAM起始地址、EP

19、ROM起始地址和編程字節(jié)數(shù)。# include # include # define COM8255 XBYTE 0 x07ff # define PA8255 XBYTE 0 x07fc# define PB8255 XBYTE 0 x07fd # define PC8255 XBYTE 0 x07fe # define uchar unsigned char # define uint unsigned int void d1_ms ( unit x ) ;void program (ram , eprom , con )uchar xdata * ram ; /* RAM起始地址 */u

20、int eprom , con ; /* EPROM起始固化地址,固化長度 */ int i ; COM8255=0 x08 ; /* 送方式選擇命令字 */ COM8255=0 x0f ; /* PC7=1 */ for (i=0 ; icon ;i+ ) PA8255= * ram ; /* 固化內(nèi)容口A鎖存 */ PB8255=eprom % 256 ; /* 2732地址低8位 */ PC8255=eprom /256 ; /* 2732地址高4位 */ eprom + ; ram + ; COM8255=0 x0e ; /* PC7=0 */ d1_ms (50 ) ; COM825

21、5=0 x0f ; /* PC7=1 */ main ( ) program ( 0 x1000,0 x0000,0 x0100 ) ; 4.2.2 MCS-51數(shù)據(jù)采集的C語言編程例7 ADC0809與8031接口的數(shù)據(jù)采集程序舉例。圖2.4 ADC0809與8031的接口電路程序如下: # include # include # define uchar unsigned char # define IN0 XBYTE 0 x7ff8 /* 設(shè)置AD0809的通道0地址 */ sbit ad_busy =P33 ; /* 即EOC狀態(tài) */ void ad0809 ( uchar idat

22、a *x ) /* 采樣結(jié)果放指針中的A/D采集函數(shù) */ uchar i ; uchar xdata *ad_adr ; ad_adr= & IN0 ; for ( i=0 ; i8 ;i+ ) /* 處理8通道 */ *ad_adr=0 ; /* 啟動轉(zhuǎn)換 */ i=i ; /* 延時等待EOC變低 */ i=i ; while (ad_busy = =0 ) ; /* 查詢等待轉(zhuǎn)換結(jié)束 */ xi = * ad_adr ; /* 存轉(zhuǎn)換結(jié)果 */ ad_adr + ; /* 下一通道 */ void main ( void ) static uchar idata ad 10 ; ad0

23、809 ( ad ) ; /* 采樣AD0809通道的值 */ 例8 AD574與8031接口的數(shù)據(jù)采集程序舉例。圖2.5 AD574與8031的接口電路源程序如下:# include # inlucde # define uint unsigned int # define ADCOM XBYTE 0 xff7c /* 使A0=0 ,R/C=0, CS=0 */# define ADLO XBYTE 0 xff7f /* 使 R/C =1,A0=1, CS=0 */# define ADHI XBYTE 0 xff7d /* 使R/C=1,A0=0,CS =0 */sbit r = P3 7

24、 ;sbit w = P3 6 ;sbit adbusy = P1 0 ;uint ad574 ( void ) /* AD574轉(zhuǎn)換器 */ r = 0 ; /* 產(chǎn)生CE=1 */ w = 0 ; ADCOM = 0 ; /* 啟動轉(zhuǎn)換 */ while ( adbusy = =1 ) ; /* 等待轉(zhuǎn)換*/ return ( ( uint )(ADHI4 )+( ADLO &0 x0f ) ); /* 返回12位采樣值*/ main ( ) uint idata result ; result =ad574 ( ) ; /* 啟動AD574進行一次轉(zhuǎn)換,得轉(zhuǎn)換結(jié)果 */ 2.2.3 MC

25、S-51輸出控制的C語言編程例9 8031與DAC0832雙緩沖接口的數(shù)據(jù)轉(zhuǎn)換程序舉例。圖4.6 DAC 0832的雙緩沖接口電路將data1和data2數(shù)據(jù)同時轉(zhuǎn)換為模擬量的C51程序如下:# include # include # define INPUTR1 XBYTE 0 x8fff # define INPUTR2 XBYTE 0 xa7ff# define DACR XBYTE 0 x2fff # define uchar unsigned char void dac2b (data1 ,data2 )uchar data1 , data2 ; INPUTR1 = data1 ;

26、/* 送數(shù)據(jù)到一片0832 */ INPUTR2 = data2 ; /* 送數(shù)據(jù)到另一片0832 */ DACR= 0 ; /* 啟動兩路D/A 同時轉(zhuǎn)換 * /例10 8031與DAC0832單緩沖區(qū)接口的數(shù)據(jù)轉(zhuǎn)換舉例。圖4.7 DAC0832與8031 的單緩沖接口 按片選線確定FFFEH為DAC0832的端口地址。使運行輸出端輸出一個鋸齒波電壓信號的C51程序如下:# include # include # define DA0832 XBYTE 0 xfffe # define uchar unsigned char # define uint unsigned int void s

27、tair (void ) uchar i ; while ( 1 ) for ( i=0 ; i=255 ; i=I+ ) /* 形成鋸齒波輸出值,最大值為255 */ DA0832 = i ; /* D/A轉(zhuǎn)換輸出 */ 例11 8031與AD7521接口的數(shù)據(jù)轉(zhuǎn)換程序舉例。圖4.8 AD7521與8031的接口 使AD7521輸出梯形波的C51程序如下:# include # include # define DA7521L XBYTE0 x7fff # define DA7521H XBYTE0 xbfff # define UP 0 x010# define T 1000# defin

28、e uint unsigned int void dlms ( uint a );void stair(void) uint i ; for ( i=0 ; i=4095 ; i=i+UP ) /* 以階高增量增值,形成梯形波輸出值,最大4095*/ DA7521L= i % 256 ; /* 送低8位數(shù)據(jù)到第一級緩沖器 */ DA7521H= i /256 ; /* 送高4位數(shù)據(jù)到高4位緩沖器,同時送低8位到第二級 /* 緩沖轉(zhuǎn)換 */ dlms ( T ) ; /* 延時 */ 4.3 頻率量測量的C語言編程4.3.1 測量頻率法 測量頻率法的最簡單的接口電路,可將頻率脈沖直接連接到MCS

29、-51的T1端,將8031的T/C0用作定時器,T/C1用作計數(shù)器。在T/C0定時時間里,對頻率脈沖進行計數(shù)。T/C1的計數(shù)值便是單位定時時間里的脈沖個數(shù)。定時輸入脈沖 T圖2.10測量頻率中的脈沖丟失例12 帶同步控制的頻率測量。圖4.11 帶同步控制的頻率測量法接口 控制時,首先P1.0發(fā)一個清零負脈沖,使U1、U2兩個D觸發(fā)器復位,其輸出封鎖與門G1和G2。接著由P1.1發(fā)一個啟動正脈沖,其有效上升沿使U1=1,門G1被開放。之后,被測脈沖上升沿通過G2送T1計數(shù);同時U2輸出的高電平使INT0 =1,定時器0的門控GATE有效,啟動T/C0開始定時。直到定時結(jié)束時,從P1.0發(fā)一負脈沖

30、,清零 U2,封鎖G2,停止T/C1計數(shù),完成一次頻率采樣過程。 測量T/C定時時間為500 ms,這樣長的時間定時,先由T/C0定時100 ms,之后軟件5次中斷后的時間即為5100 ms=500 ms。中斷次數(shù)的計數(shù)值在msn中。 T/C0定時100 ms的計數(shù)初值:03B0H。計數(shù)器1采用16位計數(shù)。設(shè)T/C0為高優(yōu)先級,允許計數(shù)中斷過程定時中斷,即定時時間到就中止計數(shù)。tf為500 ms定時時間到標志。程序如下:#include #define uchar unsigned char#define uint unsigned int#define A 5 /*500 ms 的中斷次數(shù)*/sbit P1_0=P10;sbit P1_1=P11;uchar msn=A;bit idata tf=0; /*500 ms時間到標志*/uint count(void) P1_0=0 ; P1_0=1; /*產(chǎn)生清零用負脈沖*/ TMOD=0 x59 ; TH1=0 x00; TL1=0 x00;/* T/C1計數(shù)器 */ TH0=0 x3c ;TL0=0 xb0; /* T/C0定時器100 m

溫馨提示

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

最新文檔

評論

0/150

提交評論