找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機直流電壓源Proteus仿真電路程序設計

[復制鏈接]
跳轉到指定樓層
樓主
ID:667152 發(fā)表于 2020-7-2 12:28 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
整體電路

電源模塊
文件有仿真圖,程序和文檔

本設計以直流電壓源為核心,STC89C52單片機為主控制器,單片機系統(tǒng)是數控電源的核心。它通過軟件的運行來控制整個儀器的工作,從而完成設定的功能。通過數字鍵盤來設置直流電源的輸出電壓,輸出電壓范圍為0V—9.9V,最大電流為1A,并可由液晶屏 LCD1602顯示實際輸出電壓值。本設計由單片機程 控輸出數字信號,經過 D/A轉換器(DAC0832 )輸出模擬量,同時輸出采用 ADC0832 對采樣的電壓、電流轉換為數字信號,再經過運算放大器隔離放大,最后通過單片機實現閉環(huán)控制輸出各種設備所需要的電壓。實際測試結果表明,本系統(tǒng)實際應用于需要高穩(wěn)定度小功率恒壓源的領域。

  數控直流電壓源是與普通直流電壓源相比,具有輸出電壓不連續(xù)變化的特點并且能由數碼管顯示,可以由“+”、“-”兩鍵分別控制輸出電壓步進增減輸出電壓。本例設計的電壓源輸出電壓的范圍:0~+9.9V,步進0.1V,紋波不大于10mV,除具有以上顯示控制功能外還能實現輸出電壓可預置在0~9.9V之間的任意一個值;用自動掃描代替人工按鍵,實現輸出電壓變化(步進0.1V不變),以及通過接入單穩(wěn)態(tài)電路,可以克服按鍵抖動引起的誤動作,運用計數器的反饋清零接法,起到防止誤操作的作用。
(1)輸出電壓:范圍0~+9.9V,步進0.1V,紋波不大于10mV;(2)輸出電流:500mA;(3)輸出電壓值由數碼管顯示;(4)由“+”、“-”兩鍵分別控制輸出電壓步進增減;(5)為實現上述幾部件工作,自制一穩(wěn)壓直流電源,輸出±15V,+5V。


2.1 工作方案選擇和論證

根據對現狀的分析,以及選題的指導,本課題的主要任務是220V的市電輸入到電路中,經過變壓、橋堆整流、濾波電路;經穩(wěn)壓調整模塊數據采集后輸出系統(tǒng)所需電壓,同時單片機通過軟件的運行來控制整個儀器的工作,從而完成設定的功能。通過數字鍵盤來設置直流電源的輸出電壓,通過A/D轉換、并可由數碼管顯示實際輸出電壓值。

2.1.1 主控芯片分析選擇

芯片的控制模塊主要靠單片機來實現,單片機有有多種型號,比較常見的有兩種,分別是:52系列單片機和凌陽系列單片機。52系列單片機的優(yōu)勢是價格便宜,有較強的算術計算能力,而且邏輯控制算法的實現比較靈活,同時功耗較低、技術比較成熟,有很好的抗干擾性能。凌陽系列單片機可以看作是專業(yè)版的52系列單片機,其可以實現更加復雜的邏輯控制,進行了更高層次的聚合,體積進一步減小,運算速度進一步提高,常用于大規(guī)模系統(tǒng)的控制,但價格比較昂貴。因為52單片機價格低于凌陽系列,且本次設計需要的處理速度較低,出于經濟和方便的角度考慮,方案1為最佳方案。

2.1.2控制方案比較

方案一:采用各類數字電路來組成鍵盤控制系統(tǒng),進行信號處理,如選用CPLD等可編程邏輯器件。本方案電路復雜,靈活性不高,效率低,不利于系統(tǒng)的擴展,對信號處理比較困難。


方案二:采用STC89C52單片機作為這個系統(tǒng)的控制單元,可以通過DAC0832的數據采樣和放大器的電壓調整可以改變系統(tǒng)輸出電壓的大小。 為了能夠使系統(tǒng)具備檢測實際輸出電壓值的大小,可以將輸出電壓經過DAC0832進行模數轉換,間接用單片機實時對電壓進行采樣,然后進行數據處理及送數碼管顯示。顯示的電壓值便是輸出的電壓大小。此系統(tǒng)比較靈活,采用軟件方法來解決數據的預置以及電壓的大小控制,使系統(tǒng)硬件更加簡潔,各類功能易于實現,能很好地滿足題目的要求。比較以上兩種方案的優(yōu)缺點,方案一中CPLD可編程邏輯器件控制電路內部接口信號繁瑣,中間相互關聯多,抗干擾能力差;在方案二中采用單片機完成整個數控部分的功能,也便于系統(tǒng)功能的擴展。

2.1.3 穩(wěn)壓輸出方案比較

方案一 采用線性調壓電源。以改變其基準電壓的方式使輸出不僅增加/減少, 這樣不能不考慮整流濾波后的紋波對輸出的影響。

方案二 使用運算放大器對電壓的比較放大由于運算放大器具有很大的電源電壓抑制比,可以大大減小輸出端的紋波電壓。在方案一中輸出的電壓很難跟蹤電壓的快速變化,而方案二中的輸出電壓波形與DAC0832的輸出波形相同,不僅可以輸出直流電平,而且只要預先生成產生波形的量化數據,便可以輸出多種波形,使系統(tǒng)產生的信號源有一定的驅動能力。

2.1.4 顯示模塊的選擇

顯示模塊也有多種備選方案,最常用的有LED數碼管和LCD液晶顯示屏。兩種顯示方式各有優(yōu)缺點,LED價格簡單、使用方便而且亮度較高,但能耗大;LCD功耗小、接口簡單、顯示清晰,但價格昂貴,使用復雜。結合對比權衡以及課題的具體需求,本文決定選用LED作為解決方案。


2.2 方案確立

220V 的市電輸入到電路中,經過變壓、橋堆整流、濾波電路;經穩(wěn)壓調整模塊數據采集后輸出系統(tǒng)所需電壓,同時單片機通過軟件的運行來控 制整個儀器的工作,從而完成設定的功能。通過數字鍵盤來設置直流電源的輸出電壓,并可由 LED顯示實際輸出電壓值。 由單片機程 控輸出數字信號,經過 D/A 轉換器( DAC0832)輸出模擬量,再經過運算放大器隔離放大,最后輸出各種設備所需要的電壓。

2.3總體框圖

2.4 總電路圖
本章小結

本章主要介紹這次畢業(yè)設計的方案選擇,包括系統(tǒng)控制核心的選擇及確定以及顯示模塊的選擇及確定。在下一章節(jié)當中,將對該課題中各單元電路的具體設計方案、元器件的選擇作進一步。


第3章 控制電路設計3.1  STC89C52單片機簡介

控制部分是系統(tǒng)整機協調工作和智能化管理的核心部分,主要部分包括鍵盤和 STC89C52RC單片機,而 STC89C52RC單片機實現控制功能是關鍵,采用單片機不但方便監(jiān)控,并且大大減少硬件設計。

3.1.1  STC89C52簡介

STC89C52為八位單片機,程序存儲器為8K,外部可擴展至64K,內部RAM為512B,可擴展至64K,正常工作電壓5V,支持最高時鐘頻率為80MHz,內置看門狗電路,支持ISP/IAP。

3.1.2  STC89C52引腳說明

VCC(40引腳):電源電壓;VSS(20引腳):接地P0端口(P0.0~P0.7,39~32引腳):P0口是一個漏極開路的8位雙向I/O口。作為輸出端口,每個引腳能驅動8個TTL負載,對端口P0寫入“1”時,可以作為高阻抗輸入。在訪問外部程序和數據存儲器時,P0口也可以提供低8位地址和8位數據的復用總線。此時,P0口內部上拉電阻有效。在Flash ROM編程時,P0端口接收指令字節(jié);而在校驗程序時,則輸出指令字節(jié)。驗證時,要求外接上拉電阻。P1端口(P1.0~P1.7,1~8引腳):P1口是一個帶內部上拉電阻的8位雙向I/O口。P1的輸出緩沖器可驅動(吸收或者輸出電流方式)4個TTL輸入。對端口寫入1時,通過內部的上拉電阻把端口拉到高電位,這是可用作輸入口。P1口作輸入口使用時,因為有內部上拉電阻,那些被外部拉低的引腳會輸出一個電流。

此外,P1.0和P1.1還可以作為定時器/計數器2的外部技術輸入(P1.0/T2)和定時器/計數器2的觸發(fā)輸入(P1.1/T2EX)。在對Flash ROM編程和程序校驗時,P1接收低8位地址。P2端口(P2.0~P2.7,21~28引腳):P2口是一個帶內部上拉電阻的8位雙向I/O端口。P2的輸出緩沖器可以驅動(吸收或輸出電流方式)4個TTL輸入。對端口寫入1時,通過內部的上拉電阻把端口拉到高電平,這時可用作輸入口。P2作為輸入口使用時,因為有內部的上拉電阻,那些被外部信號拉低的引腳會輸出一個電流。在訪問外部程序存儲器和16位地址的外部數據存儲器(如執(zhí)行“MOVX@DPTR”指令)時,P2送出高8位地址。在訪問8位地址的外部數據存儲器(如執(zhí)行“MOVX@R1”指令)時,P2口引腳上的內容(就是專用寄存器(SFR)區(qū)中的P2寄存器的內容),在整個訪問期間不會改變。在對Flash ROM編程和程序校驗期間,P2也接收高位地址和一些控制信號。P3端口(P3.0~P3.7,10~17引腳):P3是一個帶內部上拉電阻的8位雙向I/O端口。P3的輸出緩沖器可驅動(吸收或輸出電流方式)4個TTL輸入。對端口寫入1時,通過內部的上拉電阻把端口拉到高電位,這時可用作輸入口。P3做輸入口使用時,因為有內部的上拉電阻,那些被外部信號拉低的引腳會輸入一個電流。RST(9引腳):復位輸入。當輸入連續(xù)兩個機器周期以上高電平時為有效,用來完成單片機單片機的復位初始化操作。看門狗計時完成后,RST引腳輸出96個晶振周期的高電平。特殊寄存器AUXR(地址8EH)上的DISRTO位可以使此功能無效。DISRTO默認狀態(tài)下,復位高電平有效。ALE(30引腳):地址鎖存控制信號(ALE)是訪問外部程序存儲器時,鎖存低8位地址的輸出脈沖。在Flash編程時,此引腳也用作編程輸入脈沖。XTAL1(19引腳):振蕩器反相放大器和內部時鐘發(fā)生電路的輸入端。XTAL2(18引腳):振蕩器反相放大器的輸入端。

圖 3-1 STC89C52引腳圖

3.2 單片機的最小系統(tǒng)3.2.1 時鐘電路

STC89C52單片機的時鐘信號可以通過內部時鐘方式和外部時鐘方式兩種方式產生。其中內部時鐘方式如圖3-1所示。在圖中可以看出,內部時鐘依賴于振蕩電路,當XTAL1和XTAL2引腳外接上晶振時,振蕩電路就會變成自激振蕩器,這樣內部的時鐘

信號就會不斷的產生。圖中的兩個電容主要用來快速振蕩并維持頻率穩(wěn)定,電容值維持在5~30pF之間,典型狀況下為30pF。晶振的振蕩頻率需要控制在1.2~12MHz之間,一般取12MHz或6MHz。

圖3-2時鐘電路
3.2.2 復位電路

當RST引腳上的高電平在兩個機器周期中連續(xù)出現時,復位操作就會被觸發(fā)。若兩個周期以后電平的狀態(tài)還是高電平,那么復位操作就一直被執(zhí)行下去,直到電平狀態(tài)恢復到低電平為止。常見的復位電路實現方式有按鈕手動復位和上電自動復位兩種。最簡單的自動復位依賴于復位電容的充放電,只要Vcc的上升時間在1ms之內,就可以實現自動復位;手動復位需要借助人工按按鈕的操作,有兩種比較常見的方式:脈沖和電容,其中電平復位依靠電源Vcc與RST端的連通來實現,本文選用的就是手動復位方式。圖3-4給出了手動復位的電路圖,當時鐘頻率的要求是11.0592MHZ時,電容值取10uF,電阻值取10kΩ。

圖 3-3 按鈕復位電路

3.3 電源模塊

市電是交流電,其電壓雖然標識的是220V,但實際上220V只是一個平均值,它存在著波動,因此當需要比較穩(wěn)定的直流電壓時,就需要整流濾波操作。整流濾波的操作有整流濾波電路來實現。本文選用的整流濾波電路是橋式的,因為橋式的實現非常簡單,而且能夠達到本文的需求。橋式電路的結構如圖4-1所示利用放大器產生所需的電源電壓以供集成芯片和單片機使用。如圖3-14所示為系統(tǒng)電源供電模塊圖。變壓器產生15V左右的交流電,電源的輸入端電源由15V變壓器的線圈提供,經過整流橋D整流后經電容C1濾成平穩(wěn)的12V作為Q1的輸入電源,輸出端經過Q1濾波后就可得到平穩(wěn)的幅值為12V的直流電。產生的12V直流電壓給Q2的正電源端供電。Q2的輸入電源直接由U6產生的12V直流電提供,其輸出電壓也是通過電容C2進行濾波。輸出的5V電壓作為單片機的供電電源

圖 3-4 電源電路
3.4  D/A轉換和顯示電路的設計

DAC0832是一種D/A轉換芯片,具有雙通道、8位分辨率的性能,由美國半導體公司生產。DAC0832因為其性價比高、兼容性強、體積小的優(yōu)勢,占據了很大的D/A轉換芯片市場份額,是很多單片機用戶的首選。學習并熟練使用DAC0832可使我們了解D/A轉換器的原理,并提高我們單片機技術的水平。芯片如下所示:

圖 3-5 D/A芯片

芯片接口說明如下所示:DO:信號輸出接口,主要用于D/A轉換的輸出;DI:信號輸入接口,主要用于命令的輸入;CLK:時鐘,頻率不超過600K赫茲;CH0:頻道0,可作為正負輸入端使用;CH1:頻道1,可作為正負輸入端使用;GND:接地Vcc(VREF):電源輸入參考電壓輸入。CS_:片選,只有在低電平時才能發(fā)揮作用;DAC0832的工作原理:單片機與DAC0832之間通常需要用四根數據線相連,分別是CLK、CS、DO、DI。但考慮到DI和DI在實際的使用過程中,不會同時同時被占用,而且單片機接口通常也是雙向的,因此在實際的使用中DI和DO可以用一根數據線并聯連接。當DAC0832的CS端的電平為高電平時DAC0832是無法工作的,此時DIDO端口以及CLK端口的電平不產生任何影響,因此可以任意選擇;當DAC0832的CS端的電平為低電平時,DAC0832芯片進入工作狀態(tài),此時時鐘脈沖通過CLK端輸入,數據信號也通過DI端進入,當第1個脈沖行將結束時,DI端必須處于高電平狀態(tài),以便信號的啟動。DI端使用2位的數據對通道功能的選擇進行編碼,此步驟完成在第2、3個脈沖下沉之前。這兩位編碼可以組合出四種情

形如下:當編碼為“11”時,只有CH1通道起作用;當編碼為“10”時,進隊CH0通道起作用;當編碼為“01”時,CH1被當成正輸入端使用,而CH0責備當成負輸入端使用;當編碼為“00”時,CH1被當做負輸入端使用,而CH0則被當作正輸入端使用。當第三個脈沖結束以后DI端的使命就完成了,DO端開始發(fā)揮作用,將轉換的數據讀取過來并進行輸出。從第四個脈沖完成,一直到第十一個脈沖完成,DO端會按照從高到低的順序依次輸出一個字節(jié)的8位轉換結果,從第十一個脈沖下沉完成后,開始輸出下一個相反字節(jié),此時一直到第19個脈沖之間都不需做處理,直接輸出,這樣的過程就是一個完整的DA轉換過程。DA轉換完成以后,將CS端的電平調整到高電平,芯片停止工作,對轉換后的數據進行處理。若要同時使用多個7段LED數碼管,就必須應用掃描式的顯示。硬件電路方面,首先將每個7段LED數碼管的a,b,c,g都連接到一起,然后使用晶體管對他們的共同引腳進行逐個驅動。最后的顯示是通過將第一個7段LED數碼管需要顯示的數據發(fā)送到發(fā)送到a,b,c,g總線上,并把掃描信號發(fā)送到公共端來實現的。圖中LED1,LED2分別連接89C52的P2.0 ,P2.1 管腳,根據89C52的輸出信息來判斷驅動哪一個數碼管,即哪一個數碼管亮,而A~G和DP連接89C52單片機的P0.0~P0.7管腳,根據89C52的輸出的數字信息從而判斷數碼管的哪一段亮,顯示出所輸出的電壓值。

3.5鍵盤控制子系統(tǒng)

鍵盤控制子系統(tǒng)如圖 3-6 所示。本設計中,采用獨立按鍵 K11-K44共16個對單片機核心芯片STC89C52進行輸入控制。各按鍵分別一端接地,一端接單片機引腳。實現功能:按鍵 K11-K23為對應的數字0-9,K14,K24分別是加減0.1,K34表示位選擇鍵(十位或各位),K33是確定鍵。選擇電壓后,按確定鍵,便可輸出所需的電壓。

圖 3-6鍵盤控制子系統(tǒng)

本章小結

本章內容主要對各類硬件設計進行了說明,包括單片機最小系統(tǒng)的設計,時鐘電路的設計,復位電路的設計,電源模塊的設計,顯示電路的設計,。一一闡述了設計思路以及設計方法,在下一章,主要對系統(tǒng)的軟件部分的設計進行詳細闡述。



第4章 軟件程序設計4.1 系統(tǒng)主程序設計流程及說明

首先對系統(tǒng)進行初始化,讀取預存儲的電壓值,本次設計中預存儲電壓值為9.9V,并將其發(fā)送給 LED顯示電壓值;之后在判斷是否有鍵按下,當有鍵盤有按鍵按下時,接收來自鍵盤的電壓輸入值,并通過 D/A把輸入的數字量轉換成模擬電壓值,控制輸出電壓的大小。然后采樣輸出電壓的大小,并與輸入電壓值進行比較放大,由電壓調整電路調整輸出電壓的大小,直到輸出電壓與輸入電壓相等。通過比較從LED顯示更新的電壓值。主程序流程圖如所示

圖 4-1主程序流程圖
4.2 數碼管顯示子程序流程圖

程序實現的功能是將單片機從AD0832讀取的數字信號轉換為七段碼在LED上顯示出來。顯示方式采用的是動態(tài)掃描的方式,先給位選信號,再給段選信號,然后延時一下。結束延時10ms顯示第四位送形第四位送位選給低復位沖4s<t<960us第三位送形第三位送位選給低延時10ms顯示第二位送形第二位送位選給低第一位送形第一位送位選給低延時10ms顯示。

圖 4-2數碼管顯示子程序流程圖
本章小結

本章主要系統(tǒng)的軟件進行了分析和設計,包括參數設置,軟件開發(fā)環(huán)境,程序初始化設計,顯示模塊程序設計。繪制了各個程序的框圖。下一章將對系統(tǒng)的電路安裝與調試過程展開論述。

第5章 系統(tǒng)調試與測試結果
5.1 系統(tǒng)軟件調試

用電壓表在運算放大器輸出端上測量電壓;將所得的結果與數字顯示值和LED顯示值進行比對,如果誤差超過了合理的范圍,那么就需要對軟件部分進行調試。調試的重點應該放在采樣模塊和D/A轉換模塊的代碼,使用軟件調試的常用方法,逐步排查,找到問題所在。

5.2 系統(tǒng)硬件調

系統(tǒng)可能出現的偏差有兩類,一是輸出的電壓不夠穩(wěn)定,有波動,二是數字的顯示與數碼管的顯示存在不一致。如果出現上面的兩類偏差,就需要對系統(tǒng)進行硬件調試。硬件調試的方法是對系統(tǒng)進行各類檢查,檢查主要從以下幾個方面進行:(1)各部件是否都是完好無損的;(2)電阻的選擇是否科學;(3)電壓的供應是否正常。硬件調試是解決問題的有效手段。

本章小結

了解一個課題的內容熟悉就需要對于電路的整機原理進行學習,所以本章對于整機原理進行介紹。此外,又分別對于電路如何調試以及可能會出現的問題進行了介紹。通過調試然后解決問題可以使此次設計能夠更好的達到預期的指標。


單片機源程序如下:

  1. #include<reg51.h>
  2. #include
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar aa,bb,cc,dd,jj,ii,jjj,iii,key,j;
  6. uchar time1=0;
  7. sbit led1=P2^0;
  8. sbit led2=P2^1;
  9. sbit ce=P2^4;
  10. #define timer0_count 0xfc18//定時器初值,設置time0 1/1000秒中斷一次
  11. const seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//數碼管的顯示
  12. const seg_point[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//有小數點的數碼管顯示
  13. uchar scan1;//用來分別顯示2個數碼管
  14. uchar scan2;
  15. uchar counter[2]={0xf1,0xf2};
  16. uchar vout=0; //j_片選,vout_電壓輸出

  17. static void timer0_initialize(void)//timer0的初始化
  18. //定時器的初始化程序
  19. {
  20.         EA=0;        //中斷控制器IE--停止接受中斷
  21.                 TR0=0;        //停止計時
  22.                 TMOD=0x01;     //設置工作方式為1
  23.                 TL0=(timer0_count & 0x00ff);
  24.             TH0=(timer0_count>>8);  //設置time0 初值      
  25.                 PT0=1;    //設置timer0高優(yōu)先級
  26.                 ET0=1;          //允許timer0中斷
  27.                 TR0=1;           //開始計時
  28.                 EA=1;           //開所有中斷
  29. }

  30. void delay(uint t) //tms的延時
  31. {   
  32.         uchar i;
  33.         uint j;
  34.     for(j=0;j<t;j++)
  35.                 for(i=0;i<40;i++);
  36. }
  37. void shuc(void)
  38. {         
  39.          uchar nn;
  40.          vout=2*(scan2*10+scan1);//輸出的數字量
  41.         P1=vout;
  42.         for(nn=0;nn<250;nn++)
  43.                 ;
  44.                 nn=0;//輸出是存在D/A轉換時間差所以要延時

  45. }
  46. void shaom(void)
  47. {
  48.          P3=0x0f;//掃描是否有按鍵按下
  49.      if((P3&0x0f)!=0x0f)
  50.      dd=0;
  51.          else
  52.          dd=1;
  53. }
  54. void zdbj(void) //自動步進
  55. {
  56.         uchar rr;
  57.         jj=scan2;
  58.         ii=scan1;
  59.         shaom();
  60.         for(;jj<10;jj++)
  61.     {
  62.             for(;ii<10;ii++)
  63.                 {
  64.                          if(dd)
  65.                                  {
  66.                                          scan1=ii;
  67.                                          scan2=jj;
  68.                                         shuc();
  69.                                          for(rr=0;rr<250;rr++)
  70.                                         {
  71.                                                 shaom();
  72.                                                 if(dd)      
  73.                                                  delay(70);
  74.                                                 else
  75.                                                 break;
  76.                                         }
  77.                                          if(jj==9&&ii==9)
  78.                                          {
  79.                                                  ii=0;
  80.                                                  jj=0;
  81.                                          }

  82.                                  }
  83.                         else
  84.                          {
  85.                                  jj=10;
  86.                                  ii=10;
  87.                          }
  88.                 }
  89.                 ii=0;
  90.     }
  91.         jj=0;
  92.         shaom();
  93.         for(;dd==0;)
  94.         shaom();

  95. }

  96. void sjb(void)        //三角波
  97. {
  98.         uchar max;
  99.         max=vout;
  100.         shaom();
  101.         for(;dd;)
  102.          {
  103.                    for(iii=0;iii<=max;iii=iii+2)
  104.                    {
  105.                           P1=iii;
  106.                         shaom();
  107.                          delay(10);
  108.                            if(dd==0)
  109.                  break;
  110.                 }
  111.                 if(dd==0)
  112.             break;
  113.                 for(;iii>0;iii=iii-2)
  114.                 {
  115.                         P1=iii;
  116.                         shaom();
  117.                         delay(5);
  118.                         if(dd==0)
  119.                         break;
  120.                 }
  121.                 if(dd==0)
  122.             break;
  123.           }
  124.            P1=max;
  125.          shaom();
  126.          for(;dd==0;)
  127.         shaom();
  128. }
  129. unsigned char keyscan(void)  //鍵盤掃描函數,使用行列反轉掃描法
  130. {
  131.          unsigned char cord_h,cord_l;//行列值中間變量
  132.         P3=0x0f;          //行線輸出全為0
  133.          cord_h=P3&0x0f;     //讀入列線值
  134.          if(cord_h!=0x0f)    //先檢測有無按鍵按下
  135.          {
  136.                   delay(70);        //去抖
  137.                   if((P3&0x0f)!=0x0f)
  138.                   {
  139.                     cord_h=P3&0x0f;  //讀入列線值
  140.                     P3=cord_h|0xf0;  //輸出當前列線值
  141.                     cord_l=P3&0xf0;  //讀入行線值                                                                                                   ;;
  142.                         while((P3&0xf0)!=0xf0);//等待松開并輸出
  143.                          {
  144.                                  time1=time1+1;
  145.                             return(cord_h+cord_l);//鍵盤最后組合碼值
  146.                          }
  147.                   }
  148.          }return(0);     //返回該值
  149. }
  150. void timer0_isr(void) interrupt 1   //timer0中斷
  151. //用于LED數碼管的動態(tài)顯示
  152. {

  153.          TR0=0;    //停止時鐘0
  154.         P2=counter[j];
  155.         switch(j)
  156.         {
  157.                  case 0:P0=seg[scan1];break;                                                                                
  158.                  case 1:P0=seg_point[scan2];break;
  159.                          default:break;        //j為其他情況是跳出循環(huán)
  160.         }
  161.         j++;
  162.         if(j==2)
  163.         j=0;
  164.     TL0=(timer0_count & 0x00ff);
  165.         TH0=(timer0_count>>8);  //設置time0 初值
  166.         TR0=1;         //開時鐘                                       
  167. }

  168. void main(void)
  169. {               
  170.         ce=0;
  171.         delay(5);   
  172.         scan1=(P3/2)%10;
  173.         scan2=P3/20;
  174.         ce=1;
  175.         delay(5);
  176.         shuc();

  177.         timer0_initialize();        //定時器初始化用于LED顯示
  178.     do
  179.    {   
  180.             key=keyscan();
  181.                 if(time1==1)
  182.                 switch( key)
  183.         {      

  184.                         case 0xee:aa=1;break;//1 按下相應的鍵顯示相對應的碼值
  185.                  case 0xed:aa=2;break;
  186.                  case 0xeb:aa=3;break;
  187.                  case 0xe7:aa=4;break;//4
  188.                  case 0xde:aa=5;break;//5
  189.                        case 0xdd:aa=6;break;//5
  190.                           case 0xdb:aa=7;break;//6
  191.                             case 0xd7:aa=8;break;//7
  192.                           case 0xbe:aa=9;break;//8
  193.                           case 0xbd:aa=0;break;//9
  194.                      case 0xbb:time1--;break;//確認
  195.                            case 0xb7: //三角波
  196.                         {
  197.                         time1=0;
  198.                         sjb();
  199.                         }
  200.                         break;
  201.                            case 0x7e:                //加
  202.                     {
  203.                                 time1=0;
  204.                              scan1++;
  205.                         if(scan1==10)
  206.                                 {
  207.                                         scan1=0;
  208.                                     scan2++;
  209.                                         if(scan2==10)
  210.                                         scan2=0;
  211.                                 }
  212.                                 shuc();
  213.                         }break;//c
  214.                           case 0x7d:                //減
  215.                     {
  216.                                 time1=0;
  217.                         scan1--;                                   
  218.                                 if(scan1==-1)
  219.                                 {         
  220.                                         scan1=9;
  221.                                         scan2--;
  222.                                         if(scan2==-1)
  223.                                         scan2=9;
  224.                                 }
  225.                                 shuc();
  226.                         }break;
  227.                               case 0x7b:                //自動步進
  228.                         {
  229.                                 time1=0;
  230.                     zdbj();
  231.                         }break;//e
  232.                           case 0x77: time1--;break;      
  233.                   }

  234.                 if(time1==2)
  235.                 switch( key)
  236.                  {      

  237.                         case 0xee:bb=1;break;//0 按下相應的鍵顯示相對應的碼值
  238.                          case 0xed:bb=2;break;//1
  239.                           case 0xeb:bb=3;break;//2
  240.                      case 0xe7:bb=4;break;//3
  241.                      case 0xde:bb=5;break;//4
  242.                      case 0xdd:bb=6;break;//5
  243.                      case 0xdb:bb=7;break;//6
  244.                           case 0xd7:bb=8;break;//7
  245.                           case 0xbe:bb=9;break;//8
  246.                           case 0xbd:bb=0;break;//9
  247.                           case 0xbb:                //確認
  248.                         {
  249.                              scan2=0;
  250.                              scan1=aa;
  251.                                    time1=0;
  252.                                  shuc();
  253.                         }break;
  254.                           case 0xb7://三角波
  255.                         {
  256.                         time1=0;
  257.                         sjb();
  258.                         }
  259.                         break;
  260.                           case 0x7e:                //加
  261.                         {
  262.                                 time1=0;
  263.                         scan1++;
  264.                         if(scan1==10)
  265.                                 {
  266.                                         scan1=0;
  267.                                     scan2++;
  268.                                         if(scan2==10)
  269.                                         scan2=0;
  270.                                 }
  271.                                 shuc();
  272.                         }break;//c
  273.                      case 0x7d:                //減  
  274.                         {
  275.                                 time1=0;
  276.                               scan1--;                                   
  277.                                 if(scan1==-1)
  278.                                 {                 
  279.                                         scan1=9;
  280.                                         scan2--;
  281.                                         if(scan2==-1)
  282.                                          scan2=9;
  283.                                 }
  284.                                 shuc();
  285.                         }break;
  286.                           case 0x7b:                //自動步進
  287.                     {
  288.                                 time1=0;
  289.             zdbj();
  290.                         }break;//e
  291.                           case 0x77: time1--;break;
  292.                  }
  293.                 ;
  294.                 if(time1>2)
  295.                  switch( key)
  296.                  {      

  297.                           case 0xee:time1--;break;//0 按下相應的鍵顯示相對應的碼值
  298.                           case 0xed:time1--;break;//1
  299.                           case 0xeb:time1--;break;//2
  300.                           case 0xe7:time1--;break;//3
  301.                           case 0xde:time1--;break;//4
  302.                           case 0xdd:time1--;break;//5
  303.                           case 0xdb:time1--;break;//6
  304.                           case 0xd7:time1--;break;//7
  305.                           case 0xbe:time1--;break;//8
  306.                           case 0xbd:time1--;break;//9
  307.                           case 0xbb:                //確認               
  308.                         {  
  309.                                 time1=0;
  310.                             scan2=aa;
  311.                                   scan1=bb;
  312.                                   time1=0;
  313.                                 shuc();
  314.                         }break;
  315.                           case 0xb7://三角波
  316.                         {
  317.                         time1=0;
  318.                     sjb();
  319.                         }
  320.                         break;
  321.                           case 0x7e:                //加
  322.                     {
  323.                         scan1++;
  324.                         if(scan1==10)
  325.                                 {
  326.                                          scan1=0;
  327.                                     scan2++;
  328.                                         if(scan2==10)
  329.                                         scan2=0;
  330.                                 }
  331.                                 shuc();
  332.                         }break;//c
  333.                          case 0x7d:                //減
  334.                     {
  335.                             time1=0;
  336.                                 scan1--;                                   
  337.                                 if(scan1==-1)
  338.                                 {         
  339.                                         scan1=9;
  340.                                         scan2--;
  341.                                         if(scan2==-1)
  342.                                         scan2=9;
  343.                                 }
  344.                                 shuc();
  345.                         } break;
  346.                           case 0x7b:                //自動步進
  347.                     {
  348.                                 time1=0;
  349.                     zdbj();
  350.                         }break;//e
  351.                           case 0x77: time1--;break;
  352.             }        
  353.     }                     
  354.         while(1);
  355. }
復制代碼


全部資料51hei下載地址(仿真+hex):
數字.zip (1.11 MB, 下載次數: 65)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:831073 發(fā)表于 2021-12-29 14:38 | 只看該作者
請問一下點如果輸出電壓的范圍想改變到0-40V應該怎么設置
回復

使用道具 舉報

板凳
ID:1064325 發(fā)表于 2023-2-26 15:55 | 只看該作者
為什么我按了按鍵沒反應
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表