單片機最小系統(tǒng)設(shè)計制作訓(xùn)練_第1頁
單片機最小系統(tǒng)設(shè)計制作訓(xùn)練_第2頁
單片機最小系統(tǒng)設(shè)計制作訓(xùn)練_第3頁
單片機最小系統(tǒng)設(shè)計制作訓(xùn)練_第4頁
單片機最小系統(tǒng)設(shè)計制作訓(xùn)練_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、. . . . 第3章 單片機最小系統(tǒng)設(shè)計制作訓(xùn)練3.1單片機最小系統(tǒng)設(shè)計制作3.1.1 單片機最小系統(tǒng)電路板硬件設(shè)計單片機的主要功能是負責(zé)整個系統(tǒng)的控制,不承擔(dān)復(fù)雜的數(shù)據(jù)處理任務(wù),因此在設(shè)計單片機最小系統(tǒng)時通常選用AT89C5l、AT89C52、AT89S51、AT89S52(S系列芯片支持ISP功能)等型號的8位單片機作為MCU。一個典型的單片機最小系統(tǒng)一般由時鐘電路、復(fù)位電路、片外RAM、片外ROM、按鍵、數(shù)碼管、液晶顯示器、外部擴展接口等部分組成,圖3.1 、圖3.2分別給出了單片機最小系統(tǒng)的結(jié)構(gòu)框圖、原理圖。圖3.1 單片機最小系統(tǒng)的結(jié)構(gòu)框圖圖3.2原理圖單片機最小系統(tǒng)時鐘、復(fù)位、譯

2、碼電路簡介1、時鐘源電路單片機部具有一個高增益反相放大器,用于構(gòu)成振蕩器。通常在引腳XTALl和XTAL2跨接石英晶體和兩個補償電容構(gòu)成自激振蕩器,結(jié)構(gòu)如圖2 中Y1、C16、C17??梢愿鶕?jù)情況選擇6MHz、12MHz或24MHz等頻率的石英晶體,補償電容通常選擇30pF左右的瓷片電容。2、復(fù)位電路單片機小系統(tǒng)采用上電自動復(fù)位和手動按鍵復(fù)位兩種方式實現(xiàn)系統(tǒng)的復(fù)位操作。上電復(fù)位要求接通電源后,自動實現(xiàn)復(fù)位操作。手動復(fù)位要求在電源接通的條件下,在單片機運行期間,用按鈕開關(guān)操作使單片機復(fù)位。其結(jié)構(gòu)如圖2 中R24、R26、C18和K17。上電自動復(fù)位通過電容C18充電來實現(xiàn)。手動按鍵復(fù)位是通過按鍵

3、將電阻R26與VCC接通來實現(xiàn)。3、地址譯碼電路最小系統(tǒng)上的全部硬件除EEPROM以外均是采用總線方式進行擴展的,每一個硬件均占用特定的物理地址。為了減少芯片的使用數(shù)量和降低PCB板布線的復(fù)雜度,本系統(tǒng)使用小規(guī)??删幊踢壿嬈骷礼AL代替74系列芯片實現(xiàn)譯碼電路。具體硬件見圖2 中U24。3.2 鍵盤顯示電路設(shè)計3.2.1鍵盤接口電路與程序設(shè)計單片機鍵盤通常使用機械觸點式按鍵開關(guān),其主要功能是把機械上的通斷轉(zhuǎn)換成為電氣上的邏輯關(guān)系。也就是說,它能提供標(biāo)準(zhǔn)的TTL邏輯電平,以便與通用數(shù)字系統(tǒng)的邏輯電平相容。小系統(tǒng)上設(shè)置了一個2行乘8列的陣列式鍵盤,系統(tǒng)硬件電路如圖4所示。電路結(jié)構(gòu)采用總線擴展方式進

4、行設(shè)計,同時使用P13和P14進行行選擇,按鍵信號通過一片74LS245掛接到數(shù)據(jù)總線上,片選信號為KEY_CS,為其分配的物理地址為0xA100。圖3.3 鍵盤接口電路由于系統(tǒng)的鍵盤接口采用的是總線方式,因此讀取按鍵數(shù)值變得相當(dāng)方便,下面是使用C編寫的讀取鍵盤程序:#define KEY XBYTE 0xA100 /鍵盤地址sbit first_row = P14; /鍵盤第一行控制sbit second_row = P13; /鍵盤第二行控制uchar M_key;/鍵盤數(shù)值暫存單元first_row = 0;/讀取第一行鍵盤數(shù)值second_row = 1;M_key = KEY; fi

5、rst_row = 1;/讀取第二行鍵盤數(shù)值second_row = 0;M_key = KEY;系統(tǒng)采用定時掃描的方式(掃描間隔為4ms,部定時器定時中斷間隔為2ms,每兩次定時中斷進行一次鍵盤掃描)進行鍵盤識別,設(shè)計程序時通常要進行以下四個方面的處理:(1)每隔4ms讀取一次鍵盤的數(shù)值,判斷有無按鍵按下。具體方法是令first_row = 0,second_row = 0,M_key = KEY,判斷M_key的值是否為0xFF,如果等于0xFF說明沒有按鍵按下,如果不等于0xFF說明有按鍵按下。(2)去除按鍵的機械抖動影響。通過設(shè)置狀態(tài)標(biāo)志位first_getkey來判斷連續(xù)兩次掃描鍵盤

6、是否都檢測到有按鍵按下。如果沒有連續(xù)兩次都檢測到按鍵按下則按照鍵抖動處理;否則,認為確實有按鍵按下。(3)準(zhǔn)確輸出按鍵值keynum,并提供獲得有效按鍵標(biāo)志getkey。(4)防止按鍵沖突。在獲得有效按鍵以后設(shè)定狀態(tài)標(biāo)志位keyon來實現(xiàn)每次只處理一個按鍵,且無論一次按鍵時間有多長,系統(tǒng)僅執(zhí)行一次按鍵功能程序。鍵盤識別程序流程如圖3.4所示。程序代碼將在介紹完數(shù)碼管顯示器以后統(tǒng)一給出。圖3.4鍵盤識別程序流程3.2.2數(shù)碼管接口電路與程序設(shè)計本系統(tǒng)共設(shè)置了8個7段碼數(shù)碼管顯示器,電路結(jié)構(gòu)如圖3.5所示。圖3.5 8個7段碼數(shù)碼管顯示器電路電路結(jié)構(gòu)同樣采用總線擴展方式進行設(shè)計,其中使用的數(shù)碼管為

7、連4位的共陽型數(shù)碼管。通過芯片U15(74HC573)鎖存,為數(shù)碼管提供段碼數(shù)據(jù)。通過芯片U14(74HC573)、U13(74HC138)以與三極管Q1Q8將低三位地址A2.0進行硬件譯碼,為每個數(shù)碼管提供一個唯一的物理地址,具體地址為0xA0000xA007。此外本電路結(jié)構(gòu)還考慮了不同數(shù)碼管進行顯示切換時的消隱問題,在編寫程序時不用通過額外的處理進行消隱。由于為每個數(shù)碼管都分配了一個固定的物理地址,在編寫程序時只要將相應(yīng)的段碼數(shù)據(jù)寫入到對應(yīng)的地址當(dāng)中便可以完成顯示,例如要在第二個數(shù)碼管上顯示“1”,使用C語言辦成實現(xiàn)如下:#define 7SEG_LED2 XBYTE 0xA001 /第二

8、個數(shù)碼管的地址定義7SEG_LED2 = 0xF9;/將“1”的段碼數(shù)據(jù)“0xF9”輸出到段碼鎖/存器U15上,同時低三位地址A2.0“001”/經(jīng)過硬件譯碼使位碼LED2為高。通過上面一條語句便可以實現(xiàn)在第二個數(shù)碼管上顯示“1”的操作。但由于全部數(shù)碼管的段碼線共用,在同一時刻只能點亮一個數(shù)碼管,所以在實際應(yīng)用中必須采用動態(tài)掃描的方式進行8個數(shù)碼管的顯示。具體實現(xiàn)方法是使用部定時器每2ms產(chǎn)生一次定時中斷,系統(tǒng)在每進入到一次定時中斷后更新一次顯示容,對于每個數(shù)碼管來說其顯示的周期為16ms,由于顯示頻率足夠高人眼感覺不到閃爍的存在。數(shù)碼管顯示程序流程如下:圖3.6 數(shù)碼管顯示程序流程在編寫程序

9、時考慮到單片機的資源利用情況,使用一個定時器為鍵盤掃描和數(shù)碼管顯示更新提供定時服務(wù),定時中斷函數(shù)流程如圖3.7所示。定時器定時間隔為2ms,每次進入中斷調(diào)用一次顯示更新函數(shù),每兩次進入中斷調(diào)用一次掃描鍵盤函數(shù)。圖3.8給出了利用以上給出的鍵盤掃描和數(shù)碼管顯示以與中斷函數(shù)實現(xiàn)一個最簡單系統(tǒng)的主程序流程圖。在主程序過查詢方式判斷getkey(獲得有效按鍵標(biāo)志位,當(dāng)獲得一個有效按鍵后鍵盤掃描函數(shù)講其置為1),當(dāng)獲得有效按鍵后令所有的數(shù)碼管顯示按鍵的數(shù)值。圖3.7 定時中斷函數(shù)流程圖3.8主程序流程圖C程序代碼如下:#include #include #include #define uchar un

10、signed char /*數(shù)碼管物理地址*/ #define LED1 XBYTE 0xA000 #define LED2 XBYTE 0xA001 #define LED3 XBYTE 0xA002 #define LED4 XBYTE 0xA003 #define LED5 XBYTE 0xA004 #define LED6 XBYTE 0xA005 #define LED7 XBYTE 0xA006 #define LED8 XBYTE 0xA007 /*鍵盤物理地址*/ #define KEY XBYTE 0xA100 /*掃描鍵盤使用的變量*/ sbit first_row = P

11、14; /鍵盤第一行控制sbit second_row = P13; /鍵盤第二行控制bit first_getkey = 0,control_readkey = 0; /讀鍵盤過程中的標(biāo)志位bit getkey = 0; /獲得有效鍵值標(biāo)志位,等于1時代表得到一個有效鍵值bit keyon = 0; /防止按鍵沖突標(biāo)志位uchar keynum = 0; /獲得的有效按鍵值寄存器/*數(shù)碼管顯示使用的變量和常量*/ uchar lednum = 0; /數(shù)碼管顯示位控制寄存器uchar led8 = 0,0,0,0,0,0,0,0; /數(shù)碼管顯示容寄存器uchar code segtab18

12、= 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6, 0xa1,0x86,0x8e,0x8c,0xff; /七段碼段碼表/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, P ,black /*函數(shù)聲明*/ void leddisp(void); /數(shù)碼管顯示更新函數(shù)void readkey(void); /鍵盤掃描函數(shù)/ *T0 定時中斷處理函數(shù)*/ void intT0() interrupt 1 TH0 = -4230/256; /定時器中斷時間間隔2ms T

13、L0 = -4230%256; leddisp(); /每次定時中斷顯示更新一次if(control_readkey = 1) /每兩次定時中斷掃描一次鍵盤 readkey(); control_readkey = !control_readkey; /*主函數(shù)*/ void main(void) TMOD = 0x01; /設(shè)定定時器T0工作模式為模式1 TH0 = -4230/256; /定時器中斷時間間隔2ms TL0 = -4230%256; TCON = 0x10; ET0 = 1; EA = 1; while(1) /等待獲得有效按鍵 if(getkey = 1) /判斷是否獲得有

14、效按鍵 getkey = 0; /當(dāng)獲得有效按鍵時,清除標(biāo)志位。led0 = keynum; /令全部數(shù)碼管顯示按鍵值led1 = keynum; led2 = keynum; led3 = keynum; led4 = keynum; led5 = keynum;24 / 24led6 = keynum; led7 = keynum; /* 鍵盤掃描函數(shù)原型: void readkey(void); 功能: 當(dāng)獲得有效按鍵時,令getkey=1,keynum為按鍵值*/ void readkey(void) uchar M_key = 0; /鍵盤數(shù)值暫存單元first_row = 0; s

15、econd_row = 0; M_key = KEY; if(M_key != 0xff) /如果有連續(xù)兩次按鍵按下,認為有有效按鍵按下。消除按鍵抖動 if(first_getkey = 0) first_getkey = 1; else /當(dāng)有有效按鍵按下時,進一步識別是哪一個按鍵 if(keyon = 0) /防止按鍵沖突,當(dāng)還有未釋放的按鍵時不對其它按鍵動作響應(yīng) first_row = 0; /掃描第一行按鍵second_row = 1; M_key = KEY; if(M_key != 0xff) switch(M_key) case 0xfe: keynum = 0x00; brea

16、k; case 0xfd: keynum = 0x01; break; case 0xfb: keynum = 0x02;break; case 0xf7: keynum = 0x03; break; case 0xef: keynum = 0x04; break; case 0xdf: keynum = 0x05; break; case 0xbf: keynum = 0x06; break; case 0x7f: keynum = 0x07; break; else second_row = 0; /掃描第二行按鍵first_row = 1; M_key = KEY; switch(M_k

17、ey) case 0xfe: keynum = 0x08; break; case 0xfd: keynum = 0x09; break; case 0xfb: keynum = 0x0a; break; case 0xf7: keynum = 0x0b; break; case 0xef: keynum = 0x0c; break; case 0xdf: keynum = 0x0d; break;case 0xbf:keynum = 0x0e; break; case 0x7f: keynum = 0x0f; break; getkey = 1; /獲得有效按鍵數(shù)值keyon = 1; /防

18、止按鍵沖突,當(dāng)獲得有效按鍵時將其置1 else first_getkey = 0; keyon = 0; /防止按鍵沖突,當(dāng)所有的按鍵都釋放時將其清0 /* 數(shù)碼管顯示函數(shù)原型: void leddisp(void); 功能: 每次調(diào)用輪流顯示一位數(shù)碼管*/ void leddisp(void) switch(lednum) /選擇需要顯示的數(shù)碼位 case 0: LED1 = segtabled0; break; case 1: LED2 = segtabled1; break; case 2: LED3 = segtabled2; break; case 3: LED4 = segtabl

19、ed3; break;case 4: LED5 = segtabled4; break;case 5: LED6 = segtabled5; break; case 6: LED7 = segtabled6; break; case 7: LED8 = segtabled7; break; if(lednum = 0) /更新需要顯示的數(shù)碼管位置 lednum = 7; else lednum = lednum-1; 3.2.3液晶接口電路與程序設(shè)計傳統(tǒng)的顯示器件數(shù)碼管已經(jīng)不能滿足顯示復(fù)雜操作界面的要求。因此最小系統(tǒng)中除了數(shù)碼管顯示器以外,還接入了一個液晶顯示模塊,其型號為SGM12864C,

20、可以顯示64行128列的點陣數(shù)據(jù),通過編寫相應(yīng)的程序可以顯示英文、漢字或圖形,可以實現(xiàn)比較復(fù)雜的用戶操作界面。硬件接口電路如圖3.9所示。液晶模塊的結(jié)構(gòu)與操作控制請參閱SMG12864C.PDF。圖3.9 硬件接口電路在硬件設(shè)計中使用譯碼電路提供的LCD_R_CS、LCD_L_CS、LCD_E為液晶模塊提供片選與使能信號。使用系統(tǒng)的地址信號A0控制向液晶寫入的是命令字還是數(shù)據(jù)字。此外將液晶的讀寫控制端接地,禁止從液晶中讀數(shù)據(jù),在向液晶中寫入一個數(shù)據(jù)或命令后延時一段時間再向其中寫入新的數(shù)據(jù),避免由于液晶處在忙狀態(tài)導(dǎo)致寫入錯誤的情況發(fā)生。根據(jù)地址譯碼器提供的地址以與信號A0,可以得出向液晶左右兩個

21、控制器中寫入命令和數(shù)據(jù)的物理地址,下面給出在C語言中的具體定義:#define LCD_L_DATA XBYTE 0xA201 /左半邊液晶數(shù)據(jù)地址#define LCD_R_DATA XBYTE 0xA301 /右半邊液晶數(shù)據(jù)地址#define LCD_L_Command XBYTE 0xA200/左半邊液晶命令地址#define LCD_R_Command XBYTE 0xA300 /右半邊液晶命令地址為了使液晶能夠顯示字符、漢字以與圖形,需要對其進行正確的設(shè)置,具體過程如下:(1)在系統(tǒng)上電后對其進行初始化設(shè)置。向左右兩部分控制器寫入控制字0xC0,設(shè)置顯示的初始行。向左右兩部分控制器寫

22、入控制字0x3F,將液晶的左右兩部分顯示開啟。此部分功能由后面給出程序中的lcd_initial()函數(shù)完成。(2)在液晶指定位置顯示給定的數(shù)據(jù)。完成液晶的初始化以后,通過寫入命令字確定顯示的列地址和頁地址,然后寫入需要顯示的數(shù)據(jù)。以下給出了在液晶指定位置顯示大小為8*8字符、16*16漢字以與128*64圖形的C語言程序,用戶可以根據(jù)需要利用函數(shù)lcd_write_byte()編寫顯示任意大小圖形和文字的函數(shù)。#include #include #include #define uchar unsigned char #define LCD_L_DATA XBYTE 0xA201 /左半邊液

23、晶數(shù)據(jù)地址#define LCD_R_DATA XBYTE 0xA301 /右半邊液晶數(shù)據(jù)地址#define LCD_L_Command XBYTE 0xA200/左半邊液晶命令地址#define LCD_R_Command XBYTE 0xA300/右半邊液晶命令地址uchar code G8 = 0x00,0x00,0x3e,0x41,0x49,0x49,0x7a,0x00; /*G*/ uchar code U8 = 0x00,0x00,0x3f,0x40,0x40,0x40,0x3f,0x00; /*U*/ uchar code O8 = 0x00,0x00,0x3e,0x41,0x4

24、1,0x41,0x3e,0x00; /*O*/ /*- 宋體12; 此字體下對應(yīng)的點陣為:寬x高=16x16 -*/ /*- 文字: 國-*/ uchar code guo32 = 0x00,0xFE,0x02,0x0A,0x8A,0x8A,0x8A,0xFA,0x8A,0x8A,0x8A,0x0A,0x02,0xFE,0x00,0x00, 0x00,0xFF,0x40,0x48,0x48,0x48,0x48,0x4F,0x48,0x49,0x4E,0x48,0x40,0xFF,0x00,0x00; /*- 文字: 防-*/ uchar code fang32 = 0x00,0xFE,0x22

25、,0x5A,0x86,0x02,0x08,0x08,0xF9,0x8E,0x88,0x88,0x88,0x08,0x08,0x00,0x00, 0xFF,0x04,0x08,0x47,0x20,0x18,0x07,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00; /*- 文字: 科-*/uchar code ke32 = 0x10,0x12,0x92,0x72,0xFE,0x51,0x91,0x00,0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00,0x04, 0x02,0x01,0x00,0xFF,0x00,0x04,0x04,0

26、x04,0x02,0x02,0x02,0xFF,0x01,0x01,0x00;/*- 文字: 技-*/ uchar code ji32 = 0x08,0x08,0x88,0xFF,0x48,0x28,0x00,0xC8,0x48,0x48,0x7F,0x48,0xC8,0x48,0x08,0x00,0x01, 0x41,0x80,0x7F,0x00,0x40,0x40,0x20,0x13,0x0C,0x0C,0x12,0x21,0x60,0x20,0x00; /*- 文字: 大-*/ uchar code da32 = 0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x

27、7F,0xA0,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, 0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x01,0x06,0x08,0x30,0x60,0xC0,0x40,0x00; /*- 文字: 學(xué)-*/ uchar code xue32 = 0x40,0x30,0x10,0x12,0x5C,0x54,0x50,0x51,0x5E,0xD4,0x50,0x18,0x57,0x32,0x10,0x00,0x00, 0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x02,0x02,0x02,0x

28、02,0x02,0x02,0x00; /* 液晶驅(qū)動函數(shù)聲明*/void lcd_initial(void); void lcd_write_byte(uchar xpos,uchar ypos,uchar *byte); void lcd_write_char(uchar char_xpos,uchar char_ypos,uchar *char_source_addr); void lcd_write_hanzi(uchar hanzi_xpos,uchar hanzi_ypos,uchar *hanzi_source_addr); void lcd_clear(void); void l

29、cd_fill(void); void delay(uchar time_nop); void main(void) lcd_initial();/初始化液晶lcd_clear(); /液晶清屏lcd_write_char(0,0,G); /顯示A lcd_write_char(1,0,U); /顯示B lcd_write_char(2,0,O); /顯示C lcd_write_hanzi(2,2,guo); /顯示國 lcd_write_hanzi(4,2,fang); /顯示防 lcd_write_hanzi(6,2,ke); /顯示科 lcd_write_hanzi(8,2,ji); /

30、顯示技 lcd_write_hanzi(10,2,da); /顯示大 lcd_write_hanzi(12,2,xue); /顯示學(xué) while(1) /* 延時函數(shù)函數(shù)原型: void delay(uchar time_nop);功能: 延時time_nop個nop */ void delay(uchar time_nop) uchar i; for(i=0;itime_nop;i+) _nop_(); /* LCD初始化原型: void lcd_initial(void); 功能:將LCD進行初始化,設(shè)置初始行并開顯示*/ void lcd_initial(void) delay(5);

31、LCD_L_Command = 0xC0; /設(shè)置顯示初始行delay(5); LCD_R_Command = 0xC0; delay(5); LCD_L_Command = 0x3F; /開顯示delay(5); LCD_R_Command = 0x3F; delay(5); /*向LCD中寫入一個字節(jié)數(shù)據(jù)函數(shù)原型: void lcd_write_byte(uchar xpos,uchar ypos,uchar byte); 功能:將一個字節(jié)數(shù)據(jù)byte寫入液晶的(xpos,ypos)的位置處此處將液晶的顯示區(qū)按照二維坐標(biāo)進行定義,xpos為橫坐標(biāo)從左到右順序為0-127,ypos為縱坐標(biāo)從

32、上到下順序為0-7。*/ void lcd_write_byte(uchar xpos,uchar ypos,uchar *byte) if(xpos = 63) /坐標(biāo)位置處在液晶的左半部分 delay(5); LCD_L_Command = xpos + 0x40; /設(shè)定寫入數(shù)據(jù)的列地址delay(5); LCD_L_Command = ypos + 0xB8; /設(shè)定寫入數(shù)據(jù)的行地址delay(5); LCD_L_DATA = *byte; /向(xpos,ypos)處寫數(shù)據(jù)delay(5); else /坐標(biāo)位置處在液晶的右半部分 delay(5); LCD_R_Command =

33、(xpos - 64) + 0x40; /設(shè)定寫入數(shù)據(jù)的列地址delay(5); LCD_R_Command = ypos + 0xB8; /設(shè)定寫入數(shù)據(jù)的行地址delay(5); LCD_R_DATA = *byte; /向(xpos,ypos)處寫數(shù)據(jù)delay(5); /* 在LCD指定位置顯示一個ASIIC字符函數(shù)字符大小為8*8 原型: void lcd_write_char(uchar char_xpos,uchar char_ypos,uchar *char_source_addr); 功能:將一個字符數(shù)據(jù)寫入液晶的(char_xpos,char_ypos)的位置處此處將液晶的顯

34、示區(qū)按照二維坐標(biāo)進行定義,char_xpos為橫坐標(biāo)從左到右順序為0-15,char_ypos為縱坐標(biāo)從上到下順序為0-7。*/ void lcd_write_char(uchar char_xpos,uchar char_ypos,uchar *char_source_addr) uchar i = 0; for(i=0;i=7;i+) lcd_write_byte(char_xpos * 8 + i, char_ypos, char_source_addr + i); /* 在LCD指定位置顯示一個漢字函數(shù)字符大小為16*16 原型: void lcd_write_hanzi(uchar

35、hanzi_xpos,uchar hanzi_ypos,uchar *hanzi_source_addr); 功能:將一個漢字數(shù)據(jù)寫入液晶的(hanzi_xpos,hanzi_ypos)的位置處,此處將液晶的顯示區(qū)按照二維坐標(biāo)進行定義,hanzi_xpos為橫坐標(biāo)從左到右順序為0-14(以半個漢字符為單位),hanzi_ypos為縱坐標(biāo)從上到下順序為0-6(以半個漢字符為單位)。*/ void lcd_write_hanzi(uchar hanzi_xpos,uchar hanzi_ypos,uchar *hanzi_source_addr) uchar i = 0; for(i=0;i=15

36、;i+) /寫漢字的上半部分 lcd_write_byte(hanzi_xpos * 8 + i, hanzi_ypos, hanzi_source_addr + i); for(i=0;i=15;i+) /寫漢字的下半部分 lcd_write_byte(hanzi_xpos * 8 + i, hanzi_ypos + 1, hanzi_source_addr + 16 + i); /* LCD清屏原型: void lcd_clear(void); 功能:將LCD清屏*/ void lcd_clear(void) uchar i,j; uchar byte1 = 0x00; for(i=0;i

37、=127;i+) for(j=0;j=7;j+) lcd_write_byte(i,j,byte); /* LCD填充原型: void lcd_fill(void); 功能:將LCD填充為黑色*/void lcd_fill(void) uchar i,j; uchar byte1 = 0xFF; for(i=0;i=127;i+) for(j=0;j=7;j+) lcd_write_byte(i,j,byte); 3.4 單片機與D/A、A/D轉(zhuǎn)換電路制作A/D、D/A轉(zhuǎn)換器是單片機電路經(jīng)常要用到的器件。在電子設(shè)計中,很多時候需要處理模擬量,對模擬量進行控制。這就要使用到A/D、D/A轉(zhuǎn)換器,

38、將模擬量轉(zhuǎn)換成數(shù)字量,由單片計進行處理,再將數(shù)字量轉(zhuǎn)換為模擬量,對外圍設(shè)備進行控制。由于單片機本身工作速度慢,不能連接高速A/D、D/A轉(zhuǎn)換器,同時為了節(jié)省單片機IO口資源,本節(jié)僅就低速串行轉(zhuǎn)換器進行介紹。如果需要使用高速A/D、D/A轉(zhuǎn)換器,請使用FPGA對其進行控制。3.4.1串行模數(shù)轉(zhuǎn)換器應(yīng)用串行輸出的A/D芯片由于節(jié)省單片機的I/O口線,越來越多地被采用。如具有SPI三線接口的TLC1549、TLC1543、TLC2543、MAX187等,具有2線IIC接口的MAX127、PCF8591(4路8位A/D,還含1路8位D/A)等。本小節(jié)以串行A/D轉(zhuǎn)換器芯片TLC1549為例簡要介紹串行

39、A/D轉(zhuǎn)換器的接口電路以與驅(qū)動程序的設(shè)計。1、TLC1549的工作方式與時序l TLC1549有6種工作方式,如表2所示。l 其中方式1和方式3屬同一類型,方式2和方式4屬同一類型。l 一般來說,時鐘頻率高于280 kHz時,可認為是快速工作方式;l 低于280 kHz時,可認為是慢速工作方式。l 因此,如果不考慮I/O CLOCK周期大小,方式5與方式3一樣,方式6與方式4一樣。表2 TLC1549的工作方式工作方式1工作時序圖如圖3.10所示。圖中從下跳到DATA輸出數(shù)據(jù)要有1.3 s的延時;連續(xù)進行A/D轉(zhuǎn)換時,在上次轉(zhuǎn)換結(jié)果輸出的過程中,同時完成本次轉(zhuǎn)換的采樣,這樣大大提高了A/D轉(zhuǎn)換

40、的速率。如果I/O CLOCK的時鐘頻率為2.1 MHz,則完成一次A/D轉(zhuǎn)換的時間大約為26 s。如果用連續(xù)模擬信號進行采樣轉(zhuǎn)換,顯然其轉(zhuǎn)換速率是很高的。圖3.10方式1工作時序2、TLC1549與單片機最小系統(tǒng)的接口電路設(shè)計使用單片機小系統(tǒng)控制TLC1549,主要通過擴展接口J4完成,J4各管腳信號定義請參見圖3.2小系統(tǒng)原理圖。需要控制的芯片管腳有三個,分別為、I/O CLOCK和DATA OUT,選用J4中的P10、P11和P12(實際是單片機P1口中的三個I/O管腳)分別控制TLC1549三個管腳。使用單片機的I/O模擬圖12中的操作時序,完成對TLC1549的控制。接口電路如圖3.

41、11所示。在電路中使用VCC作為A/D的參考電平,由于VCC的不穩(wěn)定會降低轉(zhuǎn)換精度,因此可以選用專用的參考電壓芯片,提高轉(zhuǎn)換精度。圖3.11 接口電路3、A/D轉(zhuǎn)換接口程序設(shè)計編寫驅(qū)動TLC1549的程序,就是通過軟件的方法控制P10、P11和P12,產(chǎn)生如圖3.10中的操作時序,完成一次A/D轉(zhuǎn)換。使用C編寫的采樣函數(shù)如下:#include #include #include #define uchar unsigned char #define uint unsigned int sbit AD_CS = P10; /TLC1549 片選信號sbit AD_IOCLOCK = P11; /

42、TLC1549 時鐘信號sbit AD_DATAOUT = P12; /TLC1549 數(shù)據(jù)輸出信號/*A/D轉(zhuǎn)換函數(shù)聲明*/ uint ad_convert(void); void delay(uchar time_nop); void main(void) uint ad_data_10bit; /低10位為有效數(shù)據(jù)AD_CS = 1; /初始化TLC1549 AD_IOCLOCK = 0; while(1) ad_data_10bit = ad_convert(); delay(50); /完成一次采樣后要延時21us,等待下一次采樣結(jié)果轉(zhuǎn)換完成 /* AD轉(zhuǎn)換函數(shù)函數(shù)原型: uint

43、ad_convert(void); 功能: 驅(qū)動TLC1549完成一次A/D采樣返回值為AD轉(zhuǎn)換結(jié)果,使用16bit的uint型數(shù)據(jù)表示,低10位有效. */ uint ad_convert(void) uchar i; uint AD_DATA = 0; AD_CS = 0; for(i=0;i=9;i+) AD_IOCLOCK = 0; if(AD_DATAOUT = 1) AD_DATA = AD_DATA * 2 + 1; else AD_DATA = AD_DATA * 2; AD_IOCLOCK = 1; AD_IOCLOCK = 0;AD_CS = 0; return(AD_DATA); /* 延時函數(shù)函數(shù)原型: void delay(uchar time_nop); 功能: 延時time_nop個nop */ void delay(uchar time_nop) uchar i; for(i=0;itime_nop;i+) _nop_(); 3.4.2串行數(shù)模轉(zhuǎn)換器應(yīng)用單片機實現(xiàn)控制是以數(shù)字信號或模擬信號的形式通過口送給被控對象的。模擬信號的產(chǎn)生通常需要D/A轉(zhuǎn)換器的參與。本小節(jié)以串行D/A轉(zhuǎn)換芯片TLC5615為例簡要介紹串行D /

溫馨提示

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

評論

0/150

提交評論