欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 6187|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)自動(dòng)售貨機(jī)源程序與Proteus仿真原理圖及調(diào)試過(guò)程

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
此例程可以用于學(xué)習(xí)單片機(jī)技術(shù),基于51單片機(jī)制作的自動(dòng)售貨機(jī)仿真設(shè)計(jì)與調(diào)試,keil工程+proteus工程
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


設(shè)計(jì)了一款以INTEL公司出品的80C51單片機(jī)為核心的自動(dòng)售貨機(jī),并且著重詳細(xì)地介紹了自動(dòng)售貨機(jī)的整體系統(tǒng)設(shè)計(jì)方案、硬件選擇基礎(chǔ)、軟件使用方法及技巧。以80C51作為CPU處理單元連接各個(gè)功能模塊;以4*4矩陣鍵盤(pán)作為輸入控制模塊對(duì)貨物進(jìn)行種類(lèi)和數(shù)量的選擇以及模擬幣的投入功能;以L(fǎng)CD1602液晶作為顯示模塊來(lái)顯示當(dāng)前的購(gòu)物狀態(tài)以及幣狀態(tài);以L(fǎng)ED的顯示來(lái)表示當(dāng)前選擇貨物以及出貨的狀態(tài)。通過(guò)Protues7.5單片機(jī)電路原理圖進(jìn)行連接布線(xiàn)連接各個(gè)模塊;再用Keil uVision3專(zhuān)業(yè)編譯軟件完成源程序編譯和調(diào)試,最終進(jìn)行自動(dòng)售貨機(jī)的實(shí)驗(yàn)電路仿真來(lái)模擬自動(dòng)售貨。結(jié)合工作原理、系統(tǒng)設(shè)計(jì)、軟件編譯和實(shí)驗(yàn)仿真來(lái)實(shí)現(xiàn)自動(dòng)售貨這一相關(guān)功能。

本課題研究的是通過(guò)核心單片機(jī)80C51控制的自動(dòng)售貨機(jī)。涉及到用keil Uvision3來(lái)進(jìn)行C語(yǔ)言程序的編譯調(diào)試,通過(guò)protues7.5電路連接來(lái)設(shè)計(jì)系統(tǒng)電路。通過(guò)80C51與輸入模塊、輸出顯示模塊、找零模塊、顯示模塊的連接來(lái)系統(tǒng)模擬自動(dòng)售貨這一功能。設(shè)計(jì)從能根據(jù)投入的自動(dòng)售貨的機(jī)器。用4*4矩陣鍵盤(pán)來(lái)模擬貨物種類(lèi)以及數(shù)量的選擇,再通過(guò)鍵盤(pán)其他按鍵來(lái)模擬投功能。用LCD1602作為輸出顯示模塊,通過(guò)液晶顯示來(lái)明確按鍵的功能以及自動(dòng)售貨機(jī)的購(gòu)貨狀態(tài)等。用LED燈來(lái)表示貨物的種類(lèi)。因?yàn)樽R(shí)別功能是在自動(dòng)售貨機(jī)的外部硬件電路方面來(lái)加以具體實(shí)施的,而本設(shè)計(jì)是模擬自動(dòng)售貨機(jī)的功能,所以不考慮識(shí)別的模塊設(shè)計(jì),在這里只作原理介紹。

系統(tǒng)結(jié)構(gòu)
自動(dòng)售貨機(jī)是集光、機(jī)、電一體化的自動(dòng)售貨裝置,能夠獨(dú)立完成自動(dòng)售貨這一功能。
自動(dòng)售貨機(jī)的工作原理是:在初始化的界面等待顧客按鍵選擇貨物的種類(lèi)和數(shù)量顧客投入,按下確定購(gòu)買(mǎi)鍵后等待售貨機(jī)自動(dòng)計(jì)算所購(gòu)商品的總價(jià),然后提示顧客投入。所投的經(jīng)過(guò)外部硬件檢測(cè)傳感器檢測(cè)真假后累加計(jì)數(shù)。若顧客確認(rèn)購(gòu)買(mǎi)系統(tǒng)則跳轉(zhuǎn)到下一步驟,反之取消購(gòu)買(mǎi)即退出幣返回到主界面,等待顧客下一步操作。自動(dòng)售貨機(jī)通過(guò)幣的總價(jià)與和所購(gòu)商品的總價(jià)的差值來(lái)進(jìn)行出貨找零。總體工作原理如圖2.1:
圖2.1 自動(dòng)售貨機(jī)的總體工作原理圖
2.1.2 自動(dòng)售貨機(jī)的控制子系統(tǒng)概述
自動(dòng)售貨機(jī)的控制子系統(tǒng)由以下幾個(gè)部分組成,分別是預(yù)設(shè)自動(dòng)售貨系統(tǒng)、金額累加和找零系統(tǒng)、售完檢測(cè)系統(tǒng)、售出累計(jì)及反饋功能系統(tǒng)。
  • 預(yù)設(shè)自動(dòng)售貨機(jī)系統(tǒng):自動(dòng)售貨機(jī)出售的商品可分為若干個(gè)品種,在其售前設(shè)定價(jià)格時(shí)必須預(yù)先寄存在控制系統(tǒng)內(nèi)。設(shè)定的方式原理:商品的價(jià)格設(shè)置由按鍵和存儲(chǔ)器組成,通過(guò)按鍵選擇被設(shè)價(jià)商品的種類(lèi)及價(jià)格,并將設(shè)定的價(jià)格寫(xiě)入存儲(chǔ)器中,存儲(chǔ)器本身需具有斷電保護(hù)記憶功能,此為采用軟件。此外,如果在自動(dòng)售貨機(jī)中,在出售商品的種類(lèi)少,價(jià)格變化小,使用幣單一的情況下,也可以用比較簡(jiǎn)單的價(jià)格設(shè)定方法----硬件設(shè)置,即采用撥碼開(kāi)關(guān)對(duì)應(yīng)的方式設(shè)置。
  • 金額累加和找零系統(tǒng):控制系統(tǒng)的核心CPU對(duì)識(shí)幣 退、無(wú)貨檢驗(yàn)及購(gòu)貨信號(hào)進(jìn)行循環(huán)檢查。如果顧客投入幣,檢測(cè)到信號(hào)后,通過(guò)通信系統(tǒng)把識(shí)別的幣數(shù)值信號(hào)送入累計(jì)存儲(chǔ)器器中進(jìn)行累加計(jì)數(shù)。要是幣數(shù)值滿(mǎn)足購(gòu)貨需求則通過(guò)串行接口提示購(gòu)貨,售貨機(jī)則通過(guò)并行擴(kuò)展接口驅(qū)動(dòng)電磁閥或者微電機(jī)驅(qū)動(dòng)送出貨物,同時(shí)存儲(chǔ)器計(jì)數(shù)清零跳入到找零系統(tǒng),自動(dòng)售貨完成。如果幣數(shù)值不滿(mǎn)足購(gòu)貨需求則提示顧客繼續(xù)投幣或者取消購(gòu)貨,取消購(gòu)貨后由售貨機(jī)退出投入的幣返回初始化界面。
  • 貨物檢測(cè)系統(tǒng):為了貨物供應(yīng)充足,把接觸開(kāi)關(guān)和行程開(kāi)關(guān)安裝在自動(dòng)售貨機(jī)貨物存儲(chǔ)存道的下方,當(dāng)存儲(chǔ)存道尚有貨物時(shí),行程開(kāi)關(guān)保持閉合,CPU控制自動(dòng)售貨機(jī)正常售貨。貨物供應(yīng)不足的時(shí)候,行程開(kāi)關(guān)自動(dòng)斷開(kāi),向CPU發(fā)出缺貨信號(hào),經(jīng)過(guò)檢測(cè)后發(fā)送到外部電機(jī)或者電磁閥來(lái)推動(dòng)外部貨物進(jìn)入存儲(chǔ)道達(dá)到自動(dòng)添加貨物的目的,以保持貨源充足。
  • 售出累計(jì)及反饋功能系統(tǒng):自動(dòng)售貨機(jī)的CPU在每次售出一種貨物后,由通信系統(tǒng)向出貨存儲(chǔ)器中累計(jì)已經(jīng)售出的數(shù)據(jù),通過(guò)自動(dòng)售貨機(jī)內(nèi)部控制的按鍵可以顯示出累計(jì)數(shù)據(jù)以掌握銷(xiāo)售情況。此外,由外部按鍵操作在按下自測(cè)功能鍵后,出現(xiàn)自測(cè)功能信號(hào),可以通過(guò)檢測(cè)結(jié)果查看各個(gè)模塊的功能情況,也可以檢測(cè)自動(dòng)售貨機(jī)的貨物存儲(chǔ)道驅(qū)動(dòng)功能。

2.2 自動(dòng)售貨機(jī)的功能簡(jiǎn)介
2.2.1 自動(dòng)售貨機(jī)的功能
概述
基本原理:通過(guò)矩陣鍵盤(pán)來(lái)選擇貨物的種類(lèi)與數(shù)量過(guò)后自動(dòng)售貨機(jī)提示。自動(dòng)售貨機(jī)的幣識(shí)別器對(duì)所投幣進(jìn)行識(shí)別,根據(jù)金額大小然后將商品選擇權(quán)通過(guò)LCD液晶顯示給客戶(hù),客戶(hù)按鍵選擇后,CPU控制芯片發(fā)出指令將所選擇商品從儲(chǔ)備料道中送達(dá)取物口。
功能描述:貨物種類(lèi)一共設(shè)有8種,這8種商品通過(guò)選擇按鍵進(jìn)行選擇確認(rèn),通過(guò)數(shù)量選擇按鍵確定購(gòu)買(mǎi)數(shù)量,價(jià)格規(guī)定為1-8元不等;幣識(shí)別器能夠識(shí)別各種。在規(guī)定的時(shí)間內(nèi),投了幾次幣后,幣能夠?qū)崿F(xiàn)自動(dòng)累加功能,這樣設(shè)計(jì)會(huì)把投入的所有幣總額數(shù)目數(shù)據(jù)傳遞到中央控制元器件進(jìn)行處理;在超過(guò)規(guī)定時(shí)間后自動(dòng)關(guān)閉,數(shù)據(jù)處理單元按照總數(shù)和購(gòu)買(mǎi)的數(shù)量和價(jià)格乘積來(lái)進(jìn)行加減運(yùn)算累,實(shí)現(xiàn)購(gòu)買(mǎi)和找回的功能。
本設(shè)計(jì)中有一共有16個(gè)按鍵選擇,其中有兩個(gè)是貨物選擇鍵,有兩個(gè)是數(shù)量選擇鍵,此外還有6個(gè)幣投入鍵1個(gè)確認(rèn)鍵和1個(gè)取消鍵。
2.2.2 自動(dòng)售貨機(jī)的設(shè)計(jì)思路
  • 本設(shè)計(jì)以這樣的工作流程開(kāi)始自動(dòng)售貨機(jī)的自動(dòng)售貨過(guò)程:
  •    啟動(dòng)系統(tǒng),開(kāi)始待機(jī);
  •    顧客通過(guò)按鍵選擇商品的種類(lèi)以及數(shù)量并確認(rèn);
  •    售貨機(jī)檢查是否有足夠的貨物并通過(guò)LCD提示等待顧客投;
  •    顧客投入,售貨機(jī)自動(dòng)檢測(cè)是否足夠;
  •    金額足夠多,售貨機(jī)將推出顧客選擇的相應(yīng)數(shù)量的商品,若金額不足則直接退還;
  •    推出商品,售貨機(jī)轉(zhuǎn)入找零系統(tǒng)退出余;
  •    系統(tǒng)自動(dòng)復(fù)位,完成售貨;
  • 系統(tǒng)采用硬件設(shè)計(jì)思路如圖2.3:
  •    采用單片機(jī)80C51作CPU;
  •    采用P3.5口作為輸入端;
  •    采用LCD1602液晶為顯示模塊:
  •    采用4*4矩陣鍵盤(pán)連接P1口作為貨物選擇選擇端;
  •    采用P0口實(shí)現(xiàn)出貨、找零功能;

圖2.3 自動(dòng)售貨機(jī)系統(tǒng)原理圖
  • 硬件端口的選擇思路:
  •    輸入:由于本設(shè)計(jì)模擬輸入功能是由4*4矩陣鍵盤(pán)來(lái)完成的,而鍵盤(pán)連接在80C51的P1口上,則幣投入設(shè)定為:
P1口的按鍵值為0X04的時(shí)候代表1的投入;
P1口的按鍵值為0X05的時(shí)候代表5的投入;
P1口的按鍵值為0X06的時(shí)候代表10的投入;
P1口的按鍵值為0X07的時(shí)候代表20的投入;
P1口的按鍵值為0X08的時(shí)候代表50的投入;
P1口的按鍵值為0X09的時(shí)候代表100的投入;
P1口的按鍵值為0X0f的時(shí)候代表購(gòu)物確定“OK”按鈕;
P1口的按鍵值為0X0e的時(shí)候代表購(gòu)物取消“NO”按鈕;
本設(shè)計(jì)假定自動(dòng)售貨機(jī)的商品種類(lèi)為8種,價(jià)格為1、2、3、4、5、6、7、8元。每一個(gè)價(jià)格代表一種商品且一經(jīng)售出就由外部電機(jī)自動(dòng)完成補(bǔ)貨。規(guī)定每次最多只能購(gòu)買(mǎi)10個(gè)。貨物選擇:
P1口的按鍵值為OX00的時(shí)候代表選擇貨物價(jià)格“price+”;
P1口的按鍵值為OX01的時(shí)候代表選擇貨物價(jià)格“price-”;
P1口的按鍵值為OX02的時(shí)候代表選擇貨物數(shù)量“num+”;
P1口的按鍵值為OX03的時(shí)候代表選擇貨物價(jià)格“num-”;
  •    輸出:選擇商品由P0口控制的相應(yīng)LED指示燈:
選擇商品1用P0.0控制D1LED燈亮;
選擇商品2用P0.1控制D2LED燈亮;
選擇商品3用P0.2控制D3LED燈亮;
選擇商品4用P0.3控制D4LED燈亮;
選擇商品5用P0.4控制D5LED燈亮;
選擇商品6用P0.5控制D6LED燈亮;
選擇商品7用P0.6控制D7LED燈亮;
選擇商品8用P0.7控制D8LED燈亮;
  •    顯示:本設(shè)計(jì)的顯示端口由P2端口和P3.2(RS)、P3.3(RW)、P3.4(E)控制LCD1602液晶來(lái)顯示購(gòu)貨狀態(tài),用P0口控制LED燈表示貨物種類(lèi)。通過(guò)它可以顯示購(gòu)貨的種類(lèi)、數(shù)量、總價(jià)以及找零等。

3  自動(dòng)售貨機(jī)的硬件設(shè)計(jì)
3.1 80C51的簡(jiǎn)介
3.1.1 80C51的基本概述
由INTEL公司出品的MCS-51系列的80C51其實(shí)用性非常高。由于它是采用CHMOS的工藝技術(shù)制造,所以它是一款穩(wěn)定性很高的高性能8位單片機(jī),是HCMOS中的最基本的產(chǎn)品之一。在制作工藝的程中不僅繼承和擴(kuò)展了先前單片機(jī)的指令系統(tǒng)和體系結(jié)構(gòu)更是把HMOS的高速高密度的技術(shù)特點(diǎn)和CHMOS的低功耗特點(diǎn)相結(jié)合。為了滿(mǎn)足需求,在80C51內(nèi)部置入CPU、RAM(128字節(jié))、I/O(32個(gè)雙向輸入輸出)、定時(shí)器/計(jì)數(shù)器(16位)、串行通信口、兩級(jí)中斷結(jié)構(gòu)以及片內(nèi)時(shí)鐘震蕩電路。此外,它還可以通過(guò)選擇空閑和掉電的方式用于低功耗模式來(lái)進(jìn)行工作,空閑模式下保持串行口、中斷系統(tǒng)、RAM和定時(shí)器正常工作而同時(shí)凍結(jié)CPU來(lái)保證其正常運(yùn)行。掉電模式下,自動(dòng)保存RAM數(shù)據(jù),時(shí)鐘震蕩停止、芯片的其他功能停止工作。
圖3.1 80C51單片機(jī)內(nèi)部基本結(jié)構(gòu)
3.1.2 80C51的引腳功能介紹
圖3.2 80C51的引腳圖
80C51單片機(jī)的40個(gè)引腳大致可分為4類(lèi):電源、時(shí)鐘、控制和I/O引腳。
  • 電源:
  •    VCC - 芯片電源,接+5V;
  •    VSS - 接地端。
  • 時(shí)鐘:XTAL1、XTAL2晶體振蕩電路反相輸入端和輸出端。
  • 控制線(xiàn):控制線(xiàn)共有4根:
  •    ALE/PROG:地址鎖存允許/片內(nèi)EPROM編程脈沖
  •    ALE功能用來(lái)鎖存P0口送出的低8位地址;
  •    PROG功能:片內(nèi)有EPROM的芯片,在EPROM編程期間,此引腳輸入編程脈沖。
  •    PSEN:外ROM讀選通信號(hào)。
  •    RST/VPD(復(fù)位/備用電源):
  •    RST(Reset)功能是復(fù)位信號(hào)輸入端;
  •    VPD功能是在Vcc掉電情況下,接備用電源。
  •    EA/Vpp(內(nèi)外ROM選擇/片內(nèi)EPROM編程電源):
  •    EA功能:內(nèi)外ROM選擇端;
  •    Vpp功能:片內(nèi)有EPROM的芯片,在EPROM編程期間,施加編程電源Vpp。
  • I/O線(xiàn):80C51共有4個(gè)8位并行I/O端口即P0、P1、P2、P3口,共32個(gè)引腳;P3口還具有第二功能——用于特殊信號(hào)輸入輸出和控制信號(hào)(屬控制總線(xiàn))P0口輸入時(shí)需要接上拉電阻才能置1。
在每次使用單片機(jī)之前,我們都要使單片機(jī)復(fù)位,讓CPU以及其他功能部件都處于一個(gè)確定的初始狀態(tài),以消除上一次用戶(hù)的操作對(duì)本次用戶(hù)操作的影響。51的RST引腳是復(fù)位信號(hào)的輸入端。復(fù)位信號(hào)是高電平有效,持續(xù)時(shí)間要有24個(gè)時(shí)鐘周期以上。例如:若MCS-51單片機(jī)的時(shí)鐘頻率為12MHz,則復(fù)位脈沖寬度至少應(yīng)為2us。通常,80C51的復(fù)位有自動(dòng)上電復(fù)位和人工按紐復(fù)位兩種
自動(dòng)上電復(fù)位電路的工作原理是:電容在通電的時(shí)候相當(dāng)于短路情況,導(dǎo)致RST引腳上的電位為高電平,這樣電容會(huì)因?yàn)殡娮璞怀潆姡缓驲ST端逐漸降低電壓直到變?yōu)榈碗娖剑瑥亩箚纹瑱C(jī)開(kāi)始正常工作。由于自動(dòng)售貨機(jī)的功能需求,本次設(shè)計(jì)采用自動(dòng)上電復(fù)位電路。

3.2 LCD1602字符型液晶簡(jiǎn)介
3.2.1 LCD1602的概述
LCD1602液晶也叫1602字符型液晶,它是一種專(zhuān)門(mén)用來(lái)顯示字母、數(shù)字、符號(hào)等的點(diǎn)陣型液晶模塊。它由若干個(gè)5X7或者5X11等點(diǎn)陣字符位組成,每個(gè)點(diǎn)陣字符位都可以顯示一個(gè)字符,每位之間有一個(gè)點(diǎn)距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用,正因?yàn)槿绱怂运荒芎芎玫仫@示圖形(用自定義CGRAM,顯示效果也不好)。1602LCD是指顯示的內(nèi)容為16X2,即可以顯示兩行,每行16個(gè)字符液晶模塊(顯示字符和數(shù)字)。市面上字符液晶大多數(shù)是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780寫(xiě)的控制程序可以很方便地應(yīng)用于市面上大部分的字符型液晶。液晶顯示器以其微功耗、體積小、顯示內(nèi)容豐富、超薄輕巧的諸多優(yōu)點(diǎn),在各類(lèi)儀表和低功耗系統(tǒng)中得到廣泛的應(yīng)用。根據(jù)顯示內(nèi)容可以分為字符型液晶,圖形液晶。根據(jù)顯示容量又可以分為單行16字,2行16字,兩行20字等等。
3.2.2 LCD1602的硬件結(jié)構(gòu)
圖3.3 LCD1602的基本結(jié)構(gòu)圖
引腳說(shuō)明:LCD1602一般是16個(gè)引腳
第1腳:VSS為接地電源。
第2腳:VDD接5V正電源。
第3腳:VEE為液晶顯示器對(duì)比度調(diào)整端,通過(guò)連接電源正負(fù)來(lái)調(diào)節(jié)對(duì)比度的強(qiáng)弱。當(dāng)連接電源正端時(shí)對(duì)比度最弱,反之連接負(fù)極則最高。對(duì)比度太高時(shí)會(huì)產(chǎn)生所謂的“鬼影”,在連接時(shí)可以通過(guò)接一個(gè)電位器來(lái)調(diào)整對(duì)比度。
第4腳:RS為數(shù)據(jù)命令選擇端,電平為H時(shí)選擇數(shù)據(jù)寄存器、電平為L(zhǎng)時(shí)選擇指令寄存器。
第5腳:RW為讀寫(xiě)選擇端,電平為H時(shí)進(jìn)行讀操作,電平為L(zhǎng)時(shí)進(jìn)行寫(xiě)操作。
第6腳:E端為使能端,當(dāng)E端由高電平跳變成低電平時(shí),液晶模塊執(zhí)行命令。
第7~14腳:D0~D7為8位雙向數(shù)據(jù)線(xiàn)。
第15~16腳:空腳或背燈電源,15腳背光正極,16腳背光負(fù)極。
3.2.3 LCD1602的指令說(shuō)明
  • LCD1602的初始化設(shè)置:
  •    顯示模式設(shè)置如表3.1所示:
表3.1 顯示模式設(shè)置
  
  •    顯示開(kāi)/關(guān)及光標(biāo)位置如表3.2所示:
表3.2 顯示開(kāi)/關(guān)及光標(biāo)位置
  • 數(shù)據(jù)控制:控制器內(nèi)部設(shè)有一個(gè)數(shù)據(jù)地址指針,可以根據(jù)它來(lái)訪(fǎng)問(wèn)內(nèi)部的全部字節(jié)。
  •    數(shù)據(jù)指針設(shè)置如表3.3所示:
表3.3 數(shù)據(jù)指針設(shè)置
  •    讀數(shù)據(jù):輸入時(shí) RW 、RS、 E均等于H,輸出D0-D7=數(shù)據(jù)
  •    寫(xiě)數(shù)據(jù):輸入時(shí)RW=L、RS=H、D0-D7=數(shù)據(jù)、E=高脈沖,輸出無(wú);
  •    其他設(shè)置如表3.4所示:
表3.4 其他設(shè)置
  • LCD1602液晶模塊的讀寫(xiě)指令:
  •    指令1:清除顯示,指令碼為01H,清楚顯示數(shù)據(jù);
  •    指令2:光標(biāo)返回到地址00H即光標(biāo)復(fù)位;
  •    指令3:光標(biāo)和顯示位置設(shè)置,光標(biāo)按方向移動(dòng),高/低電平右/左移,S:屏幕上所有文字是否左移或右移,高電平移動(dòng),低電平不移動(dòng);
  •    指令4:顯示開(kāi)關(guān)控制D:控制整體的顯示開(kāi)與關(guān),高電平表示開(kāi)顯示,低電平表示關(guān)顯示。C:控制光標(biāo)的開(kāi)與關(guān),高電平表示有光標(biāo),低電平表示無(wú)光標(biāo) B:控制光標(biāo)是否閃爍,高電平閃爍,低電平不閃爍;
  •    指令5:光標(biāo)或顯示移位 S/C :高電平時(shí)顯示移動(dòng)的文字,低電平時(shí)移動(dòng)光標(biāo);
  •    指令6:功能設(shè)置命令 DL:高電平時(shí)為4位總線(xiàn),低電平時(shí)為8位總線(xiàn) N:低電平時(shí)為單行顯示,高電平時(shí)為雙行顯示,F(xiàn):低電平時(shí)顯示5X7的點(diǎn)陣字符,高電平時(shí)顯示5X10的顯示字符;
  •    指令7:字符發(fā)生器RAM地址設(shè)置;
  •    指令8:DDRAM地址設(shè)置;
  •    指令9:讀忙信號(hào)和光標(biāo)地址BF:忙標(biāo)志位,高電平表示忙,此時(shí)模塊不能接收命令或數(shù)據(jù),如果為低電平表示不忙;
3.2.4 LCD1602的基本時(shí)序操作
LCD1602的基本時(shí)序操作以及對(duì)應(yīng)的狀態(tài)和輸入輸出如表3.5所示:

表3.5 基本時(shí)序操作及對(duì)應(yīng)狀態(tài)的輸入輸出
LCD1602的讀寫(xiě)時(shí)序操作如圖3.4、3.5所示:
圖 3.4讀時(shí)序操作圖
圖 3.5寫(xiě)時(shí)序操作圖

3.3 4*4矩陣鍵盤(pán)簡(jiǎn)介
3.3.1 4*4矩陣鍵盤(pán)的概述
4*4矩陣鍵盤(pán)又是4*4行列鍵盤(pán),它是分別用4條I/O線(xiàn)作為行線(xiàn)和列線(xiàn)組成的鍵盤(pán)。每個(gè)鍵的位置設(shè)置在每條行線(xiàn)和列線(xiàn)在交叉處上,可以知道4*4矩陣鍵盤(pán)共有4*4=16個(gè)按鍵。這樣的設(shè)置可以有效地提高單片機(jī)I/O口的利用率,與獨(dú)立式按鍵相比大大降低了接口占用率。當(dāng)設(shè)計(jì)過(guò)程中需要按鍵個(gè)數(shù)要求比較大時(shí),為了釋放出I/O端口來(lái)供其他連接需要時(shí)往往采用這種矩陣式按鍵來(lái)解決問(wèn)題。在矩陣鍵盤(pán)中,行列線(xiàn)均通過(guò)一個(gè)按鍵加以連接取代了直接交叉相連。這樣,在很大的程度上增加了按鍵數(shù),而直接將端口線(xiàn)連接在鍵盤(pán)上則會(huì)減少一倍的按鍵數(shù)量。在需要很多按鍵的設(shè)計(jì)中采用矩陣鍵盤(pán)明顯地比獨(dú)立式按鍵更合理,而且行列線(xiàn)越多效果越明顯。
3.3.2 4×4矩陣鍵盤(pán)的硬件結(jié)構(gòu)

圖3.6 4*4矩陣鍵盤(pán)的基本結(jié)構(gòu)圖
在應(yīng)用矩陣鍵盤(pán)的設(shè)計(jì)中要編譯程序的時(shí)候必定會(huì)計(jì)算出每個(gè)按鍵的接口地址是多少以方便編譯,在矩陣鍵盤(pán)的按鍵確定上我們可以采用兩種方法:
  • 行掃描法:
行掃描法是我們常用的一種識(shí)別按鍵的方法,這種方法需要我們逐行逐列進(jìn)行掃描查詢(xún),分為兩個(gè)步驟:
  •    將連接的全部行線(xiàn)置為低電平,然后檢測(cè)所有列線(xiàn)的電位狀態(tài)。只要某一列列線(xiàn)電位為低電平,就表示矩陣鍵盤(pán)中這列有鍵被按下,并且在被按下的閉合的按鍵在低電平列線(xiàn)與全部根行線(xiàn)相交叉的4個(gè)按鍵之中。反之,若所有列線(xiàn)電位均為高電平,則表示矩陣鍵盤(pán)中沒(méi)有按鍵被按下;
  •    通過(guò)前一可知按鍵處在判斷的4個(gè)按鍵之中,在確認(rèn)了有按鍵被按下后,就可進(jìn)入到確定具體被閉合鍵的操作。然后再依次將所有行線(xiàn)電位置為低電平,即只有一根行線(xiàn)為低電平,其余行線(xiàn)則為高電平。在確定了某根行線(xiàn)電位為低電平后,再逐行檢測(cè)所有列線(xiàn)的電平狀態(tài)。若某根列線(xiàn)的電位為低電平,則被按下的按鍵就處在這根列線(xiàn)和低電平行線(xiàn)的交叉處;
  • 高低電平翻轉(zhuǎn)法:
這種確定矩陣鍵盤(pán)按鍵的方法也是非常有效的方法,也分為兩個(gè)步驟:
  •    先讓所連接的端口高四位為高(1),低四位為低(0),若矩陣鍵盤(pán)上有按鍵被按下,則高四位中會(huì)有一個(gè)電平從1被翻轉(zhuǎn)到0,低四位則不會(huì)改變電平狀態(tài),然后即可確定矩陣鍵盤(pán)上被按下的按鍵的所在行的具體位置;
  •     讓讓所連接的端口高四位為低(0),低四位為高(1)。若矩陣鍵盤(pán)上有按鍵被按下,則低四位中會(huì)會(huì)有一個(gè)電平1翻被轉(zhuǎn)為0,高四位則不會(huì)改變電平狀態(tài),然后即可確定矩陣鍵盤(pán)上被按下的按鍵的所在列的具體位置。綜合這兩個(gè)步驟就可以判斷出被按下的按鍵具體位置;

3.4 識(shí)別系統(tǒng)
3.4.1對(duì)硬幣的識(shí)別
目前在國(guó)內(nèi),對(duì)于硬幣的識(shí)別可采用多種方法,比如激光掃描、應(yīng)變片測(cè)重量、光電管檢測(cè)大小等,然而在自動(dòng)售貨機(jī)中采用結(jié)構(gòu)簡(jiǎn)單、成本低、測(cè)量準(zhǔn)確及其非接觸測(cè)量等優(yōu)點(diǎn)集一身的渦流傳感器檢測(cè)。
電渦流檢測(cè)原理:以高頻的電信號(hào)通過(guò)一個(gè)線(xiàn)圈,在這個(gè)過(guò)程中產(chǎn)生變化的磁場(chǎng)通過(guò)硬幣的表面即變化磁通通過(guò)硬幣的表面,相應(yīng)地硬幣表面上產(chǎn)生電渦流, 并產(chǎn)生反向的變化磁場(chǎng),以削弱原來(lái)線(xiàn)圈產(chǎn)生出來(lái)的磁場(chǎng)。然后根據(jù)激勵(lì)磁場(chǎng)線(xiàn)圈幅值的變化,通過(guò)變化的給定值即可測(cè)出真假硬幣。

圖3.7 電渦流檢測(cè)電路原理圖
圖3.7中Q2所需要的頻率由Q1、L、C4等元件組成的振蕩電路所提供,從而在C點(diǎn)產(chǎn)生一正弦波振蕩信號(hào);然后再A、B 兩點(diǎn)外接一個(gè)傳感線(xiàn)圈,當(dāng)有硬幣投入通過(guò)線(xiàn)圈時(shí)會(huì)改變C點(diǎn)原有信號(hào)的幅值大小,而真假硬幣通過(guò)線(xiàn)圈時(shí)改變的幅值大小是不一樣的,通過(guò)對(duì)比設(shè)定給定真幣的參照值來(lái)判斷真假硬幣。
但是在實(shí)際應(yīng)用中,由于某些條件的原因會(huì)影響到電子線(xiàn)路元器件的判定值,比如溫漂的影響,由于材質(zhì)的差異比較小,從而導(dǎo)致信號(hào)值得差距變小,若受到的溫漂影響稍微增強(qiáng)一點(diǎn),那么則很難精確地確檢測(cè)出不行的,為此可以采用電橋的方法來(lái)進(jìn)行改善彌補(bǔ),從而減小由溫漂造成的干擾。圖中L3、L4都是激勵(lì)線(xiàn)圈,L3上方放置一個(gè)標(biāo)準(zhǔn)的1元硬幣或其它用低碳鋼做成的圓片,L4為檢測(cè)有無(wú)硬幣通過(guò)和是否為真假的激勵(lì)線(xiàn)圈,A、B兩信號(hào)通過(guò)通信模塊同時(shí)送到后續(xù)的運(yùn)算放大器之中進(jìn)行相減,從而抵消因溫漂所造成的影響。


3.5 貨物選擇系統(tǒng)
貨物選擇系統(tǒng)主要通過(guò)矩陣鍵盤(pán)按鍵操作來(lái)完成。4*4矩陣鍵盤(pán)是自動(dòng)售貨機(jī)中的輸入裝置,價(jià)格低廉,結(jié)構(gòu)簡(jiǎn)單,使用方便,在單片機(jī)應(yīng)用系統(tǒng)中得到廣泛地應(yīng)用。鍵盤(pán)按照接口原理可分為編碼鍵盤(pán)與非編碼鍵盤(pán)兩類(lèi),它們的主要區(qū)別是識(shí)別鍵符及給出相應(yīng)鍵碼的方法。編碼鍵盤(pán)主要是用硬件來(lái)實(shí)現(xiàn)對(duì)鍵的識(shí)別,非編碼鍵盤(pán)主要是由軟件來(lái)實(shí)現(xiàn)鍵盤(pán)的定義與識(shí)別。
CPU可以采用查詢(xún)或中斷方式了解有無(wú)將鍵輸入,并檢查是哪一個(gè)鍵按下,然后通過(guò)跳轉(zhuǎn)指令轉(zhuǎn)入執(zhí)行該鍵的功能程序,執(zhí)行完后再返回主程序。
一個(gè)完整的矩陣鍵盤(pán)控制程序應(yīng)該具備以下功能:
  • 能夠準(zhǔn)確檢測(cè)鍵盤(pán)上有無(wú)按鍵按下,為了消除鍵盤(pán)的按鍵機(jī)械觸點(diǎn)抖動(dòng)可以采取硬件或軟件措施;
  • 有良好的邏輯處理方法,按鍵處理可以獨(dú)立開(kāi)展,在處理期間對(duì)任何一個(gè)按鍵的操作不對(duì)系統(tǒng)產(chǎn)生影響,只要按鍵按下系統(tǒng)都只執(zhí)行一次按鍵功能程序;
  • 輸出的按鍵值或者鍵號(hào)可以達(dá)到很精確的狀態(tài)來(lái)正確執(zhí)行跳轉(zhuǎn)指令;
圖3.9 貨物選擇系統(tǒng)圖

3.6 出貨及找零系統(tǒng)
在本系統(tǒng)中,總共設(shè)計(jì)了8種飲料,價(jià)格分別為1、2、3、4、5、6、7、8元不等,由顧客通過(guò)按鍵選擇確定后,投入售貨機(jī)可識(shí)別的幣(幣可以累加計(jì)數(shù))。當(dāng)投入的幣總值不夠購(gòu)買(mǎi)選擇的商品總值時(shí),售貨機(jī)顯示金取消交易并退出所投幣,如果所投幣大于等于購(gòu)買(mǎi)選擇的商品總值時(shí),由售貨機(jī)出貨并計(jì)算剩余幣。但是在單片機(jī)的輸出中只有高電平和低電平之分。在自動(dòng)售貨機(jī)中只需要安裝一個(gè)驅(qū)動(dòng)電機(jī),待顧客投入幣后將信號(hào)送入系統(tǒng)通過(guò)相應(yīng)電路來(lái)驅(qū)動(dòng)電機(jī)推出相應(yīng)商品即可。本設(shè)計(jì)只模擬實(shí)現(xiàn)此功能,負(fù)責(zé)軟件仿真,暫不考慮硬件電機(jī)方面,只作介紹。在這里,我們選用光敏三極管來(lái)實(shí)現(xiàn)這一功能。當(dāng)單片機(jī)輸出端為高電平時(shí),則驅(qū)動(dòng)二極管發(fā)光,使驅(qū)動(dòng)電機(jī)電路導(dǎo)通,這時(shí)驅(qū)動(dòng)電機(jī)開(kāi)始工作等待信號(hào)。當(dāng)單片機(jī)輸出端為低電平時(shí),則二極管熄滅。驅(qū)動(dòng)電機(jī)電路斷開(kāi),即完成推貨動(dòng)作,LED燈閃爍。售貨機(jī)通過(guò)投幣時(shí)累計(jì)的計(jì)數(shù)和購(gòu)買(mǎi)商品的總金額進(jìn)行相減的運(yùn)算,在LCD液晶上顯示出余幣的數(shù)量,顧客取走貨物后自動(dòng)退還余幣。
圖3.10 出貨及找零

4  系統(tǒng)的軟件流程圖設(shè)計(jì)
4.1 自動(dòng)售貨機(jī)貨物選擇流程圖
本設(shè)計(jì)提供1-8元不等的貨物,分別用1-8的序號(hào)對(duì)應(yīng)貨物。當(dāng)啟動(dòng)系統(tǒng)后進(jìn)入初始化界面,等待顧客選擇貨物種類(lèi)和數(shù)量,按鍵“OK”則跳入投幣系統(tǒng),按鍵“NO”則返回初始化等待界面。在這里只以1號(hào)商品作為例子來(lái)講解具體流程如圖4.1:
圖4.1 自動(dòng)售貨機(jī)貨物選擇流程圖

4.2 自動(dòng)售貨機(jī)投幣系統(tǒng)流程圖
在4*4矩陣鍵盤(pán)上模擬投入幣,若投入一種面值的幣就累加一種面值的幣,如果沒(méi)有投入幣或者投入幣值不足購(gòu)買(mǎi)商品的話(huà)則提示繼續(xù)投幣。當(dāng)所投幣足夠時(shí),進(jìn)入出貨找零系統(tǒng)如圖4.2所示:
圖4.2 自動(dòng)售貨機(jī)投幣系統(tǒng)流程圖

4.3 自動(dòng)售貨機(jī)出貨找零系統(tǒng)流程圖
進(jìn)入出貨找零系統(tǒng)時(shí),如果購(gòu)買(mǎi)商品后沒(méi)有剩余幣則直接推出商品,若還有剩余幣則找出余幣,如圖4.3所示:
4.3 自動(dòng)售貨機(jī)出貨找零系統(tǒng)流程圖

5.2 仿真結(jié)果
設(shè)計(jì)好程序之后,還需要通過(guò)protues7.5和keil3.0來(lái)實(shí)現(xiàn)程序的調(diào)試和仿真,仿真結(jié)果圖如下:
  • 當(dāng)啟動(dòng)自動(dòng)售貨機(jī)時(shí)機(jī)器進(jìn)入初始化等待狀態(tài),等待按鍵輸入,如圖5.1所示:
圖5.1 初始化等待界面
  • 通過(guò)按鍵price+和price-來(lái)選擇貨物的種類(lèi),然后通過(guò)num+和num-來(lái)選擇所購(gòu)買(mǎi)貨物的數(shù)量,同時(shí)代表被選擇貨物的LED指示燈亮,如圖5.2所示:
圖5.2 選擇貨物的種類(lèi)及數(shù)量
  • 當(dāng)選擇好貨物后,按下“OK”鍵進(jìn)入到投幣系統(tǒng),此時(shí)機(jī)器會(huì)自動(dòng)計(jì)算出所購(gòu)貨物總金額,如圖5.3所示:
圖5.3 貨物選擇并計(jì)價(jià)
  • 當(dāng)機(jī)器計(jì)算出總價(jià)等待顧客投入幣并按下“OK”鍵后,當(dāng)投入幣幣值大于或等于總價(jià)時(shí)就出貨并找零,若投入幣幣值小于總價(jià)則不能出貨只能按下“NO”退出所投幣或繼續(xù)投幣,如圖5.4所示:
圖5.4 出貨找零
  • 當(dāng)完成以上步驟后則完成一次自動(dòng)購(gòu)物過(guò)程,機(jī)器自動(dòng)復(fù)位回到初始化界面如圖5.5所示:
圖5.5 自動(dòng)復(fù)位返回初始化界面

附錄B:系統(tǒng)總圖

單片機(jī)源程序如下:
  1. #include<reg51.h>

  2. /*******************define*************************/
  3. #define WAIT_SALE        0                 //定義1602顯示狀態(tài)
  4. #define NO_WATER         1                 
  5. #define INPUT_MONEY        2
  6. #define SALING                3
  7. #define CHANGE                4
  8. #define CANCLE                5
  9. #define NO_DATA                0
  10. #define water_change(x, y) ((x) & (~(0x01 << y))) //宏 控制水種類(lèi)的切換
  11. #define uint unsigned int
  12. #define uchar unsigned char

  13. unsigned char water_total[] = {10, 10, 10, 10, 10, 10, 10, 10};   
  14. unsigned char water_price[] = {1, 2, 3, 4, 5, 6, 7, 8};
  15. uchar code wait_sale[]="for sale";                  //定義所顯示的內(nèi)容
  16. uchar code no_water[] = "no water!";
  17. uchar code price[] = "price:";
  18. uchar code number[] = "num:";
  19. uchar code sum[] = "SUM:";
  20. uchar code input[] = "INPUT:";
  21. uchar code change[] = "change:";
  22. uchar code put_water[] = "put water...";
  23. uchar code cancle[] = "cancle...";

  24. unsigned char e=0x00;                    
  25. sbit P2_0=P2^0;                       //定義接端口
  26. sbit P2_1=P2^1;
  27. sbit P2_2=P2^2;
  28. sbit P2_3=P2^3;
  29. sbit lcd_en=P3^4;            
  30. sbit rs=P3^2;
  31. sbit rw = P3^3;
  32. /****************************************************/

  33. /***********************function**********************************/
  34. /************lcd 1602*************************/
  35. void lcd_1602_delay(uint z)          //延時(shí)
  36. {
  37. uint x,y;
  38. for(x=z;x>0;x--)
  39. for(y=110;y>0;y--);
  40. }

  41. void lcd_1602_write_com(uchar com)   //寫(xiě)命令
  42. {
  43. rs=0;
  44. rw=0;
  45. P2=com;
  46. lcd_1602_delay(5);
  47. lcd_en=1;
  48. lcd_1602_delay(5);
  49. lcd_en=0;
  50. }

  51. void lcd_1602_write_data(uchar date) //寫(xiě)數(shù)據(jù)
  52. {
  53. rs=1;
  54. rw=0;
  55. P2=date;
  56. lcd_1602_delay(5);
  57. lcd_en=1;
  58. lcd_1602_delay(5);
  59. lcd_en=0;
  60. }

  61. void lcd_1602_init()               //LCD1602初始化函數(shù)
  62. {
  63. lcd_en=0;
  64. lcd_1602_write_com(0x38);
  65. lcd_1602_write_com(0x0e);
  66. lcd_1602_write_com(0x06);
  67. lcd_1602_write_com(0x01);
  68. }

  69. void lcd_1602_wait_sure()         //顯示'OK'&'NO'界面
  70. {
  71. lcd_1602_write_com(0x80+0x40);
  72. lcd_1602_write_data('O');
  73. lcd_1602_write_data('K');
  74.                
  75. lcd_1602_write_com(0x80+0x4e);
  76. lcd_1602_write_data('N');
  77. lcd_1602_write_data('O');
  78. }

  79. void lcd_1602_show_num(uint num)       // 1602顯示數(shù)字的函數(shù)
  80. {
  81. if(num <= 9)
  82. {
  83.    lcd_1602_write_data('0'+num);
  84.    lcd_1602_write_data(' ');
  85.   }else if(num >= 10 )
  86. {
  87.    lcd_1602_write_data('0'+num/10);
  88.    lcd_1602_write_data('0'+num%10);
  89.   }
  90. }

  91. void lcd1602_info_display(uint choose, uint num_type, uint num_count)  //1602顯示函數(shù)
  92. {
  93. int num;
  94. lcd_1602_write_com(0x01);
  95. switch(choose)
  96.   {
  97. case WAIT_SALE:
  98. lcd_1602_write_com(0x80+0x03);       //
  99. for(num = 0; num < 8; num++)
  100. {
  101. lcd_1602_write_data(wait_sale[num]);        
  102. }
  103. break;
  104. case NO_WATER:
  105. lcd_1602_write_com(0x80+0x03);
  106. for(num = 0; num < 9; num++)
  107.   {
  108.    lcd_1602_write_data(no_water[num]);        
  109.    }
  110. break;
  111. case SALING:
  112. //price
  113. lcd_1602_write_com(0x80+0x00);
  114. for(num = 0; num < 6; num++)
  115.   {
  116.     lcd_1602_write_data(price[num]);
  117.    }
  118. lcd_1602_write_data('0'+(num_type+1));
  119. lcd_1602_write_data(' ');
  120. //number
  121. lcd_1602_write_data(' ');
  122. for(num = 0; num < 4; num++)
  123.           {
  124.            lcd_1602_write_data(number[num]);
  125.            }
  126. lcd_1602_show_num(num_count);
  127.                
  128.                
  129. break;
  130. case INPUT_MONEY:
  131. //need money        
  132. lcd_1602_write_com(0x80+0x00);
  133. for(num = 0; num < 4; num++)
  134.     {
  135.       lcd_1602_write_data(sum[num]);
  136.     }
  137. lcd_1602_show_num(num_type);
  138. //input
  139. lcd_1602_write_data(' ');
  140. lcd_1602_write_data(' ');
  141. for(num = 0; num < 6; num++)
  142.         {
  143.        lcd_1602_write_data(input[num]);
  144.         }
  145. lcd_1602_show_num(num_count);
  146. break;
  147. case CHANGE:
  148. if(!num_count)
  149.                 {
  150.                 //put water
  151.        lcd_1602_write_com(0x80+0x02);
  152.                 for(num = 0; num < 13; num++)
  153.             {
  154. lcd_1602_write_data(put_water[num]);
  155.             }
  156.        }
  157. else
  158. {
  159. //cancle water
  160. lcd_1602_write_com(0x80+0x02);              //取消選擇時(shí)寫(xiě)命令退幣
  161. for(num = 0; num < 9; num++)
  162.         {
  163.              lcd_1602_write_data(cancle[num]);
  164.         }
  165. }
  166. //change
  167. lcd_1602_write_com(0x80+0x43);
  168. for(num = 0; num < 7; num++)
  169.         {
  170.             lcd_1602_write_data(change[num]);
  171.         }
  172. lcd_1602_show_num(num_type);
  173. break;
  174. default:
  175. break;
  176. }
  177. lcd_1602_write_com(0x0c);
  178. }
  179. void lcd_1602_saling(uint type, uint num)
  180. {
  181.         lcd1602_info_display(SALING, type, num);
  182.         lcd_1602_wait_sure();
  183. }

  184. void lcd_1602_inputing(uint need, uint input)
  185. {
  186.   lcd1602_info_display(INPUT_MONEY, need, input);
  187.   lcd_1602_wait_sure();
  188. }
  189. /*************************************************/
  190. void delay1(unsigned int t)           // 延時(shí)函數(shù)
  191. {
  192. unsigned int i,j;
  193. for(i=0;i<t;i++)
  194. for(j=0;j<10;j++);
  195. }

  196. void out_water()             //推出水函數(shù)
  197. {
  198. int i, j = 100;
  199. while(j--)
  200.   {
  201.         for(i = 0; i < 8; i++)
  202.         {
  203.           P0 = water_change(0xff, i);
  204.      delay1(50);
  205.     }
  206.   }
  207. P0 = 0xff;
  208. }

  209. unsigned char key(void)       //按鍵響應(yīng)函數(shù)
  210. {
  211. unsigned char key,key1,key2;
  212. P1=0XF0;
  213. if((P1&0XF0)!=0XF0)           //ked down
  214.     {
  215.        delay1(10);                         //延時(shí)去抖動(dòng)
  216.        if((P1&0XF0)!=0XF0)                  //仍然有鍵按下
  217.       {
  218.         key1=P1&0XF0;                          //讀入列線(xiàn)值
  219.         P1=0X0F;
  220.         key2=P1&0X0F;
  221.         key=key1|key2;
  222. switch(key)                  //按鍵映射
  223. {
  224. case 0xee: e=0x00;break;
  225. case 0xde: e=0x01;break;
  226. case 0xbe: e=0x02;break;
  227. case 0x7e: e=0x03; break;
  228. case 0xed: e=0x04;break;
  229. case 0xdd: e=0x05;break;
  230. case 0xbd: e=0x06;break;
  231. case 0x7d: e=0x07; break;
  232. case 0xeb: e=0x08;break;
  233. case 0xdb: e=0x09;break;
  234. case 0xbb: e=0x0a;break;
  235. case 0x7b: e=0x0b; break;
  236. case 0xe7: e=0x0c;break;
  237. case 0xd7: e=0x0d;break;
  238. case 0xb7: e=0x0e;break;
  239. case 0x77: e=0x0f; break;
  240. }
  241. while((P1&0X0F)!=0X0F);
  242. delay1(10);
  243. return 1;
  244. }
  245.   }
  246. return 0;
  247. }

  248. /*********************************************************************/
  249. /*****************main********************************/
  250. void main()
  251. {
  252. unsigned char ok = 0, water_type = -1,  water_is_choose = 0;
  253. char water_count = 0;
  254. unsigned int flag = 0, money = 0, need_money;

  255. lcd_1602_init();
  256. again:
  257. ok = 0; water_type = -1; water_count = 0; water_is_choose = 0;
  258. flag = 0; money = 0; need_money = 0;        
  259. lcd1602_info_display(WAIT_SALE, 0, 0);
  260. while(!ok)        //choose the water and count
  261. {
  262.   flag=key();
  263.   if(flag)
  264.   {
  265.     switch(e)         //不同的按鍵進(jìn)行不同的操作
  266.      {
  267.         case(0x00):
  268.         water_type++;
  269.         water_is_choose = 1;
  270.         if(water_type == 8)
  271.                {
  272.              water_type = 0;
  273.                 }
  274. P0 = water_change(0xff, water_type);
  275. break;               
  276. case(0x01):
  277. water_type--;
  278. water_is_choose = 1;
  279. if(water_type == -1 || water_type == -2)
  280. {
  281.   water_type = 7;
  282. }
  283. P0 = water_change(0xff, water_type);
  284. break;
  285. case(0x02):
  286. if(water_is_choose == 1)
  287.   {
  288.      water_count++;
  289.      if(water_count > water_total[water_type])
  290.      {
  291.        water_count = water_total[water_type];
  292.             }
  293.    }
  294. break;
  295. case(0x03):
  296. if(water_is_choose == 1)
  297. {
  298.   water_count--;
  299.   if(water_count < 0)
  300.         {
  301.       water_count = 0;
  302.          }
  303. }                                
  304. break;
  305. case(0x0e):        //  返回
  306. goto again;
  307. break;   
  308. case(0x0f):         //   確認(rèn)
  309. if(water_is_choose == 1)
  310.          {        
  311.       ok=1;
  312.           }                                
  313.         break;
  314.    default:
  315.    break;                                
  316. }
  317. lcd_1602_saling(water_type, water_count);                        
  318.         }
  319. }
  320.         
  321. //choose ok: calculate the money        //計(jì)算總數(shù)
  322. need_money = water_count * water_price[water_type];
  323. lcd_1602_inputing(need_money, money);
  324. ok = 0;        
  325. while(!ok)                //get money
  326.         {
  327.                 flag=key();
  328.                 if(flag)
  329.                 {
  330.                         switch(e)
  331. ……………………

  332. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

Keil5代碼與Proteus8.8仿真下載:
仿真程序文檔.7z (756.5 KB, 下載次數(shù): 114)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:262 發(fā)表于 2022-4-26 05:16 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

板凳
ID:983355 發(fā)表于 2022-5-14 18:14 | 只看該作者
您好啊,“自動(dòng)售貨機(jī)的控制子系統(tǒng)由以下幾個(gè)部分組成,分別是預(yù)設(shè)自動(dòng)售貨系統(tǒng)、金額累加和找零系統(tǒng)、售完檢測(cè)系統(tǒng)、售出累計(jì)及反饋功能系統(tǒng)。”
我剛試了一遍,請(qǐng)問(wèn)這里的售出累計(jì)及反饋功能系統(tǒng)  能顯示出來(lái)嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:1060270 發(fā)表于 2023-1-4 11:30 | 只看該作者
51黑真的很好哦
回復(fù)

使用道具 舉報(bào)

5#
ID:92810 發(fā)表于 2023-1-9 16:29 | 只看該作者
謝謝樓主分享,下載學(xué)習(xí)啦
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表