久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 41211|回復: 27
打印 上一主題 下一主題
收起左側

單片機模擬電話撥號系統設計資料 帶程序

  [復制鏈接]
跳轉到指定樓層
#
系統總體設計
2.1系統基本設計方案
2.1.1控制部分的選擇方案與論證
2.1.2 顯示電路模塊的選擇方案與論證
2.1.3輸入電路模塊的選擇方案與論證
2.2電路設計最終方案
3 系統硬件設計
3.1 系統硬件原理圖
3.2主芯片模塊
3.2.1 AT89C51芯片引腳
3.2.2晶振和復位電路模塊
3.3顯示電路模塊
3.3.1 1602LCD簡介
3.3.2 1602LCD的RAM地址映射及標準字庫表
3.3.3 1602LCD的一般初始化過程
3.4矩陣鍵盤輸入電路模塊
3.4.1矩陣鍵盤的基本結構
3.4.2矩陣鍵盤的按鍵識別方法
4 系統軟件設計
4.1 程序設計整體思路
4.2.主要功能模塊設計
4.2.1 鍵盤掃描模塊設計
4.2.2 LCD顯示模塊設計
5 系統仿真與調試
5.1系統運行環境
5.2 系統仿真說明
5.2.1 KEILC調試
5.2.2 Proteus調試
5.2.3 Proteus與Keilc聯調實現電路仿真
總  結
致  謝
參考文獻
附件1 源程序代碼
附件2 電話撥號系統電路原理圖


    隨著社會的發展,科學的進步,人們的生活水平在逐步的提高,尤其是微電子技術的發展,猶如雨后春筍般的變化。各種數字顯示儀器中的顯示、廣告牌、數碼產品等,傳統的數碼管顯示已經遠遠不能滿足各行各業的需求。單片機的應用已經越來越貼近生活,用單片機來實現一些電子設計也變得容易起來;趩纹瑱C的LCD顯示是一種用單片機來控制的一種顯示系統,它不僅能顯示種各數字、字母、還能顯示各種字體的漢字以及一些簡單的圖象,使用起來極為方便,只要通過對單片機寫入一定的程序來控制LCD的顯示即可完成,根據程序的不同而產生不同不效果。隨著單片機產品以及LCD產品的不斷涌現,這一領域已經得到了飛速的發展。
本文設計的是基于單片機的電話撥號系統,主要介紹了一種基于AT89C51單片機的電話撥號控制系統,該系統可以實現電話號碼數字顯示。系統主要由電話撥號矩陣鍵盤、單片機最小系統、LCD1602顯示屏幾個單元電路組成。在本設計中,最終選用的是矩陣式鍵盤,把所操作的數字送至單片機,通過單片機實現號碼的顯示與控制。


2 系統總體設計
2.1系統基本設計方案
2
.1.1控制部分的選擇方案與論證
    方案一:用可編程邏輯器件設計
可采用PLD器件,設計起來結構清晰,各個模塊從硬件上設計起來相對簡單,控制與顯示的模塊間連接也會比較方便。但是考慮到本設計的特點,EDA在能夠擴展上比較受局限,占用的資源也多。從成本上講,可編程邏輯器件價格比較高。

    方案二:用單片機設計

用單片機芯片作為控制部分,單片機有豐富的中斷源,它的準確度相當高,并且C語言的靈活運用,給編程帶來了方便。單片機I/O功能也比較強大,容易對其進行擴展,使設計更加完善,此外單片機的成本也比較低。

綜上所述,單片機資源豐富,程序編寫也靈活簡單,可移植性強,性價比也高,所以選擇單片機作為主控芯片。

2.1.2 顯示電路模塊的選擇方案與論證
LCD由于其顯示清晰,顯示內容豐富,顯示信息量大,使用方便,顯示快速而得到了廣泛的應用。
對于此系統本設計選用的LCD液晶能夠顯示英語字母和數字,能夠很好的滿足顯示要求,因此本設計選擇了此方案。
2.1.3輸入電路模塊的選擇方案與論證
鍵盤用于實現單片機應用系統中的數據和控制命令的輸入,鍵盤輸入也是單片機應用系統中使用最廣泛的一種輸入方式。鍵盤輸入的主要對象是各種按鍵或開關。這些按健或者開關可以獨立使用,也可以組合成鍵陣使用。單片機中常用的按鍵式鍵盤可以分為兩類:獨立連接式和行列式。每類按譯碼方式的不同又分為編碼式和非編碼式兩種。單片機中一般使用的都是用軟件來識別和產生鍵代碼的非編碼鍵盤。行列式鍵盤的編碼方式有靜態和動態兩種。靜態接口主要由一個行編碼器和一個列編碼器構成;動態接口可采用計數器,譯碼器和數據選擇器構成。這兩種鍵盤由硬件完成鍵的辨碼任務。一般在小型儀器儀表和控制系統中,使用較多的是行列式和獨立式的非編碼鍵盤;如果系統要求實現多鍵同時按下的處理,則用非編碼獨立方式較為合適。
    方案一:采用獨立式按鍵電路
獨立式按鍵電路每個按鍵單獨占有一根I/O接口線, 每個I/O口的工作狀態互不影響,此類鍵盤采用端口直接掃描方式。缺點為當按鍵較多時占用單片機的I/O口數目較多,優點為電路設計簡單,且編程相對比較容易。
    方案二:采用矩陣式鍵盤電路
矩陣式鍵盤為4*3矩陣式行列掃描,雖然軟件較為復雜,但是當按鍵較多時可降低占用單片機的I/O口數目。
對于本系統,由于按鍵數目多,故采用方案二。
2.2電路設計最終方案
本系統包括主芯片模塊、顯示電路模塊、鍵盤輸入模塊、晶振和復位電路模塊。綜上各方案所述,確定最終設計方案為:采用單片機作為主控芯片,1602LCD液晶作為顯示部分,矩陣式按鍵作為鍵盤輸入模塊。

3 系統硬件設計3.1 系統硬件原理圖
    將電話撥號鍵盤上所撥號碼顯示在1602液晶屏上的電路如圖3.1所示。

圖3.1系統硬件原理圖
3.2主芯片模塊
    AT89C51是一種帶4K字節閃存可編程可擦除只讀存儲器FPEROM—Falsh Programmable and Erasable Read Only Memory )的低電壓、高性能CMOS8位微處理器,俗稱單片機。AT89C2051是一種帶2K字節閃存可編程可擦除只讀存儲器的單片機。單片機的可擦除只讀存儲器可以反復擦除1000次。該器件采用ATMEL高密度非易失存儲器制造技術制造,與工業標準的MCS-51指令集和輸出管腳相兼容。由于將多功能8位CPU和閃爍存儲器組合在單個芯片中,ATMEL的AT89C51是一種高效微控制器,AT89C2051是它的一種精簡版本。AT89C51單片機為很多嵌入式控制系統提供了一種靈活性高且價廉的方案。如圖3.2所示。

圖3.2 AT89C51芯片引腳圖
3.2.1 AT89C51芯片引腳
管腳說明
VCC:供電電壓。
GND:接地。
P0口:P0口為一個8位漏級開路雙向I/O口,每腳可吸收8TTL門電流。當P0口的管腳第一次寫1時,被定義為高阻輸入。P0能夠用于外部程序數據存儲器,它可以被定義為數據/地址的第八位。在FIASH編程時,P0 口作為原碼輸入口,當FIASH進行校驗時,P0輸出原碼,此時P0外部必須被拉高。
P1口:P1口是一個內部提供上拉電阻的8位雙向I/O口,P1口緩沖器能接收輸出4TTL門電流。P1口管腳寫入1后,被內部上拉為高,可用作輸入,P1口被外部下拉為低電平時,將輸出電流,這是由于內部上拉的緣故。在FLASH編程和校驗時,P1口作為第八位地址接收。
P2口:P2口為一個內部上拉電阻的8位雙向I/O口,P2口緩沖器可接收,輸出4個TTL門電流,當P2口被寫“1”時,其管腳被內部上拉電阻拉高,且作為輸入。并因此作為輸入時,P2口的管腳被外部拉低,將輸出電流。這是由于內部上拉的緣故。P2口當用于外部程序存儲器或16位地址外部數據存儲器進行存取時,P2口輸出地址的高八位。在給出地址“1”時,它利用內部上拉優勢,當對外部八位地址數據存儲器進行讀寫時,P2口輸出其特殊功能寄存器的內容。P2口在FLASH編程和校驗時接收高八位地址信號和控制信號。
P3口:P3口管腳是8個帶內部上拉電阻的雙向I/O口,可接收輸出4個TTL門電流。當P3口寫入“1”后,它們被內部上拉為高電平,并用作輸入。作為輸入,由于外部下拉為低電平,P3口將輸出電流(ILL)這是由于上拉的緣故。P3口也可作為AT89C51的一些特殊功能口,如表3.1所示。
表3.1 P3口特殊功能表
接口
功能
P3.0 /RXD
串行輸入口
P3.1 /TXD
串行輸出口
P3.2 /INT0
外部中斷0
P3.3 /INT1
外部中斷1
P3.4 /T0
記時器0外部輸入
P3.5 /T1
記時器1外部輸入
P3.6 /WR
外部數據存儲器寫選通
P3.7 /RD
外部數據存儲器讀選通

    P3口同時為閃爍編程和編程校驗接收一些控制信號。
RST:復位輸入。當振蕩器復位器件時,要保持RST腳兩個機器周期的高電平時間。
ALE/PROG:當訪問外部存儲器時,地址鎖存允許的輸出電平用于鎖存地址的地位字節。在FLASH編程期間,此引腳用于輸入編程脈沖。在平時,ALE端以不變的頻率周期輸出正脈沖信號,此頻率為振蕩器頻率的1/6。因此它可用作對外部輸出的脈沖或用于定時目的。然而要注意的是:每當用作外部數據存儲器時,將跳過一個ALE脈沖。如想禁止ALE的輸出可在SFR8EH地址上置0。此時,ALE只有在執行MOVX,MOVC指令是ALE才起作用。另外,該引腳被略微拉高。如果微處理器在外部執行狀態ALE禁止,置位無效。
/PSEN:外部程序存儲器的選通信號。在由外部程序存儲器取指期間,每個機器周期兩次/PSEN有效。但在訪問外部數據存儲器時,這兩次有效的/PSEN信號將不出現。
/EA/VPP:當/EA保持低電平時,則在此期間外部程序存(0000H-FFFFH),不管是否有內部程序存儲器。注意加密方式1時,/EA將內部鎖定為RESET;當/EA端保持高電平時,此間內部程序存儲器。在FLASH編程期間,此引腳也用于施加12V編程電源(VPP)。
XTAL1:反向振蕩放大器的輸入及內部時鐘工作電路的輸入。
XTAL2:來自反向振蕩器的輸出。
3.2.2晶振和復位電路模塊
    (1)復位電路
單片機需要復位以后才能正常工作,復位的目的就是使單片機處于一個基準點,在這個基準點,程序將會從C51的main()主函數的第一條語句開始執行。復位工作是一個純硬件的工作,一般是在上電開始幾毫秒內執行完畢。
復位的過程很簡單,在電源剛剛合上時,電流經過電阻對電解電容器充電,這樣在電阻上就形成一個電壓,對于單片機來說,這個電壓就是復位電壓。經過若干毫秒以后,電解電容器被充滿電,這時電阻就沒有電流流過,電阻兩端也就沒有電壓,單片機的復位腳電壓恢復為0,復位工作結束,單片機開始工作。晶振和復位電路模塊是系統中很重要的一部分,如圖3.3所示。



圖3.3 晶振和復位電路
   (2)晶振電路
  在AT89C51單片機內部有一振蕩電路,只要在單片機的XTAL1和XTAL2引腳外接晶振,就改成了自激振蕩器并在單片機內部產生時鐘脈沖信號。
如圖3.3所示,單片機工作的時間基準是由時鐘電路提供的。在單片機的XTAL1和XTAL2兩個引腳間,接一個晶振及兩只電容就構成了時鐘電路。
電路中的器件可以通過計算和實驗確定,也可以參考一些典型電路參數。電路中,電容器C1和C2對晶振器頻率有微調作用,通常取值范圍30+10pF;石英晶體選擇6MHZ或12MHZ都可以。其結果只是機器周期時間不同,影響計算器的計數初值。
3.3顯示電路模塊
本設計中重點部分是基于單片機系統的液晶顯示部分。液晶顯示模塊是一種將液晶顯示器件、連接件、集成電路、PCB線路板、背光源、結構件裝配在一起的組件,英文名叫“LCD Module”, 簡稱“LCM”,中文一般為“液晶顯示模塊”。在單片機系統中使用液晶顯示模塊作為輸出有以下優點:顯示資料高、數字式接口、功率消耗小、電路中的應用。

3.3.1 1602LCD簡介
工業字符型液晶能夠同時顯示16*2即32個字,(16列2行)1602字符型LCD通常有14條引腳線或16條引腳線的LCD,多出來的兩條是背光電源線。 一般1602字符型液晶顯示器實物如圖3.4所示。
圖3.4 1602LCD的實物圖
1602LCD分為帶背光和不帶背光兩種,基控制器大部分為HD44780,帶背光的比不帶背光的厚,應用中并無差別。
1602LCD原件顯示原理如圖3.5所示。

圖3.5 1602LCD原件顯示原理圖


1602LCD采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如表3.2所示。
表3.2 引腳接口說明表
編號
符號
引腳說明
編號
符號
引腳說明
1
VSS
電源地
9
D2
數據
2
VDD
電源正極
10
D3
數據
3
VEE
液晶顯示偏壓
11
D4
數據
4
RS
數據/命令選擇
12
D5
數據
5
R/W
讀/寫選擇
13
D6
數據
6
E
使能信號
14
D7
數據
7
D0
數據
15
BLA
背光源正極
8
D1
數據
16
BLK
背光源負極

第1腳:VSS為地電源。
第2腳:VDD接5V正電源。
第3腳:VEE為液晶顯示器對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。
第4腳:RS為寄存器選擇,高電平時選擇數據寄存器、低電平時選擇指令寄存器。
第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入數據。
第6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令。
第7~14腳:D0~D7為8位雙向數據線。
第15腳:背光源正極。
第16腳:背光源負極。
1602LCD的控制命令表如表3.3所示。
表3.3 控制命令表
序號
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清顯示
0
0
0
0
0
0
0
0
0
1
2
光標返回
0
0
0
0
0
0
0
0
1
*
3
置輸入模式
0
0
0
0
0
0
0
1
I/D
S
4
顯示開/關控制
0
0
0
0
0
0
1
D
C
B
5
光標或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符發生存貯器地址
0
0
0
1
字符發生存貯器地址
8
置數據存貯器地址
0
0
1
顯示數據存貯器地址
9
讀忙標志或地址
0
1
BF
計數器地址
10
寫數到CGRAM或DDRAM)
1
0
要寫的數據內容
11
從CGRAM或DDRAM讀數
1
1
讀出的數據內容

1602液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明:1為高電平、0為低電平)
指令1:清顯示,指令碼01H, 光標復位到地址00H位置。
指令2:光標復位,光標返回到地址00H。
指令3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S: 屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。
指令4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。
指令5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。
指令6:功能設置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。
指令7:字符發生器RAM地址設置。
指令8:DDRAM地址設置。
指令9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如果為低電平表示不忙。
指令10:寫數據。
指令11:讀數據。
3.3.2 1602LCD的RAM地址映射及標準字庫表
液晶顯示模塊是一個慢顯示器件,所以在執行每條指令前一定要確認模塊的忙標志為低電平,表示不忙,否則此指令失效。要顯示字符時要先輸入顯示字符地址,也就是告訴模塊在哪里顯示字符,圖3.6是1602的內部顯示地址。
圖3.6 1602LCD內部顯示地址
例如第二行第一個字符的地址是40H,那么是否直接寫入40H就可以將光標定位在第二行第一個字符的位置呢?這樣不行,因為寫入顯示地址時要求最高位D7恒定為高電平1所以實際寫入的數據應該是01000000B(40H)+10000000B (80H) =11000000B (C0H) 。
在對液晶模塊的初始化中要先設置其顯示模式,在液晶模塊顯示字符時光標是自動右移的,無需人工干預。每次輸入指令前都要判斷液晶模塊是否處于忙的狀態。1602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A”。其中字符代碼與字符圖形對應關系如圖3.7所示。

圖3.7字符代碼與字符圖形對應關系
3.3.3 1602LCD的一般初始化過程
延時15mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
延時5mS
寫指令38H(不檢測忙信號)
以后每次寫指令、讀/寫數據操作均需要檢測忙信號
寫指令38H:顯示模式設置
寫指令08H:顯示關閉
寫指令01H:顯示清屏
寫指令06H:顯示光標移動設置
寫指令0CH:顯示開及光標設置
3.4矩陣鍵盤輸入電路模塊3.4.1矩陣鍵盤的基本結構
矩陣鍵盤中的鍵實際上就是一個機械開關,位于行線和列線的交點處,圖3.8所示為本設計中使用的4行×3列的12鍵矩陣鍵盤,當鍵被按下時,其交點的行線和列線接通,使相應行線或列線上的電平發生變化,根據電平變化情況確定被按下的鍵。              

圖3.8鍵盤排列圖                                                  
3.4.2矩陣鍵盤的按鍵識別方法
常用的鍵盤識別方法有:行掃描法,線翻轉法和利用8279鍵盤接口的中斷法。前兩種方法相當于查詢法,需要反復查詢按鍵的狀態,會占用大量的CPU時間。后一種方法在有鍵按下時向CPU申請中斷,平時并不需要占用CPU時間。在本系統中,完全可以不使用中斷法完成鍵盤接口,這是由系統的特殊性決定的。首先,對于本系統而言,要實現便攜式的設計,硬件電路使用的器件越少越好。其次,被測信號由外中斷引腳輸入,未占用單片機4個并行I/O口中的任何一個,系統有足夠的資源利用自身I/O 口完成接口。最后,只有當傳感器輸出信號頻率為空載頻率,系統處于空閑待測的狀態下,才允許鍵盤輸入,因此鍵盤識別占用的CPU時間不會對系統正常工作造成影響。因此直接利用單片機并行接口完成鍵盤的接口,采用行掃描法進行鍵盤識別。

行掃描法又稱為逐行(或列)掃描查詢法,是一種最常用的按鍵識別方法,如圖3.9所示鍵盤。
圖3.9鍵盤原理圖
(1)判斷鍵盤上是否有鍵閉合
將全部行線置低電平,然后檢測列線的狀態。只要有一列的電平為低,則表示鍵盤中有鍵被按下,而且閉合的鍵位于低電平線與4根行線相交叉的4個按鍵之中。若所有列線均為高電平,則鍵盤中無鍵按下。
(2)去除鍵的機械抖動
為保證鍵的正確識別,需要進行去抖動處理。其方法是得知鍵盤上有鍵閉合后延遲一段時間,再判別鍵盤的狀態,若仍有鍵閉合,則認為鍵盤上有一個鍵處于穩定的閉合期,否則認為是鍵的抖動或者是干擾。
(3)確定閉合鍵的物理位置
在確認有鍵按下后,即可進入確定具體閉合鍵的過程。其方法是:依次將行線置為低電平,即在置某根行線為低電平時,其它線為高電平。在確定某根行線位置為低電平后,再逐行檢測各列線的電平狀態。若某列為低,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵。
(4)得到閉合鍵的編號
在得到閉合鍵的物理位置的基礎上,根據給定的按鍵編號規律,計算得出閉合鍵的編號。
(5)確保CPU對鍵的一次閉合僅做一次處理
為實現這一功能,可以采用等待閉合鍵釋放以后在處理的方法。
4 系統軟件設計
C51單片機可以應用匯編語言和C語言進行編程。匯編語言與機器指令一一對應,所以用匯編語言編寫的程序在單片機里運行起來效率較高,但可移植性差。C語言程序可讀性高,也便于移植到其它系統中,故本次設計使用C語言編程。
4.1 程序設計整體思路
本設計是由單片機控制的LCD顯示系統,另外鍵盤來控制顯示的方式。
用P3口作為鍵盤的輸入端,對于按鍵的識別方式可以是中斷也可以是查詢,在此設計中所選用的是行掃描法進行鍵盤識別。
用P0口作為LCD的顯示控制端,由于此LCD的顯示屏被分為了兩部分,所以應該對LCD顯示位置進行設置。由此LCD的顯示時序可知,在顯示過程中還需要一定的延時并且在顯示前需將一些特定的控制端置相應的電平,所以還需要一個適當的延時子程序以及輸入數據前的準備程序。除了這些外,還應寫一個初始化程序,用來對LCD進行初始化設置。
最后就是主函數,它的主要功能就是判斷鍵盤上是否有按鍵閉合,若有按鍵閉合,然后根據按下的是哪一個鍵來執行相應的程序,選擇相應的顯示方式。系統功能設計框圖如圖4.1所示。


                      圖4.1 系統功能設計框圖

4.2.主要功能模塊設計
    系統主程序設計流程圖如圖4.2,其源代碼見附件1。

圖片見附件
圖4.2 系統主程序設計流程圖

    系統第一次上電后,先進行初始化,初始化LCD模塊,設置LCD中各個部分的顯示內容,然后進行鍵盤掃描,獲取按鍵,以及根據各按鍵的不同執行相應的操作,最后等待釋放,釋放之后再進行鍵盤掃描,循環以上操作。
4.2.1 鍵盤掃描模塊設計
鍵盤上有很多鍵,每一個鍵對應一個鍵碼,以便根據鍵碼轉到相應的鍵處理子程序,進一步實現數據輸入和命令處理的功能。
鍵盤掃描子程序設計流程圖如圖4.3所示,其源代碼見附件1。



下面給出一個具體的例子解釋圖4.3的流程。
如圖3.2所示,AT89C51單片機的P3口用作鍵盤I/O口,鍵盤的列線接到P3口的低4位,鍵盤的行線接到P3口的高4位。列線P3.0-P3.3分別接有4個上拉電阻到正電源+5V,并把列線P3.0-P3.3設置為輸入線,行線P3.4-P3.7設置為輸出線。4根行線和4根列線形成16個相交點。
(1)檢測當前是否有鍵被按下。檢測的方法是P3.4-P3.7輸出全“0”,讀取P3.0-P3.3的狀態,若P3.0-P3.3為全“1”,則無鍵閉合,否則有鍵閉合。
(2)去除鍵抖動。當檢測到有鍵按下后,延時一段時間再做下一步的檢測判斷。
(3)若有鍵被按下,應識別出是哪一個鍵閉合。方法是對鍵盤的行線進行掃描。P3.4-P3.7按下述4種組合依次輸出如表 4.1所示。
表4.1 鍵盤掃描
I/O口
高低電平(0或1)
P3.7
1
1
1
0
P3.6
1
1
0
1
P3.5
1
0
1
1
P3.4
0
1
1
1

   (4)在每組行輸出時讀取P3.0-P3.3,若全為“1”,則表示為“0”這一行沒有鍵閉合,否則有鍵閉合。由此得到閉合鍵的行值和列值,然后可采用計算法或查表法將閉合鍵的行值和列值轉換成所定義的鍵值。鍵盤掃描主要代碼如下:
uchar GetKey ()
              {
                uchar i, j, k = 0;
                uchar KeyScanCode [] = {0xEF, 0xDF, 0xBF, 0x7F}; //鍵盤掃描碼
                uchar KeyCodeTable[] ={0xEE,0xED,0xEB,0xDE,0xDD,0xDB,
0xBE,0xBD,0xBB,0x7E,0x7D,0x7B}; //鍵盤特征碼
                P3 = 0x0F;//掃描鍵盤獲取按鍵序號
              if (P3! = 0x0F)  DelayMS(20);//延時去機械抖動
    if (P3! = 0x0F)
                {
                            for (i = 0; i< 4;i++)
                            {  P3 = KeyScanCode;
                                          for (j = 0;j < 3;j++)
                                          {  k = i * 3 + j;
                                                        if (P3 == KeyCodeTable[k]) return k;}
                            }
                }
                else return 0xFF;
              }
//--------------------------------------------------------------------
4.2.2 LCD顯示模塊設計
LCD LM016L的顯示函數很簡單,只要按照時序圖操作,結合相關指令集,寫好LCD初始化程序,清屏程序,寫指令程序,寫數據程序,讀數據程序等一系列驅動程序,可完成LCD的所有顯示需要。在本設計中,由于要顯示的內容比較多,且有些需重復顯示,有些只要顯示一次,故只畫液晶顯示的基本流程。
LCD顯示模塊流程如圖4.4所示,其源代碼見附件1。








                        圖4.4 LCD顯示模塊流程圖

5 系統仿真與調試5.1系統運行環境
  (1)本系統的硬件電路是在Proteus電路仿真軟件上運行的。
  (2)本系統的軟件是在 Keil uVision3 上編譯運行的。
  (3)通過Proteus與Keil連調實現電路仿真。
5.2 系統仿真說明5.2.1 KEILC調試
打開Keil新建工程文件,然后添加源程序文件,保存時把文件后綴名改成“.c”,再直接導入新建的工程中。
把源程序全部錄入后,先粗略的檢查一遍,主要改正明顯的各種錯誤,這樣可以減少之后的修改工作量。接著Options for Target “Target 1” ,點擊Output ,勾選Create Hex 那個選項,一邊生成可執行的文件。然后點擊Project菜單下的Built Target命令然后再進行編譯、連接,形成目標文件。編譯、連接用Project菜單下的Built Target命令(或快捷鍵F7),也可以直接點擊工具欄中相對應的圖標。.
編譯、連接時,如果程序存在語法有錯,則不會通過編譯,并在下面的信息窗口給出相應的出錯提示信息,其中錯誤是一定得改正的,警告可以忽略。雙擊下面顯示錯誤信息的那一行,可以直接定位錯誤所在的行,用戶可以方便的對程序進行修改。修改后再編譯、連接,繼續進行調試,這個過程可能會重復多次。如果沒有任何語法上的錯誤,則編譯、連接成功,并且信息窗口給出提示信息。
5.2.2 Proteus調試
在Proteus軟件中先從元件庫中加載要使用的那些元件,然后把元件放在圖紙上一個一個的接線,盡量不讓線交錯,便于查看、分析,有必要時,使用接線標號法,完成所有元器件的接線。
5.2.3 Proteus與Keilc聯調實現電路仿真
在Proteus中雙擊AT89C51,在彈出的窗口中Program File后面選擇在Keil中生成的以“.hex”為后綴名的文件,為單片機添加可執行文件。然后點擊左下角的相關圖標,開始進行仿真。
仿真運行結果如下圖5.1所示。

圖5.1 電路仿真圖



總  結
隨著IT行業的不斷發展,傳統的固定電話已漸漸不能滿足人們日常的通信需求,而更智能、更人性化、微小型、多元化的電子產品成為了現代化電子產業的主要發展方向。本系統就是基于這樣一個背景下開始設計的。系統以AT89C51芯片作為主控模塊,鍵盤作為輸入電路模塊,1602LCD作為顯示電路模塊,實現了以下功能如下:
(1)系統運行時將所按下的鍵盤顯示在液晶屏上;
(2)電話號碼鍵盤上的“*”鍵能夠實現退格功能;
(3)電話號碼鍵盤上的“#”鍵能夠實現清除功能;
(4)每按下一個鍵盤能夠發出聲音;
通過此次設計本人在各方面有了一定的提高。
首先,通過這次設計,我不僅對理論有了更深一步的認識,增強了和外界技術的溝通,還培養了自學能力和分析解決問題的能力,更重要的是,培養了克服困難的勇氣和信心。
其次,培養了自己的市場觀念。一個商品是否能夠搶占市場,除了必須的功能和質量要求外,其價格是最大的競爭優勢。如何在保證質量和完成同等功能的情況下,把產品的成本降到最低。是每個設計人員在作出方案時首要考慮的因素。
此次設計不僅鍛煉了我們理論和實踐相結合的綜合能力,還使得我對專業有了更深一步的了解,鞏固了我們所學的專業基礎知識,提高了我們解決實際工程問題的能力,同時也提高我們查閱文獻資料、設計手冊、設計規范的動手能力,通過對整體的掌控,對局部的取舍,以及對細節的斟酌處理,都使我的能力得到了鍛煉,經驗得到了豐富,并且意志力,抗壓能力也都得到了不同程度的提升。這正是我們進行設計的目的所在。
“團結、合作、謙虛”這三個詞我的體會也比較深。做任何事包括做實驗都不是孤立的,不是你“閉門造車”,而是一個需要和他人交往的過程。這就要求我們要團結,要有合作精神,要注意和他人的溝通,要謙虛,不懂就問所謂“知之為知之,不知為不知”。
總之,在整個實驗操作和文檔完成的過程中,我體會到的是實驗的艱辛和收獲的充實,感受到的是一種堅持不懈、契而不舍的科研精神。對我以后的深造學習有重要的意義。























致  謝
設計即將完成之際,我特別想借此機會感謝一下賈老師。賈老師在百忙之中抽出時間,從方案的論證、資料的查閱、電路的設計、調試、文檔的撰寫、修改,都進行了一絲不茍的指導和嚴格的要求,她的悉心指導是我設計能如期完成的重要因素,在此我衷心的感謝賈老師給我提供的大量指導與幫助。
同時,在此我也非常感謝小組同學給我提供幫助。在設計過程中,我遇到的問題有很多,在編程上給了我很多指導,在他們的幫助下我才能完成整體程序的編制。可以說,本設計的順利完成,他們對我的幫助是不可忽視的。在此,我要向他們表示由衷的感謝。
最后,感謝學校三年來對我的培養與教育,感謝學院各級領導及相關老師對我三年來成長的關心與本設計的指導。感謝所有在我完成本設計過程中給予我幫助的同學和朋友。也祝愿大家身體健康,工作順利,合家歡樂,萬事如意!








參考文獻
[1] 李朝青編著,單片機原理及接口技術.北京:北京航空航天大學出版社,2006.
[3] 張毅剛編著,單片機原理極其應用.哈爾濱:哈爾濱工業大學出版社,2004.
[4] 趙建領編著,51系列單片機開發寶典.電子工業出版社,2007.
[5] 潘永雄編著,新編單片機原理與應用.西安電子科技大學出版社,2003.
[6] 李國興、李偉編著,單片機開發應用技術.北京大學出版社,2007.
[7] 劉瑞新編著,單片機原理及應用教程.機械工業出版社,2003.
[8] 譚浩強編著,C程序設計(第二版) [M]. 北京: 清華大學出版社, 1999.12.
[9]楊居義編著,單片機設計實例教程.清華大學出版社,2010.8.
[10] 趙又新著,微機原理與接口技術.中國電力出版社,2007.
[11] 韓曉東、李勇江等著,Protel 99 SE電路設計實用教程. 中國鐵道出版社,2008.
[12] 胡漢才,單片機原理及其接口技術.清華大學出版社,2010.
[13] 陳忠平編著,51單片機C語言程序設計經典實例. 電子工業出版社,2012.



程序代碼:
  1. //-------------------------------------------------------------------
  2. // 名稱:1602顯示電話撥號鍵盤按鍵
  3. // 說明: 本例將電話撥號鍵盤上所撥號碼顯示在1602液晶屏上。
  4. //--------------------------------------------------------------------
  5.   #include <reg51.h>
  6.   #include <intrins.h>
  7.   #define uchar unsigned char
  8.   #define uint unsigned int
  9.   #define DelayNOPx() {_nop_();_nop_();_nop_();_nop_();}
  10.   sbit  BEEP =    P1^0;
  11.   sbit  RS = P2^0;
  12.   sbit  RW = P2^1;
  13.   sbit  E = P2^2;
  14.   void DelayMS (uint ms);   //聲明延時函數
  15.   bit    LCD_Busy ();
  16.   void    LCD_Pos (uchar);
  17.   void    LCD_Wcmd (uchar);
  18.   void    LCD_Wdat (uchar);
  19. //--------------------------------------------------------------------
  20. //  標題字符串
  21.   char code Title_Text[] = {"-- Phone Code --"};
  22. //    鍵盤序號與鍵盤符號映射表
  23.   uchar code Key_Table[]={'1','2','3','4','5','6','7','8','9','*','0','#'};
  24. //    鍵盤撥號數字緩沖
  25.   uchar Dial_Code_Str[] = {"              "};
  26.   uchar KeyNo = 0xFF;
  27.   int tCount = 0;
  28. //-------------------------------------------------------------------
  29. //    延時
  30. //-------------------------------------------------------------------
  31.      void DelayMS (uint x)
  32. {
  33.     uchar i;
  34.     while(x--) for (i = 0;i < 120; i++);
  35. }
  36. //------------------------------------------------------------------
  37. //    在LCD指定鍵盤上顯示字符串
  38. //-------------------------------------------------------------------
  39. void Display_String(uchar * str,uchar LineNo)
  40. {
  41.       uchar k;
  42.       LCD_Pos(LineNo);
  43.       for (k = 0; k< 16; k++) LCD_Wdat (str[k]);
  44. }
  45. //--------------------------------------------------------------------
  46. //    LCD狀態檢測
  47. //--------------------------------------------------------------------
  48.   bit LCD_Busy ()
  49.   {
  50.     bit result;
  51.     RS =0;RW =1;E=1;DelayNOPx();result = (bit)(P0 & 0x80); E= 0;
  52.     return result;
  53.   }
  54. //--------------------------------------------------------------------
  55. //    寫LCD命令
  56. //--------------------------------------------------------------------
  57.   void LCD_Wcmd (uchar cmd)
  58.   {
  59.      while (LCD_Busy ()); //判斷LCD是否忙碌
  60.      RS=0;RW=0;E=0;_nop_();_nop_();
  61.      P0=cmd;DelayNOPx();E=1;DelayNOPx();E=0;
  62.   }
  63. //-------------------------------------------------------------------
  64. //    寫LCD數據
  65. //--------------------------------------------------------------------
  66.    void LCD_Wdat (uchar str)
  67.    {
  68.       while (LCD_Busy ()); //判斷LCD是否忙碌
  69.       RS =1;RW =0;E=0;
  70.       P0=str; DelayNOPx ();
  71.       E=1;DelayNOPx();E=0;
  72.    }
  73. //--------------------------------------------------------------------
  74. //    LCD初始化
  75. //--------------------------------------------------------------------
  76.    void LCD_Init()
  77.    {
  78.       LCD_Wcmd(0x38);DelayMS(1);//設定LCD為16*2顯示,5*7點陣,8位數據接口
  79.       LCD_Wcmd(0x0c);DelayMS(1);//開顯示,不顯示光標
  80.       LCD_Wcmd(0x06);DelayMS(1);//顯示光標,自動右移,整屏不要動
  81.       LCD_Wcmd(0x01);DelayMS(1);//顯示清屏
  82.    }
  83. //--------------------------------------------------------------------
  84. //    設置LCD顯示位置
  85. //--------------------------------------------------------------------
  86.    void LCD_Pos (uchar pos)
  87.    {
  88.      LCD_Wcmd(pos | 0x80);
  89.    }
  90. //--------------------------------------------------------------------
  91. //    T0控制按鍵聲音
  92. //--------------------------------------------------------------------
  93.     void T0_INT () interrupt 1
  94.     {
  95.         TH0 = -600 / 256;
  96.         TL0 = -600 % 256;
  97.         BEEP = ~BEEP;
  98.         if (++tCount == 200)
  99.         {
  100.              tCount = 0; TR0 = 0;
  101.         }
  102.     }
  103. //--------------------------------------------------------------------
  104. //    鍵盤掃描
  105. //--------------------------------------------------------------------
  106.     uchar GetKey ()
  107.     {
  108.       uchar i, j, k = 0;
  109.       uchar KeyScanCode [] = {0xEF, 0xDF, 0xBF, 0x7F}; //鍵盤掃描碼
  110.       uchar KeyCodeTable[] ={0xEE,0xED,0xEB,0xDE,0xDD,0xDB,
  111. 0xBE,0xBD,0xBB,0x7E,0x7D,0x7B}; //鍵盤特征碼
  112.       P3 = 0x0F;//掃描鍵盤獲取按鍵序號
  113.       if (P3!= 0x0F)  DelayMS(20);//延時去機械抖動
  114.     if (P3!= 0x0F)
  115.       {
  116.           for (i = 0; i< 4;i++)
  117.          {
  118.             P3 = KeyScanCode[i];
  119.             for (j = 0;j < 3;j++)
  120.             {
  121.                 k = i * 3 + j;
  122.                 if (P3 == KeyCodeTable[k]) return k;

  123.             }
  124.          }
  125.       }
  126.       else return 0xFF;
  127.     }
  128. //--------------------------------------------------------------------
  129. //    主程序
  130. //--------------------------------------------------------------------
  131. void main()
  132. {
  133.     uchar i = -1,j,a;
  134.     P0 = P2 = P1 = 0xFF;
  135.     IE = 0x82;
  136.   TMOD = 0X01;//寄存器工作方式設定為模式1
  137.   LCD_Init();//初始化LCD
  138.   Display_String (Title_Text,0x00);//在第一行顯示標題
  139.   while(1)
  140.   {
  141.         KeyNo = GetKey();//獲取按鍵
  142.         if (KeyNo ==0xFF) continue;//無按鍵時繼續掃描
  143.          i++;
  144.        if(KeyNo==9)
  145.          { Dial_Code_Str[i-1]= ' ';i=i-2;     }  //按”*”鍵退格
  146.         else   
  147.      {  if (KeyNo==11)   
  148.        {for (a = 0;a< 16;a++) Dial_Code_Str[a] = ' '; i=-1;}//按鍵“#”鍵清空
  149.           else    if (i == 11)
  150.           {for (j = 0;j < 16;j++) Dial_Code_Str[j] = ' ';i = 0;} //超過11位清空
  151.          Dial_Code_Str[i] = Key_Table [KeyNo];    }
  152.          Display_String (Dial_Code_Str, 0x40); //在第二行顯示號碼
  153.          TR0 = 1;//T0中斷控制按鍵聲音
  154.          while(GetKey()!=0xFF);//等待釋放
  155.                  
  156.     }
  157. }
復制代碼

以上圖文的Word格式文檔下載(內容和本網頁上的一模一樣,方便大家保存):
基于單片機的電話撥號系統的設計.doc (568.5 KB, 下載次數: 325)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂3 踩
回復

使用道具 舉報

27#
ID:1013883 發表于 2024-11-2 10:36 | 只看該作者
嘿嘿,把哥哥,現在從事嵌入式行業嗎?
回復

使用道具 舉報

26#
ID:1118927 發表于 2024-6-13 09:21 | 只看該作者
為什么矩陣鍵盤不能用,只有獨立按鍵可以按
回復

使用道具 舉報

25#
ID:1124627 發表于 2024-6-11 23:45 來自手機 | 只看該作者
總結的好好
回復

使用道具 舉報

24#
ID:1105363 發表于 2023-12-21 11:28 | 只看該作者
有沒有好心人可以給我看看那個主程序設計模塊的流程圖還還控制聲音的代碼
回復

使用道具 舉報

23#
ID:1038458 發表于 2022-7-7 17:29 | 只看該作者
word里面的代碼不對啊,可能是全角字符問題,還是用網頁上面的可以
回復

使用道具 舉報

22#
ID:44459 發表于 2022-4-4 00:20 | 只看該作者
額 以為是解析DTMF  不過也很不錯了
回復

使用道具 舉報

21#
ID:1014576 發表于 2022-3-31 14:06 | 只看該作者
加個調制解調電路更完美
回復

使用道具 舉報

20#
ID:1014175 發表于 2022-3-31 10:05 | 只看該作者
3347702066 發表于 2020-7-12 08:56
感謝分享,仿真結果終于成功了

請問結尾實現鍵盤清空功能時,a未定義的問題怎么解決的?
還有源代碼,能分享一下嗎?
回復

使用道具 舉報

19#
ID:1014175 發表于 2022-3-31 10:00 | 只看該作者
YGYG.1014 發表于 2020-6-28 14:44
厲害了,結果完美運行

請問結尾實現鍵盤清空功能時,a未定義的問題怎么解決的?
回復

使用道具 舉報

18#
ID:931449 發表于 2021-6-16 15:43 來自手機 | 只看該作者
樓主有源文件嗎?
回復

使用道具 舉報

17#
ID:931299 發表于 2021-6-2 19:03 | 只看該作者
ZPDN 發表于 2018-11-7 09:40
這個149行的a為啥未定義呀

直接復制網頁里面的程序可以用  但是word里面的不行
回復

使用道具 舉報

16#
ID:794330 發表于 2020-7-12 08:56 來自手機 | 只看該作者
感謝分享,仿真結果終于成功了
回復

使用道具 舉報

15#
ID:801284 發表于 2020-7-10 21:49 | 只看該作者
YGYG.1014 發表于 2020-6-28 14:44
厲害了,結果完美運行

老鐵,有源文件嗎
回復

使用道具 舉報

14#
ID:717851 發表于 2020-7-1 14:25 | 只看該作者
直接復制網頁里面的程序可以用  但是word里面的不行
回復

使用道具 舉報

13#
ID:791685 發表于 2020-6-28 14:44 | 只看該作者
厲害了,結果完美運行
回復

使用道具 舉報

12#
ID:791685 發表于 2020-6-28 12:57 | 只看該作者
keil3中應該輸入哪些代碼?
回復

使用道具 舉報

11#
ID:438381 發表于 2018-12-3 14:30 來自手機 | 只看該作者
aixf 發表于 2017-12-27 19:54
有源文件嗎?

能發我
一份源程序嗎
回復

使用道具 舉報

10#
ID:421553 發表于 2018-11-7 09:40 | 只看該作者
這個149行的a為啥未定義呀?但是網頁上面的程序可以用
回復

使用道具 舉報

9#
ID:421553 發表于 2018-11-6 10:30 | 只看該作者
666 厲害啊
回復

使用道具 舉報

8#
ID:390236 發表于 2018-8-28 13:11 | 只看該作者
89c52rc能用在這個程序嗎?
回復

使用道具 舉報

7#
ID:362964 發表于 2018-7-2 11:07 | 只看該作者
老哥666
回復

使用道具 舉報

6#
ID:309549 發表于 2018-4-16 20:06 | 只看該作者
解惑不少 感謝分享
回復

使用道具 舉報

5#
ID:272575 發表于 2018-1-6 22:49 | 只看該作者
非常有用 感謝感謝
回復

使用道具 舉報

地板
ID:267982 發表于 2017-12-27 21:23 | 只看該作者
非常感謝樓主分享
回復

使用道具 舉報

板凳
ID:252394 發表于 2017-12-27 19:55 | 只看該作者
我想要這個系統的源文件圖和代碼可以嗎?
回復

使用道具 舉報

沙發
ID:252394 發表于 2017-12-27 19:54 | 只看該作者
有源文件嗎?
回復

使用道具 舉報

樓主
ID:208740 發表于 2017-6-7 12:03 來自手機 | 只看該作者
厲害了,我也想做這個類似的
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩一区二区三区av | 久久精品 | 欧美在线色 | 五十女人一级毛片 | 国产精品久久久亚洲 | 欧美日日日日bbbbb视频 | 精品视频在线播放 | 日韩视频在线免费观看 | 亚洲国产成人在线观看 | 色天天综合 | 91超碰在线 | 午夜天堂精品久久久久 | 国产成人精品av | 欧美色综合一区二区三区 | 日韩欧美在线观看视频网站 | 亚洲福利在线观看 | 天天拍天天操 | 91偷拍精品一区二区三区 | 中文字幕在线免费观看 | 国产精品夜间视频香蕉 | 免费特黄视频 | av激情在线 | 久久久婷婷 | 水蜜桃久久夜色精品一区 | 日韩亚洲一区二区 | 精品欧美一区二区三区久久久 | 国产成人高清 | 亚洲一区二区三区在线视频 | 国产精品欧美一区二区三区不卡 | 伊人久久在线观看 | 欧美日韩国产精品激情在线播放 | 久久久91 | 91精品国产乱码久久久久久久久 | 色婷婷久久久久swag精品 | 国产成人aⅴ | 黄色网址大全在线观看 | 99精品99| 国产视频中文字幕 | caoporn视频 | 久久久久久久久久久一区二区 | 亚洲成人免费视频在线观看 |