




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、一、課程設(shè)計內(nèi)容及要求1、蜂鳴計算器設(shè)計利用普中科技HC6800-ES V2.0單片機(jī)開發(fā)板設(shè)計一款帶蜂鳴器的電子計算器。主要使用開發(fā)板上的數(shù)碼管、LED點陣、矩陣鍵盤、蜂鳴器等模塊功能。開發(fā)板配有光盤,里面有各個模塊的使用說明和程序范例可供參考。2、設(shè)計要求1) 上電開機(jī)或者復(fù)位鍵按下之后,數(shù)碼管自動顯示個人學(xué)號的后8位。2) 定義矩陣鍵盤的S1-S9代表數(shù)字按鍵1-9,鍵盤S10代表數(shù)字按鍵0,鍵盤S11-S16分別代表按鍵+、-、×、÷、=、C,其中C按鍵為計算器清零按鍵,按下C鍵計算器開始新的計算。3) 計算器計算過程中,用LED點陣顯示+、-、×、
2、47;運算符號,用8位數(shù)碼管顯示鍵入的數(shù)字和運算的結(jié)果。鍵入時依次顯示并自動移位,例如18+9=27,先鍵入1,顯示1,再鍵入8,1自動左移一位顯示18,鍵入+,LED點陣顯示+,鍵入9,數(shù)碼管之前顯示的18消失并重新顯示為9,鍵入=,數(shù)碼管顯示運算結(jié)果27。4) 為這16個矩陣鍵盤的按鍵分配不同的蜂鳴器頻率,使得按下不同的按鍵蜂鳴器響聲不同,便于識別按鍵。5) 按鍵應(yīng)具有一定的消除抖動功能。6) 所有單片機(jī)程序代碼都用C語言編寫,并燒寫到單片機(jī)中上電自動運行。2、 設(shè)計思想蜂鳴器計算器設(shè)計包括矩陣鍵盤模塊、數(shù)碼管及矩陣LED動態(tài)顯示模塊、輸入邏輯計算顯示模塊和蜂鳴器響應(yīng)模塊這四大模塊。具體實
3、施方法如下:1、 矩陣鍵盤模塊,四乘四的矩陣鍵盤,設(shè)計按鍵掃描函數(shù),在定時中斷中調(diào)用,調(diào)用定時器中斷,中斷間隔時間設(shè)置為1ms,選擇P2IO口,P2.0到P2.3做輸出KeyOut,P2.4做P2.7做輸入KeyIn,每次在按鍵掃描中斷中,每次讓矩陣按鍵的一個 KeyOut 輸出低電平,其它三個輸出高電平,判斷當(dāng)前所有 KeyIn 的狀態(tài),然后再讓下一個 KeyOut 輸出低電平,其它三個輸出高電平,再次判斷所有 KeyIn,通過四次掃描,確定按下的鍵,再通過快速的中斷不停的循環(huán)進(jìn)行判斷,就可以最終確定哪個按鍵按下了。 同時在按鍵模塊,還需要消抖使按鍵穩(wěn)定。通常我們采用延遲再次檢測的方式消抖,
4、但是太過消耗單片機(jī)的CUP。所以為了避免通過延時消抖占用單片機(jī)執(zhí)行時間,將其轉(zhuǎn)化成了一種按鍵狀態(tài)判定而非按鍵過程判定,只對當(dāng)前按鍵的連續(xù) 16ms 的 4 次狀態(tài)進(jìn)行判斷,全為0就斷定對于的鍵按下了,全為1就斷定為沒有按下。2、數(shù)碼管及矩陣LED動態(tài)顯示模塊,通過每毫秒進(jìn)行動態(tài)掃描進(jìn)行顯示,由于數(shù)碼管和矩陣LED動態(tài)顯示模塊都需要通過P1.3和P1.4進(jìn)行選擇來控制,所以在寫刷新數(shù)據(jù)和符號的時候需要先在函數(shù)開始調(diào)好對應(yīng)的控制位。而所需要的顯示的數(shù)字和符號保存在數(shù)組中,以便需要的時候直接調(diào)用。3、輸入邏輯計算顯示模塊,在編寫程序的時候,對于這個簡易計算器,以正整數(shù)的連續(xù)加減乘除為基本編程目的。在
5、第一次輸入為0-9這十個按鍵的時候,此時設(shè)置了標(biāo)記符號flag=0,直接保存到數(shù)據(jù)保存數(shù)組addflag中,若繼續(xù)輸入數(shù)字就把addflag乘以10再加上新輸入的數(shù)字;若掃描到加減乘除這四個符號的時候,先把標(biāo)記符號flag置為1,再把算數(shù)符號保存到符號標(biāo)記sign中,把需要LED矩陣顯示的全局符號變量tx設(shè)置為對應(yīng)的數(shù)字,繼續(xù)掃描到數(shù)字的時候就會把數(shù)據(jù)保存到add1(flag=1)中;如果接下來輸入為等于號,就判斷sign數(shù)值然后對add0和add1做對應(yīng)的計算;如果輸入還是計算符號,就先計算把計算結(jié)果保存到add0中,再清零add1,再繼續(xù)掃描。4、蜂鳴器響應(yīng)模塊,由于開發(fā)板上面的蜂鳴器是無
6、源蜂鳴器,所以需要通過輸出pwm脈沖來驅(qū)動蜂鳴器,同時由于脈沖頻率不同對于蜂鳴器發(fā)聲也不一樣,所以通過一個需要傳入頻率參數(shù)的函數(shù)。通過該頻率參數(shù),來設(shè)置中斷定時器T1,控制蜂鳴器驅(qū)動端口輸出高低電平,然后在按鍵處理函數(shù)處判斷對應(yīng)需要的頻率送給蜂鳴器響應(yīng)函數(shù)。3、 程序流程圖 1、整體流程圖2、算數(shù)邏輯流程四、詳細(xì)程序 1、總程序Calculator.c#include <reg52.h>#include <stdlib.h>#include <sys.h>#include <fun.h>void main() Init();ShowNumber(
7、135043);/顯示學(xué)號while (1) KeyDriver(); /調(diào)用按鍵驅(qū)動函數(shù) /* T0中斷服務(wù)函數(shù),用于數(shù)碼管顯示掃描與按鍵掃描 */void InterruptTimer0() interrupt 1 TH0 = 0xFC; /重新加載初值 TL0 = 0x67; LedScan(); /調(diào)用數(shù)碼管顯示掃描函數(shù) KeyScan(); /調(diào)用按鍵掃描函數(shù)ShowPhoto(tx);/調(diào)用點陣顯示函數(shù)/* T1中斷服務(wù)函數(shù),用于蜂鳴器 */ void InterruptTimer1() interrupt 3 TH1 = T1RH; /重新加載重載值 TL1 = T1RL; BU
8、ZZ = BUZZ; /反轉(zhuǎn)蜂鳴器控制電平2、宏定義頭文件sys.c#ifndef _sys_h_#define _sys_h_#include "sys.h"#define uint unsigned int#define uchar unsigned charsbit ADDR0 = P10;sbit ADDR1 = P11;sbit ADDR2 = P12;sbit ADDR3 = P13;sbit ENLED = P14;sbit KEY_IN_1 = P24;sbit KEY_IN_2 = P25;sbit KEY_IN_3 = P26;sbit KEY_IN_4
9、 = P27;sbit KEY_OUT_1 = P23;sbit KEY_OUT_2 = P22;sbit KEY_OUT_3 = P21;sbit KEY_OUT_4 = P20;sbit BUZZ = P16; /蜂鳴器控制引腳unsigned char T1RH = 0; /T0重載值的高字節(jié)unsigned char T1RL = 0; /T0重載值的低字節(jié)unsigned char tx = 0; /矩陣led顯示unsigned char code LedChar = /數(shù)碼管顯示字符轉(zhuǎn)換表 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF
10、8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E;unsigned char LedBuff6 = /數(shù)碼管顯示緩沖區(qū) 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF;unsigned char code KeyCodeMap44 = /矩陣按鍵編號到標(biāo)準(zhǔn)鍵盤鍵碼的映射表 0x31, 0x32, 0x33, 0x26 , /數(shù)字鍵1、數(shù)字鍵2、數(shù)字鍵3、加鍵 0x34, 0x35, 0x36, 0x25 , /數(shù)字鍵4、數(shù)字鍵5、數(shù)字鍵6、乘鍵 0x37, 0x38, 0x39, 0x28 , /數(shù)字鍵7、數(shù)字鍵8、數(shù)字鍵
11、9、減鍵 0x30, 0x1B, 0x0D, 0x27 /數(shù)字鍵0、ESC鍵、等號鍵、 除鍵;unsigned char KeySta44 = /全部矩陣按鍵的當(dāng)前狀態(tài) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1;unsigned char code image68 = /符號的字模表 0xFF,0xBD,0x5A,0xFF,0xFF,0xBD,0xDB,0xE7,/笑臉 0xE7,0xE7,0xE7,0x00,0x00,0xE7,0xE7,0xE7,/加號 0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF, /減
12、號 0x3C,0x18,0x81,0xC3,0xC3,0x81,0x18,0x3C, /乘號 0xE7,0xE7,0xFF,0x00,0x00,0xFF,0xE7,0xE7, /除號0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF /等號;void Init();void ShowNumber(unsigned long num);void KeyAction(unsigned char keycode);void KeyDriver();void KeyScan();void LedScan();void OpenBuzz(unsigned int frequ)
13、;void StopBuzz();void Delay();void Buzz(unsigned int frequ);void ShowPhoto(unsigned int a);#endif3、函數(shù)頭文件fun.c#ifndef _fun_h_#define _fun_h_#include "fun.h"void Init()EA = 1; /使能總中斷 TMOD = 0x11; /設(shè)置T0為模式1 TH0 = 0xFC; /為T0賦初值0xFC67,定時1ms TL0 = 0x67; ET0 = 1; /使能T0中斷TR0 = 1; /啟動T0 /* 將一個無符號長整
14、型的數(shù)字顯示到數(shù)碼管上,num-待顯示數(shù)字 */void ShowNumber(unsigned long num) signed char i; unsigned char buf6; for (i=0; i<6; i+) /把長整型數(shù)轉(zhuǎn)換為6位十進(jìn)制的數(shù)組 bufi = num % 10; num = num / 10; for (i=5; i>=1; i-) /從最高位起,遇到0轉(zhuǎn)換為空格,遇到非0則退出循環(huán) if (bufi = 0) LedBuffi = 0xFF; else break; for ( ; i>=0; i-) /剩余低位都如實轉(zhuǎn)換為數(shù)碼管顯示字符 L
15、edBuffi = LedCharbufi; /* 按鍵動作函數(shù),根據(jù)鍵碼執(zhí)行相應(yīng)的操作,keycode-按鍵鍵碼 */void KeyAction(unsigned char keycode) static unsigned long result = 0; /用于保存運算結(jié)果 static unsigned long add2 = 0; /用于保存輸入的數(shù)字static unsigned intsign2 = 0;/用作統(tǒng)計前一次和當(dāng)前運算符號,03依次代表加減乘除 static unsigned int flag = 0; /用于統(tǒng)計次數(shù)switch(keycode) /不同按鍵蜂鳴器發(fā)
16、出不同頻率聲音case 0x30 : Buzz(1000);break;case 0x31 : Buzz(1500);break;case 0x32 : Buzz(2000);break;case 0x33 : Buzz(2500);break;case 0x34 : Buzz(3000);break;case 0x35 : Buzz(3500);break;case 0x36 : Buzz(4000);break;case 0x37 : Buzz(4500);break;case 0x38 : Buzz(5000);break;case 0x39 : Buzz(5500);break;cas
17、e 0x26 : Buzz(6000);break;case 0x28 : Buzz(6500);break;case 0x25 : Buzz(7500);break;case 0x27 : Buzz(8000);break;case 0x0D : Buzz(8500);break;case 0x1B : Buzz(9000);break;default : break; if (keycode>=0x30) && (keycode<=0x39) /輸入0-9的數(shù)字 if(flag = 0) add0 = (add0*10)+(keycode-0x30); /整體十
18、進(jìn)制左移,新數(shù)字進(jìn)入個位 ShowNumber(add0); /運算結(jié)果顯示到數(shù)碼管elseadd1 = (add1*10)+(keycode-0x30); /整體十進(jìn)制左移,新數(shù)字進(jìn)入個位 ShowNumber(add1); /運算結(jié)果顯示到數(shù)碼管 else if (keycode = 0x26) /向上鍵用作加號,執(zhí)行加法或連加運算 sign0 = sign1; /保存前一次的運算符號 sign1 = 0; /保存當(dāng)前運算符號flag = 1;tx = 1;switch(sign0) /用于連加case 0:add0= add0+add1;break;case 1:add0= add0-a
19、dd1;break;case 2:add0= add0*add1;break;case 3:add0= add0/add1;break;default : break; ShowNumber(add0); /運算結(jié)果顯示到數(shù)碼管add1=0; /清零add1; else if (keycode = 0x28) /向下鍵用作減號,執(zhí)行減法sign0 = sign1; /保存前一次的運算符號 sign1 = 1; /保存當(dāng)前運算符號flag = 1;tx = 2;switch(sign0)case 0:add0= add0+add1;break;case 1:add0= add0-add1;bre
20、ak;case 2:add0= add0*add1;break;case 3:add0= add0/add1;break;default : break;ShowNumber(add0); /運算結(jié)果顯示到數(shù)碼管add1=0; /清零add1;else if (keycode = 0x25) /向下鍵用作乘號,執(zhí)行乘法sign0 = sign1; /保存前一次的運算符號 sign1 = 2; /保存當(dāng)前運算符號flag = 1;tx = 3;switch(sign0)case 0:add0= add0+add1;break;case 1:add0= add0-add1;break;case 2
21、:add0= add0*add1;break;case 3:add0= add0/add1;break;default : break;ShowNumber(add0); /運算結(jié)果顯示到數(shù)碼管add1=0; /清零add1;else if (keycode = 0x27) /向下鍵用作除號,執(zhí)行除法sign0 = sign1; /保存前一次的運算符號 sign1 = 3; /保存當(dāng)前運算符號flag = 1;tx = 4 ;switch(sign0)case 0:add0= add0+add1;break;case 1:add0= add0-add1;break;case 2:add0= a
22、dd0*add1;break;case 3:add0= add0/add1;break;default : break;ShowNumber(add0); /運算結(jié)果顯示到數(shù)碼管add1=0; /清零add1; else if (keycode = 0x0D) /等號鍵,執(zhí)行運算 switch(sign1)case 0: result = add0+add1; /進(jìn)行加法運算 ShowNumber(result); /運算結(jié)果顯示到數(shù)碼管 break;case 1: result = add0-add1; /進(jìn)行減法運算 ShowNumber(result); /運算結(jié)果顯示到數(shù)碼管 brea
23、k;case 2: result = add0*add1; /進(jìn)行乘法運算 ShowNumber(result); /運算結(jié)果顯示到數(shù)碼管 break;case 3: result = add0/add1; /進(jìn)行除法運算 ShowNumber(result); /運算結(jié)果顯示到數(shù)碼管 break;default : break; tx = 5 ;flag = 0;add0 = 0;add1 = 0;sign0=0;sign1=0; else if (keycode = 0x1B) /Esc鍵,清零結(jié)果 add0 = 0;add1 = 0;sign0=0;sign1=0;flag = 0; r
24、esult = 0;tx = 0 ; ShowNumber(result); /清零后的加數(shù)顯示到數(shù)碼管 /* 按鍵驅(qū)動函數(shù),檢測按鍵動作,調(diào)度相應(yīng)動作函數(shù),需在主循環(huán)中調(diào)用 */void KeyDriver() unsigned char i, j; static unsigned char backup44 = /按鍵值備份,保存前一次的值 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ; for (i=0; i<4; i+) /循環(huán)檢測4*4的矩陣按鍵 for (j=0; j<4; j+) if (backupij != Key
25、Staij) /檢測按鍵動作 if (backupij != 0) /按鍵按下時執(zhí)行動作 KeyAction(KeyCodeMapij); /調(diào)用按鍵動作函數(shù) backupij = KeyStaij; /刷新前一次的備份值 /* 按鍵掃描函數(shù),需在定時中斷中調(diào)用,調(diào)用間隔1ms */void KeyScan() unsigned char i; static unsigned char keyout = 0; /矩陣按鍵掃描輸出索引 static unsigned char keybuf44 = /矩陣按鍵掃描緩沖區(qū) 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x
26、FF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ; /將一行的4個按鍵值移入緩沖區(qū) keybufkeyout0 = (keybufkeyout0 << 1) | KEY_IN_1; keybufkeyout1 = (keybufkeyout1 << 1) | KEY_IN_2; keybufkeyout2 = (keybufkeyout2 << 1) | KEY_IN_3; keybufkeyout3 = (keybufkeyout3 << 1) | KEY_IN_4; /消抖后更
27、新按鍵狀態(tài) for (i=0; i<4; i+) /每行4個按鍵,所以循環(huán)4次 if (keybufkeyouti & 0x0F) = 0x00) /連續(xù)4次掃描值為0,即4*4ms內(nèi)都是按下狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的按下 KeyStakeyouti = 0; else if (keybufkeyouti & 0x0F) = 0x0F) /連續(xù)4次掃描值為1,即4*4ms內(nèi)都是彈起狀態(tài)時,可認(rèn)為按鍵已穩(wěn)定的彈起 KeyStakeyouti = 1; /執(zhí)行下一次的掃描輸出 keyout+; /輸出索引遞增 keyout = keyout & 0x03; /索引值加
28、到4即歸零 switch (keyout) /根據(jù)索引,釋放當(dāng)前輸出引腳,拉低下次的輸出引腳 case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; /* 數(shù)碼管動態(tài)掃描刷新函數(shù),需在定時中斷中調(diào)用 */void LedScan() static unsigned
29、 char i = 0; /動態(tài)掃描的索引 ENLED = 0; /選擇數(shù)碼管進(jìn)行顯示 ADDR3 = 1; P0 = 0xFF; /顯示消隱 switch (i) case 0: ADDR2=0; ADDR1=0; ADDR0=0; i+; P0=LedBuff0; break; case 1: ADDR2=0; ADDR1=0; ADDR0=1; i+; P0=LedBuff1; break; case 2: ADDR2=0; ADDR1=1; ADDR0=0; i+; P0=LedBuff2; break; case 3: ADDR2=0; ADDR1=1; ADDR0=1; i+; P
30、0=LedBuff3; break; case 4: ADDR2=1; ADDR1=0; ADDR0=0; i+; P0=LedBuff4; break; case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff5; break; default: break; /* 蜂鳴器啟動函數(shù),frequ-工作頻率 */void OpenBuzz(unsigned int frequ) unsigned int reload; /計算所需的定時器重載值 reload = 65536 - (11059200/12)/(frequ*2); /由給定頻率計算定時器重載值 T1RH = (unsigned char)(reload >> 8); /16位重載值分解為高低兩個字節(jié) T1RL = (unsigned char)reload; TH1 = 0xFF; /設(shè)定一個接近溢出的初值,以使定時器馬上投入工作 TL1 = 0xFE; ET1 = 1; /使能T0中斷 TR1 = 1; /啟動T0/* 蜂鳴器停止函數(shù)*/void StopBuzz() ET1 = 0; /禁用T0中斷 TR1 = 0; /停止T0 /*延時函數(shù) */void Delay()unsi
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中級會計考試考前心理輔導(dǎo)與試題及答案
- 高級審計師個人復(fù)習(xí)計劃及試題及答案設(shè)計
- 不容忽視的一級建造師考試試題及答案
- 2025年護(hù)士考試健康服務(wù)管理試題及答案
- 碩士生外語能力提升系列指導(dǎo)及試題及答案
- 思維導(dǎo)圖2024年高級會計試題及答案
- 2025年ACCA國際注冊會計師考試真題卷:戰(zhàn)略商業(yè)與管理模擬試題
- 2025年團(tuán)員發(fā)展關(guān)切試題及答案
- 企業(yè)融資決策解析試題及答案
- 2025年企業(yè)培訓(xùn)師職業(yè)資格考試真題卷:企業(yè)培訓(xùn)師培訓(xùn)課程設(shè)計與評估
- 工程師轉(zhuǎn)正匯報課件
- 語法知識-2022-2023學(xué)年八年級語文上學(xué)期期中考前復(fù)習(xí)訓(xùn)練(解析版)
- 水利工程中的水環(huán)境保護(hù)與生態(tài)修復(fù)
- 高一數(shù)學(xué)組尖子生培養(yǎng)計劃(修改)
- 醫(yī)療器械輻射安全管理的要求
- 自動按頻率減負(fù)荷裝置
- 6朗誦《唐詩里的中國》朗誦稿
- 停車場運營維護(hù)管理投標(biāo)方案(技術(shù)標(biāo))
- 工業(yè)硅行業(yè)可行性研究報告
- 水生態(tài)修復(fù)與保護(hù)概述
- 地鐵站白蟻防治施工方案
評論
0/150
提交評論