極客DIY開源方案分享——智能家居你也可以做,何不DIY個自動窗簾升降控制系統(tǒng)?(紀念我的職業(yè)生涯處女作、上古匯編語言編程)

      網(wǎng)友投稿 1108 2022-05-29

      【系列專欄】:博主結(jié)合工作實踐輸出的,解決實際問題的專欄,朋友們看過來!

      《QT開發(fā)實戰(zhàn)》

      《嵌入式通用開發(fā)實戰(zhàn)》

      《從0到1學習嵌入式Linux開發(fā)》

      《Android開發(fā)實戰(zhàn)》

      《實用硬件方案設計》

      長期持續(xù)帶來更多案例與技術文章分享;

      歡迎商業(yè)項目咨詢,10年+軟硬全棧內(nèi)功,助力解決您的尊貴需求。

      ——————————————————————————————————

      目錄

      0 引言

      1 功能需求

      2 方案設計

      2.1 硬件設計

      2.1.1 STC12C5A60S2單片機最小系統(tǒng)

      2.1.2 步進電機

      2.1.3 按鍵/顯示接口電路

      2.1.4 傳感器

      2.2 軟件設計

      2.2.1 主程序軟件設計

      2.2.2 步進電機子程序設計

      2.2.3 顯示子程序設計

      2.2.4 按鍵子程序設計

      2.2.5 定時子程序設計

      3 總結(jié)

      附1:作品實拍

      附2:匯編語言代碼

      0 引言

      整理資料時,發(fā)現(xiàn)了學生時代一些好的電子設計,這些設計在當時也是比較不錯的,到現(xiàn)在看來已經(jīng)年代久遠了,不過放在今天自己DIY下給小朋友,培養(yǎng)興趣愛好,也是很好的。

      今天分享的是基于STC單片機設計的自動窗簾控制升降系統(tǒng),根據(jù)其不同控制模式,實現(xiàn)半自動控制、自動控制、定時控制和無線控制的相互轉(zhuǎn)換控制窗簾機。該設計由光電開關電路、按鍵控制模塊、無線遙控模塊等組成,可實現(xiàn)窗簾自動升降。這個小電子設計當時得了校電子設計大賽一等獎,翻看了下,連編程語言都是用匯編寫的,現(xiàn)在想想,那時候真是初生牛犢不怕虎啊。

      1 功能需求

      自動窗簾主要有以下幾大功能:

      1)手動控制:電動窗簾具有手動正轉(zhuǎn)、手動反轉(zhuǎn) 和手動停止的功能;

      2)工作狀態(tài)指示:電機工作在正轉(zhuǎn)、反轉(zhuǎn)和停止狀態(tài)的時候,數(shù)碼管均有不同工作狀態(tài)指示;

      3)半自動控制:在需要關閉或打開窗簾的時候,只需要人工按一下“正轉(zhuǎn)”或“反轉(zhuǎn)”按鍵后,窗簾到位自動停止;

      4)無線控制:通過遠程遙控器,控制窗簾的正轉(zhuǎn)、反轉(zhuǎn) 和停止;

      5)環(huán)境亮度控制:通過自動感知環(huán)境亮度完成窗簾的開啟或關閉操作控制,“天黑關閉,天亮打開”具有智能管理,不產(chǎn)生誤動作;

      6)定時控制:根據(jù)設置輸入的開啟或關閉時間,來控制窗簾的關閉和打開。

      2 方案設計

      基于以上需求,使用基于單片機的方案實現(xiàn),單片機應用系統(tǒng)由硬件和軟件組成。硬件由單片機,輸入/出設備以及各種實現(xiàn)單片機系統(tǒng)控制要求的接口電路和有關的外圍電路芯片或部件組成;軟件由單片機應用系統(tǒng)實現(xiàn)其特定控制功能的各種工作程序和管理程序組成。

      本自動窗簾控制升降系統(tǒng)采用STC12C5A60S2單片機作為主控器,窗簾的正轉(zhuǎn)、反轉(zhuǎn)和停止功能可由單片機輸出電平來控制步進電機的運轉(zhuǎn)實現(xiàn);環(huán)境亮度的控制通過光敏電阻和運放組成的電路來控制單片機輸出電平繼而控制電機的正轉(zhuǎn)和反轉(zhuǎn);時間自動控制可以由定時器來控制;無線控制由無線收發(fā)模塊完成。由光電傳感器來探測外界的光強,后的信號由單片機控制器,來實現(xiàn)電機的運行與停止。顯示部件用來顯示電動窗簾控制器的各種狀態(tài)信息。鍵盤是主要的輸入設備,控制單片機的各種參量。

      窗簾控制器可以使用無線遙控器進行遠程手動開、手動關和手動停控制;可以執(zhí)行事先輸入的開啟時間和關閉時間進行時間控制。三種工作方式可以方便地進行選擇,當選擇時間控制的方案時,數(shù)碼管還能顯示當時小時和分鐘時間。

      2.1 硬件設計

      當時是使用Protues仿真軟件設計的電路圖,該軟件可以進行仿真,驗證設計的功能是否正確。系統(tǒng)總體的硬件接線圖如下:

      總體硬件電路圖包括單片機外圍電路、檢測電路、鍵盤/顯示接口電路、步進電機控制電路等模塊。單片機外圍電路提供各模塊所需的5V電源和時鐘模塊;單片機的P2口控制步進電機的運行從而控制窗簾的升降。顯示和鍵盤讓人機交換變得更容易。以上各模塊組成了電動窗簾控制器的總體電路。因當時proteus器件庫中不含STC12C5A60S2,仿真電路中單片機芯片采用AT89C51。

      2.1.1 STC12C5A60S2單片機最小系統(tǒng)

      (1)STC12C5A60S2單片機

      89C51是一種帶4K字節(jié)閃爍可編程可擦除只讀存儲器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低電壓,高性能CMOS8位微處理器,俗稱單片機。STC12C5A60S2/AD/PWM系列單片機是宏晶科技生產(chǎn)的單時鐘/機器周期(1T)的單片機,是高速/低功耗/超強抗干擾的新一代8051單片機,指令代碼完全兼容傳統(tǒng)8051,但速度快8-12倍。內(nèi)部集成MAX810專用復位電路,2路PWM,8路高速10位A/D轉(zhuǎn)換(250K/S),針對電機控制,強干擾場合。STC12C5A60S2單片機為很多嵌入式控制系統(tǒng)提供了一種靈活性高且價廉的方案。

      (2)晶振電路

      電路中的晶振即石英晶體震蕩器。由于石英晶體震蕩器具有非常好的頻率穩(wěn)定性和抗外界干擾的能力,所以,石英晶體震蕩器是用來產(chǎn)生基準頻率的。通過基準頻率來控制電路中的頻率的準確性。同時,它還可以產(chǎn)生振蕩電流,向單片機發(fā)出時鐘信號。

      下圖是單片機的晶振電路。電路中的電容C1和C2的典型值通常選擇為30PF左右,該電容的大小會影響振蕩電路頻率的高低、振蕩器的穩(wěn)定性和起振的快速性。晶體振蕩頻率的范圍通常在1.2~12MHz。晶體的頻率越高,系統(tǒng)的時鐘頻率越快,單片機的運行速度越快。但反過來,運行速度對于存儲器的速度要求就越高,對印刷電路板的工藝要求也就越高,即要求線間的寄生電容要小。晶體和電容應該盡可能安裝得與單片機芯片靠近,以減少寄生電容,更好地保證振蕩器穩(wěn)定、可靠地工作。

      (3)復位電路

      復位是單片機的初始化操作,只需要給STC12C5A60S2的復位引腳RST加上大于2個機器周期(即24個時鐘振蕩周期)的高電平就可以使STC12C5A60S2復位。復位時,單片機初始化為0000H,從0000H單元開始執(zhí)行程序。除了進入系統(tǒng)的正常初始化之外,當程序運行錯誤(如程序跑飛)或操作錯誤使系統(tǒng)處于鎖死狀態(tài)時,也需要復位鍵使RST腳為高電平,使STC12C5A60S2擺脫“跑飛”或“死鎖”狀態(tài)而重新啟動。

      2.1.2 步進電機

      步進電機是一種將電脈沖轉(zhuǎn)化為角位移的執(zhí)行機構。通俗一點講:當步進驅(qū)動器接收到一個脈沖信號,它就驅(qū)動步進電機按設定的方向轉(zhuǎn)動一個固定的角度(及步進角)。可以通過控制脈沖個數(shù)來控制角位移量,從而達到準確定位的目的;同時也可以通過控制脈沖頻率來控制電機轉(zhuǎn)動的速度和加速度,從而達到調(diào)速的目的。

      步進電機28BYJ48型四相八拍電機,電壓為DC5V—DC12V。當對步進電機施加一系列連續(xù)不斷的控制脈沖時,它可以連續(xù)不斷地轉(zhuǎn)動。每一個脈沖信號對應步進電機的某一相或兩相繞組的通電狀態(tài)改變一次,也就對應轉(zhuǎn)子轉(zhuǎn)過一定的角度(一個步距角)。當通電狀態(tài)的改變完成一個循環(huán)時,轉(zhuǎn)子轉(zhuǎn)過一個齒距。四相步進電機可以在不同的通電方式下運行,常見的通電方式有單(單相繞組通電)四拍(A-B-C-D-A。。。),雙(雙相繞組通電)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)

      步進電機控制系統(tǒng)的方框圖如下:

      選用的步進電機接線方式:

      紅線接電源5V,其他四根線接單片機IO口,由于單片機接口驅(qū)動能力不足,需要使用ULN2003進行電機驅(qū)動:

      極客DIY開源方案分享——智能家居你也可以做,何不DIY個自動窗簾升降控制系統(tǒng)?(紀念我的職業(yè)生涯處女作、上古匯編語言編程)

      2.1.3 按鍵/顯示接口電路

      按鍵在單片機應用系統(tǒng)中能實現(xiàn)向單片機輸入數(shù)據(jù),傳送命令等功能,是人工干預單片機的主要手段。本設計中的功能按鍵有:當前時間設定鍵(調(diào)整時間 分);鬧鈴時間設定鍵(調(diào)整時間時);自動窗簾開和關的定時控制鍵;確定鍵,時間設定完成后確定輸入;復位鍵,在程序出錯或者有誤操作的時候;正轉(zhuǎn)鍵,使步進電機正轉(zhuǎn),窗簾打開;反轉(zhuǎn)鍵,使步進電機反轉(zhuǎn),窗簾關閉;停止鍵,步進電機停止運轉(zhuǎn)。

      按鍵的觸點在閉合和斷開時均會產(chǎn)生抖動,這時觸點的邏輯電平是不穩(wěn)定的,如果不妥善處理,將會引起按鍵命令的錯誤執(zhí)行或重復執(zhí)行。一般消除抖動采用軟件方法來解決,將在軟件部分介紹這點。

      顯示部分則主要顯示時間,用于設置時間。采用LED數(shù)碼管進行顯示是一種經(jīng)濟實用的方法。每位數(shù)碼管由7個筆畫加上小數(shù)點共8個發(fā)光二極管組成;有共陰極和共陽極兩種類型,公共端用來進行位控制,筆畫端用來進行字符控制;數(shù)碼管顯示有靜態(tài)顯示和動態(tài)顯示兩種方法。

      在數(shù)碼管顯示中,有2個技術問題需要解決,這就是整數(shù)高位和閃爍顯示問題。雖然某些新型LED驅(qū)動芯片本身具有閃爍控制和熄滅控制功能,但通過合理的軟件設計,采用廉價芯片組成的驅(qū)動電路同樣可以實現(xiàn)整數(shù)高位滅零和閃爍顯示功能,達到降低系統(tǒng)硬件成本的目的。本設計采用的就是4位LED數(shù)碼管的串行驅(qū)動電路來達到顯示時間和消除閃爍顯示的目的。驅(qū)動器采用74LS245,顯示電路圖如下:

      2.1.4 傳感器

      電動窗簾要根據(jù)光照的情況而自動開關窗簾,因而需要使用到光電傳感器。這里使用光敏電阻,光敏電阻是用光電導體制成的光電器件,又稱光導管,他是基于半導體光電效應工作的。光敏電阻沒有極性,純粹是一個電阻器件,使用時可以加直流偏壓,也可以加交流電壓。當無光照時,光敏電阻值(暗電阻)很大,電路中電流很小。當光敏電阻受到一定波長范圍的光照時,它的阻值急劇減少,因此電路中電流迅速增加。光敏電阻具有很高的靈敏度,很好的光譜特性,光譜響應從紫外區(qū)一直到紅外區(qū)。而且體積小、重量輕、性能穩(wěn)定。因此在自動化技術中得到廣泛的應用。光敏電阻器一般用于光的測量、光的控制和光電轉(zhuǎn)換(將光的變化轉(zhuǎn)換為電的變化)。通常,光敏電阻器都制成薄片結(jié)構,以便吸收更多的光能。當它受到光的照射時,半導體片(光敏層)內(nèi)就激發(fā)出電子—空穴對,參與導電,使電路中電流增強。

      根據(jù)光敏電阻的光譜特性,可分為三種光敏電阻器:

      1)紫外光敏電阻器:對紫外線較靈敏,包括硫化鎘、硒化鎘光敏電阻器等,用于探測紫外線。

      2)紅外光敏電阻器:主要有硫化鉛、碲化鉛、硒化鉛。銻化銦等光敏電阻器,廣泛用于導彈制導、天文探測、非接觸測量、人體病變探測、紅外光譜,紅外通信等國防、科學研究和工農(nóng)業(yè)生產(chǎn)中。

      3)可見光光敏電阻器:包括硒、硫化鎘、硒化鎘、碲化鎘、砷化鎵、硅、鍺、硫化鋅光敏電阻器等。主要用于各種光電控制系統(tǒng),如光電自動開關門戶,航標燈、路燈和其他照明系統(tǒng)的自動亮滅,自動給水和自動停水裝置,機械上的自動保護裝置和“位置檢測器”,極薄零件的厚度檢測器,照相機自動曝光裝置,光電計數(shù)器,煙霧報警器,光電跟蹤系統(tǒng)等方面。這里選用可見光光敏電阻器。

      應用光控原理工作,天亮窗簾自動打開,天黑窗簾自動關閉。上圖中使用LM358做的比較電路,同相輸入端有兩個電阻分壓得到一個電壓值,作為基準電壓進行比較,而反相輸入端用一個光敏電阻對外部環(huán)境的光線進行采集,利用光敏電阻暗時電阻大,亮時電阻小的特點,來確定反向輸入端的電壓值。再兩者進行比較,比較后的信號再送入單片機89C2051的IO口,輸出高/低電平,從而通過單片機來控制電機的正反轉(zhuǎn)。來實現(xiàn)天亮窗簾自動打開,天黑窗簾自動關閉這一自動控制功能。另外反相輸入端可以通過可變電阻改變分壓值,進而調(diào)節(jié)感光的靈敏度。

      2.2 軟件設計

      系統(tǒng)軟件設計主要包括顯示子程序,鍵盤子程序,時鐘程序,步進電機控制程序設計及部分構成。本章節(jié)系統(tǒng)的介紹了電動窗簾的主程序和各主要功能子程序的設計流程,具體的程序代碼見附錄。

      2.2.1 主程序軟件設計

      主程序大循環(huán),主要完成單片機初始化,關中斷,菜單顯示內(nèi)容初始化,按鍵掃描,電機運行,計時等功能。

      啟動主程序,先關中斷并且設置堆棧,接著初始化寄存器,初始化顯示內(nèi)容;然后執(zhí)行按鍵查詢,執(zhí)行相應的操作。如果是設定鍵,則設定時間,開始計時;到時間后步進電機開始相應的工作,工作完成后停機。如果是電機控制鍵,則也執(zhí)行相應的工作。如果都不是,則是復位鍵,采取復位操作。

      2.2.2 步進電機子程序設計

      步進電機程序設計的主要任務有三點:

      1)判斷旋轉(zhuǎn)方向;

      2)按順序傳送控制脈沖;

      3)判斷所要求的控制步數(shù)是否傳送完畢。

      2.2.3 顯示子程序設計

      顯示程序開始后,起始地址60H發(fā)送到R0,01H發(fā)送至顯示位代碼R2,再將位代碼發(fā)送到單片機A口,單片機取顯示數(shù)據(jù)查表轉(zhuǎn)換成顯示代碼發(fā)送至單片機B口,延時2ms,指針R0加1,然后判斷6顯示是否完成。如果完成則返回,沒完成則位代碼R2左移一位,繼續(xù)顯示查表,一直到6位顯示完成后返回。

      2.2.4 按鍵子程序設計

      按鍵的觸點在閉合和斷開時均會產(chǎn)生抖動,這時觸點的邏輯電平是不穩(wěn)定的,如不妥善處理,將會引起按鍵命令的錯誤執(zhí)行或者重復執(zhí)行。現(xiàn)在用軟件延時的方法來避開抖動階段。在判斷是否有鍵閉合后都延時5ms,按下鍵后再延時12ms就可以避免鍵盤的抖動。然后鍵碼分析,執(zhí)行相應的模塊,顯示后返回。

      2.2.5 定時子程序設計

      定時的主要功能是在設定時間單片機能夠得到中斷信號,從而控制窗簾的開關。時鐘發(fā)出50ms的信號給單片機,計數(shù)器計數(shù),當計數(shù)到20,則過了1秒,秒單元數(shù)值加1,當秒單元到達60,分單元數(shù)值加1,秒單元清零。當時單元到達24,時單元清零。標志1天時間計滿,把他們的值放到存儲單元的指定單元。

      3 總結(jié)

      博主在整理此篇文章時,充滿了對學生時代滿滿的回憶,因為這個電子設計是博主從事工程師生涯的第一個作品,當時得了校級電子設計大賽一等獎,懷念當時一起組隊的小伙伴。這個作品現(xiàn)在看來可能很簡單,但在當時剛剛?cè)腴T的階段,完成它也算是經(jīng)歷了千辛萬苦的,清晰的記著因為一點硬件問題去電子城買器件的契機請教老師傅,去學校實驗室請教高年級學長,到網(wǎng)上查資料,到圖書館惡補專業(yè)知識,大學時代真的是太美好了。

      作于202204281410,已歸檔

      ———————————————————————————————————

      本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載!

      若本文對您有幫助,輕抬您發(fā)財?shù)男∈郑P注/評論//,就是對我最大的支持!

      祝君升職加薪,鵬程萬里!

      附1:作品實拍

      當時都是手工焊接的,看起來有些簡陋吧。現(xiàn)在有些器件已經(jīng)丟了,運行不起來了,這么多年過去了,板子一直留在身邊:)

      附2:匯編語言代碼

      當時才大二,C語言剛剛學習,匯編語言學的較多,所以當時就勇者無畏的使用了匯編語言編程:)

      主程序: ALB EQU 20H.0 ;鬧鈴標志位 K5 EQU P0.0 ;設定P0.0以K5表示 正 K6 EQU P0.1 ;設定P0.1以K6表示 反 K7 EQU P0.2 ;設定P0.2以K7表示 停 K8 EQU P0.3 ;設定P0.3以K8表示 轉(zhuǎn)換 K9 EQU P3.7 ;光敏信號 K10 EQU P3.6 ;復位調(diào)節(jié)鍵 K2 EQU P0.5 ;小時控制位 K1 EQU P0.4 ;分鐘控制位 K3 EQU P0.6 ;時間確認按鍵 K4 EQU P0.7 ;電機正反辨認 SEC EQU 38H ;存放秒鐘變量 MIN EQU 37H ;存放分鐘變量 HOUR EQU 36H ;存放時鐘變量 TCNT EQU 39H ;存放50ms計數(shù) HH EQU 40H ;鬧鐘設置小時變量 MM EQU 41H ;鬧鐘設置分鐘變量 SS EQU 42H ;鬧鐘設置秒鐘變量 ;程序開始 ORG 00H SJMP START ORG 0BH LJMP INT_T0 START: ;初始化 MOV R1,#1 ;用于計電機轉(zhuǎn)數(shù) MOV R3,#0 ;用于計電機轉(zhuǎn)數(shù) MOV HOUR,#0 MOV MIN,#0 MOV SEC,#0 MOV TCNT,#0 MOV TMOD,#01H MOV TH0,#3CH ;定時50毫秒 MOV TL0,#0B0H MOV IE,#82H SETB TR0 ;**************************************************** ;無窮循環(huán),判斷是否有控制鍵按下,是哪一個鍵按下 LOOP: ACALL CONV ACALL TIME_PRO ;檢查鬧鈴時間 JB K8,L12 ;開關轉(zhuǎn)換光控制 JNB K5, ZM_2 ;是否按K5,是則正轉(zhuǎn) JNB K6, FM_2 ;是否按K6,是則反轉(zhuǎn) JNB K7, STOP1 ;是否按K7,是則停止 JB K10,TJ ;是否按K10,是則調(diào)節(jié)反轉(zhuǎn) JNB K10,$ LCALL F_MTJ TJ: JB K1,M1 ACALL SET_TIME ;設置目前時間 JMP LOOP ;設置鬧鈴時間 M1:JB K2,M2 ;未按下K2,則繼續(xù)掃描 ACALL SET_ATIME ;設置鬧鈴時間 SETB ALB JMP LOOP ;跳到LOOP處執(zhí)行 M2:JB K1,M3 ;未按下K1,則繼續(xù)掃描 JMP LOOP ;跳到LOOP處執(zhí)行 M3:JB K3,M4 ;未按下K3,則繼續(xù)掃描 JMP LOOP ;跳到LOOP處執(zhí)行 M4:JMP LOOP ;跳到LOOP處執(zhí)行 L12: JNB K9,FM_3 JB K9,ZM_3 ;*********************************************** STOP: MOV P3,#0F0H ;步進電機停止工作 JMP LOOP ;開關控制步進電機正反轉(zhuǎn)程序 ZM_3:LCALL DELAY1 CJNE R3,#40, Z_M ; 檢測正轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP FM_3:LCALL DELAY1 CJNE R3,#0, F_M ; 檢測反轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP FM_2: LCALL DELAY1 ;按K6鍵消抖 JNB K6,$ ;K6是否放開 LCALL DELAY1 ;放開消抖 CJNE R3,#0, F_M ;是否反轉(zhuǎn)滿 JMP LOOP ;轉(zhuǎn)至LOOP ZM_2: LCALL DELAY1 ;按K5鍵消抖 JNB K5,$ ;K5是否放開 LCALL DELAY1 ;放開消抖 CJNE R3,#40, Z_M ; 檢測正轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP ;*********************************************** STOP1:LCALL DELAY1 ;按K7鍵消抖 JNB K7,$ ;K7是否放開 LCALL DELAY1 ;放開消抖 JMP STOP ;電機停止 ;執(zhí)行鬧鈴處理 TIME_OUT: JB K4,Z JMP F Z: ACALL ZM_3 CLR ALB LJMP LOOP F:ACALL FM_3 CLR ALB LJMP LOOP RET Z_M: MOV R0,#00H ;正轉(zhuǎn)到TABLE取碼指針初值 Z_M1: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ Z_M ;是否取到結(jié)束碼 MOV P3,A ;輸出 JNB K7,STOP1 ;若按K7鍵,停止轉(zhuǎn)動 JNB K6,FM_2 ;若按K6鍵,反轉(zhuǎn)動 LCALL CONV INC R0 ;取下一碼 INC R1 ;計數(shù) CJNE R1,#255, Z_M1 ;循環(huán) MOV R1,#00H INC R3 ;計數(shù) CJNE R3,#40, Z_M1 ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET ;反轉(zhuǎn)子程序 F_M : MOV R0,#09H ;反轉(zhuǎn)到TABLE取碼指針初值 F_M1: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ F_M ;是否取到結(jié)束碼 MOV P3,A ;輸出 JNB K7,STOP1 ;若按K7鍵,停止轉(zhuǎn)動 JNB K5,ZM_2 ;若按K6鍵,反轉(zhuǎn)動 LCALL CONV INC R0 ;取下一碼 DJNZ R1,F_M1 ;循環(huán) MOV R1,#255 DJNZ R3,F_M1 ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET ;*********************************************** ;定時器中斷服務程序,對秒,分鐘和小時的計數(shù) INT_T0: MOV TH0,#3CH ;重加載初始值 MOV TL0,#0B0H INC TCNT ;加1 MOV A,TCNT CJNE A,#20,RETUNE ;是否到了1s INC SEC MOV TCNT,#0 ;計數(shù)值清零 MOV A,SEC CJNE A,#60,RETUNE ;是否到了1min INC MIN MOV SEC,#0 MOV A,MIN CJNE A,#60,RETUNE ;是否到了1h INC HOUR MOV MIN,#0 MOV A,HOUR CJNE A,#24,RETUNE ;是否到了24h MOV HOUR,#0 MOV MIN,#0 MOV SEC,#0 MOV TCNT,#0 RETUNE: RETI ;實現(xiàn)顯示功能的子程序 CONV:MOV DPTR ,#TABLE MOV A,SEC ;顯示秒 MOV B,#10 DIV AB CLR P2.6 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.6 MOV A,B CLR P2.7 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.7 CLR P2.5 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.5 MOV A,MIN ;顯示分鐘 MOV B,#10 DIV AB CLR P2.3 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.3 MOV A,B CLR P2.4 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.4 CLR P2.2 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.2 MOV A,HOUR ;顯示小時 MOV B,#10 DIV AB CLR P2.0 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.0 MOV A,B CLR P2.1 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.1 RET TABLE: DB 3FH,06H,5BH,4FH,66H DB 6DH,7DH,07H,7FH,6FH ;*********************************************** ;實現(xiàn)調(diào)整時間子程序 ;設置目前時間 SET_TIME: CLR TR0 ;定時器暫時停止工作 MOV SEC,#0 ;秒鐘清零 L00: ACALL CONV ;掃描顯示 JNB K1,L00 L0: ACALL CONV ;掃描顯示 JMP L1 L3: JB K2,L2 ;未按下K2,則繼續(xù)掃描 JNB K2,$ ;按下,則等待放開 ; K2小時調(diào)整 INC HOUR ;小時值加1 MOV A,HOUR CJNE A,#24,L11 ;判斷是否加到24小時 MOV HOUR,#0 L11: ACALL CONV ;轉(zhuǎn)換顯示數(shù)據(jù) JMP L0 ;繼續(xù)程序執(zhí)行 L1: JB K1,L3 ;未按下K1,則繼續(xù)掃描 JNB K1,$ ;按下,則等待放開 ; K1分鐘調(diào)整 INC MIN ; 分鐘值加1 MOV A,MIN CJNE A,#60,L21 ;判斷是否加到60min MOV MIN,#0 L21: ACALL CONV ;轉(zhuǎn)換顯示數(shù)據(jù) JMP L0 ;繼續(xù)程序執(zhí)行 L2: JB K3,L0 ;未按下K3,則繼續(xù)掃描 JNB K3,$ ;按下,則等待放開 SETB TR0 ;啟動定時器 RET ;*********************************************** ;設置鬧鈴時間 SET_ATIME: N00: ACALL CONVA ; 加載鬧鈴時間數(shù)據(jù) JNB K2,N00 ;按下,則等待放開 ; K2小時調(diào)整 N0: ACALL CONVA ; 加載鬧鈴時間數(shù)據(jù) JB K2,N1 JNB K2,$ INC HH ;小時值加1 MOV A,HH CJNE A,#24,N11 ;判斷是否加到24小時 MOV HH,#0 N11: ACALL CONVA ;加載鬧鈴時間數(shù)據(jù) JMP N0 ;跳轉(zhuǎn)到N0執(zhí)行 N1: JB K1,N2 ; 未按下K1,則繼續(xù)掃描 JNB K1,$ ;按下,則等待放開 ; K1分鐘調(diào)整 INC MM ; 分鐘值加1 MOV A,MM CJNE A,#60,N21 ;判斷是否加到60min MOV MM,#0 N21: ACALL CONVA ;加載鬧鈴時間數(shù)據(jù) JMP N0 ;跳轉(zhuǎn)到N0執(zhí)行 N2: JB K3,N0 ;未按下K3,則繼續(xù)掃描 JNB K3,$ ;按下,則等待放開 ACALL CONV ;加載現(xiàn)在時間數(shù)據(jù) RET ;*********************************************** ; 加載鬧鈴時間數(shù)據(jù) CONVA: MOV DPTR,#TABLE MOV A,SS ;顯示秒 MOV B,#10 DIV AB CLR P2.6 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.6 MOV A,B CLR P2.7 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.7 CLR P2.5 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.5 MOV A,MM ;顯示分鐘 MOV B,#10 DIV AB CLR P2.3 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.3 MOV A,B CLR P2.4 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.4 CLR P2.2 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.2 MOV A,HH ;顯示小時 MOV B,#10 DIV AB CLR P2.0 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.0 MOV A,B CLR P2.1 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.1 RET ;*********************************************** ;檢查鬧鐘時間處理 TIME_PRO: JB ALB ,TI3 RET ;檢查鬧鈴是否到 TI3: MOV A,HOUR MOV B,HH CJNE A,B,BX ;檢查鬧鈴小時時間 MOV A,MIN MOV B,MM CJNE A,B,BX ;檢查鬧鈴分鐘時間 MOV A,SEC MOV B,SS CJNE A,B,BX ;檢查鬧鈴分鐘時間 ACALL TIME_OUT ;時間到,進行處理 BX: RET DELAY: MOV R6,#10 D1: MOV R7,#50 DJNZ R7,$ DJNZ R6,D1 RET DELAY1 :MOV R6,#20 ;延時20ms D2 :MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 RET TABLE1: ALB EQU 20H.0 ;鬧鈴標志位 K5 EQU P0.0 ;設定P0.0以K5表示 正 K6 EQU P0.1 ;設定P0.1以K6表示 反 K7 EQU P0.2 ;設定P0.2以K7表示 停 K8 EQU P0.3 ;設定P0.3以K8表示 轉(zhuǎn)換 K9 EQU P3.7 ;光敏信號 K10 EQU P3.6 ;復位調(diào)節(jié)鍵 K2 EQU P0.5 ;小時控制位 K1 EQU P0.4 ;分鐘控制位 K3 EQU P0.6 ;時間確認按鍵 K4 EQU P0.7 ;電機正反辨認 SEC EQU 38H ;存放秒鐘變量 MIN EQU 37H ;存放分鐘變量 HOUR EQU 36H ;存放時鐘變量 TCNT EQU 39H ;存放50ms計數(shù) HH EQU 40H ;鬧鐘設置小時變量 MM EQU 41H ;鬧鐘設置分鐘變量 SS EQU 42H ;鬧鐘設置秒鐘變量 ;程序開始 ORG 00H SJMP START ORG 0BH LJMP INT_T0 START: ;初始化 MOV R1,#1 ;用于計電機轉(zhuǎn)數(shù) MOV R3,#0 ;用于計電機轉(zhuǎn)數(shù) MOV HOUR,#0 MOV MIN,#0 MOV SEC,#0 MOV TCNT,#0 MOV TMOD,#01H MOV TH0,#3CH ;定時50毫秒 MOV TL0,#0B0H MOV IE,#82H SETB TR0 ;**************************************************** ;無窮循環(huán),判斷是否有控制鍵按下,是哪一個鍵按下 LOOP: ACALL CONV ACALL TIME_PRO ;檢查鬧鈴時間 JB K8,L12 ;開關轉(zhuǎn)換光控制 JNB K5, ZM_2 ;是否按K5,是則正轉(zhuǎn) JNB K6, FM_2 ;是否按K6,是則反轉(zhuǎn) JNB K7, STOP1 ;是否按K7,是則停止 JB K10,TJ ;是否按K10,是則調(diào)節(jié)反轉(zhuǎn) JNB K10,$ LCALL F_MTJ TJ: JB K1,M1 ACALL SET_TIME ;設置目前時間 JMP LOOP ;設置鬧鈴時間 M1:JB K2,M2 ;未按下K2,則繼續(xù)掃描 ACALL SET_ATIME ;設置鬧鈴時間 SETB ALB JMP LOOP ;跳到LOOP處執(zhí)行 M2:JB K1,M3 ;未按下K1,則繼續(xù)掃描 JMP LOOP ;跳到LOOP處執(zhí)行 M3:JB K3,M4 ;未按下K3,則繼續(xù)掃描 JMP LOOP ;跳到LOOP處執(zhí)行 M4:JMP LOOP ;跳到LOOP處執(zhí)行 L12: JNB K9,FM_3 JB K9,ZM_3 ;*********************************************** STOP: MOV P3,#0F0H ;步進電機停止工作 JMP LOOP ;開關控制步進電機正反轉(zhuǎn)程序 ZM_3:LCALL DELAY1 CJNE R3,#40, Z_M ; 檢測正轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP FM_3:LCALL DELAY1 CJNE R3,#0, F_M ; 檢測反轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP FM_2: LCALL DELAY1 ;按K6鍵消抖 JNB K6,$ ;K6是否放開 LCALL DELAY1 ;放開消抖 CJNE R3,#0, F_M ;是否反轉(zhuǎn)滿 JMP LOOP ;轉(zhuǎn)至LOOP ZM_2: LCALL DELAY1 ;按K5鍵消抖 JNB K5,$ ;K5是否放開 LCALL DELAY1 ;放開消抖 CJNE R3,#40, Z_M ; 檢測正轉(zhuǎn)是否滿 JMP LOOP ;轉(zhuǎn)至LOOP ;*********************************************** STOP1:LCALL DELAY1 ;按K7鍵消抖 JNB K7,$ ;K7是否放開 LCALL DELAY1 ;放開消抖 JMP STOP ;電機停止 ;執(zhí)行鬧鈴處理 TIME_OUT: JB K4,Z JMP F Z: ACALL ZM_3 CLR ALB LJMP LOOP F:ACALL FM_3 CLR ALB LJMP LOOP RET Z_M: MOV R0,#00H ;正轉(zhuǎn)到TABLE取碼指針初值 Z_M1: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ Z_M ;是否取到結(jié)束碼 MOV P3,A ;輸出 JNB K7,STOP1 ;若按K7鍵,停止轉(zhuǎn)動 JNB K6,FM_2 ;若按K6鍵,反轉(zhuǎn)動 LCALL CONV INC R0 ;取下一碼 INC R1 ;計數(shù) CJNE R1,#255, Z_M1 ;循環(huán) MOV R1,#00H INC R3 ;計數(shù) CJNE R3,#40, Z_M1 ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET ;反轉(zhuǎn)子程序 F_M : MOV R0,#09H ;反轉(zhuǎn)到TABLE取碼指針初值 F_M1: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ F_M ;是否取到結(jié)束碼 MOV P3,A ;輸出 JNB K7,STOP1 ;若按K7鍵,停止轉(zhuǎn)動 JNB K5,ZM_2 ;若按K6鍵,反轉(zhuǎn)動 LCALL CONV INC R0 ;取下一碼 DJNZ R1,F_M1 ;循環(huán) MOV R1,#255 DJNZ R3,F_M1 ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET ;*********************************************** ;定時器中斷服務程序,對秒,分鐘和小時的計數(shù) INT_T0: MOV TH0,#3CH ;重加載初始值 MOV TL0,#0B0H INC TCNT ;加1 MOV A,TCNT CJNE A,#20,RETUNE ;是否到了1s INC SEC MOV TCNT,#0 ;計數(shù)值清零 MOV A,SEC CJNE A,#60,RETUNE ;是否到了1min INC MIN MOV SEC,#0 MOV A,MIN CJNE A,#60,RETUNE ;是否到了1h INC HOUR MOV MIN,#0 MOV A,HOUR CJNE A,#24,RETUNE ;是否到了24h MOV HOUR,#0 MOV MIN,#0 MOV SEC,#0 MOV TCNT,#0 RETUNE: RETI ;實現(xiàn)顯示功能的子程序 CONV:MOV DPTR ,#TABLE MOV A,SEC ;顯示秒 MOV B,#10 DIV AB CLR P2.6 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.6 MOV A,B CLR P2.7 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.7 CLR P2.5 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.5 MOV A,MIN ;顯示分鐘 MOV B,#10 DIV AB CLR P2.3 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.3 MOV A,B CLR P2.4 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.4 CLR P2.2 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.2 MOV A,HOUR ;顯示小時 MOV B,#10 DIV AB CLR P2.0 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.0 MOV A,B CLR P2.1 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.1 RET TABLE: DB 3FH,06H,5BH,4FH,66H DB 6DH,7DH,07H,7FH,6FH ;*********************************************** ;實現(xiàn)調(diào)整時間子程序 ;設置目前時間 SET_TIME: CLR TR0 ;定時器暫時停止工作 MOV SEC,#0 ;秒鐘清零 L00: ACALL CONV ;掃描顯示 JNB K1,L00 L0: ACALL CONV ;掃描顯示 JMP L1 L3: JB K2,L2 ;未按下K2,則繼續(xù)掃描 JNB K2,$ LCALL DELAY ;按下,則等待放開 ; K2小時調(diào)整 INC HOUR ;小時值加1 MOV A,HOUR CJNE A,#24,L11 ;判斷是否加到24小時 MOV HOUR,#0 L11: ACALL CONV ;轉(zhuǎn)換顯示數(shù)據(jù) JMP L0 ;繼續(xù)程序執(zhí)行 L1: JB K1,L3 ;未按下K1,則繼續(xù)掃描 JNB K1,$ LCALL DELAY ;按下,則等待放開 ; K1分鐘調(diào)整 INC MIN ; 分鐘值加1 MOV A,MIN CJNE A,#60,L21 ;判斷是否加到60min MOV MIN,#0 L21: ACALL CONV ;轉(zhuǎn)換顯示數(shù)據(jù) JMP L0 ;繼續(xù)程序執(zhí)行 L2: JB K3,L0 ;未按下K3,則繼續(xù)掃描 JNB K3,$ ;按下,則等待放開 SETB TR0 ;啟動定時器 RET ;*********************************************** ;設置鬧鈴時間 SET_ATIME: N00: ACALL CONVA ; 加載鬧鈴時間數(shù)據(jù) JNB K2,N00 ;按下,則等待放開 ; K2小時調(diào)整 N0: ACALL CONVA ; 加載鬧鈴時間數(shù)據(jù) JB K2,N1 JNB K2,$ LCALL DELAY INC HH ;小時值加1 MOV A,HH CJNE A,#24,N11 ;判斷是否加到24小時 MOV HH,#0 N11: ACALL CONVA ;加載鬧鈴時間數(shù)據(jù) JMP N0 ;跳轉(zhuǎn)到N0執(zhí)行 N1: JB K1,N2 ; 未按下K1,則繼續(xù)掃描 JNB K1,$ LCALL DELAY ;按下,則等待放開 ; K1分鐘調(diào)整 INC MM ; 分鐘值加1 MOV A,MM CJNE A,#60,N21 ;判斷是否加到60min MOV MM,#0 N21: ACALL CONVA ;加載鬧鈴時間數(shù)據(jù) JMP N0 ;跳轉(zhuǎn)到N0執(zhí)行 N2: JB K3,N0 ;未按下K3,則繼續(xù)掃描 JNB K3,$ ;按下,則等待放開 ACALL CONV ;加載現(xiàn)在時間數(shù)據(jù) RET ;*********************************************** ; 加載鬧鈴時間數(shù)據(jù) CONVA: MOV DPTR,#TABLE MOV A,SS ;顯示秒 MOV B,#10 DIV AB CLR P2.6 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.6 MOV A,B CLR P2.7 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.7 CLR P2.5 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.5 MOV A,MM ;顯示分鐘 MOV B,#10 DIV AB CLR P2.3 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.3 MOV A,B CLR P2.4 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.4 CLR P2.2 MOV P1,#40H ;顯示分隔符 LCALL DELAY SETB P2.2 MOV A,HH ;顯示小時 MOV B,#10 DIV AB CLR P2.0 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.0 MOV A,B CLR P2.1 MOVC A,@A+DPTR MOV P1,A LCALL DELAY SETB P2.1 RET ;*********************************************** ;檢查鬧鐘時間處理 TIME_PRO: JB ALB ,TI3 RET ;檢查鬧鈴是否到 TI3: MOV A,HOUR MOV B,HH CJNE A,B,BX ;檢查鬧鈴小時時間 MOV A,MIN MOV B,MM CJNE A,B,BX ;檢查鬧鈴分鐘時間 MOV A,SEC MOV B,SS CJNE A,B,BX ;檢查鬧鈴分鐘時間 ACALL TIME_OUT ;時間到,進行處理 BX: RET DELAY: MOV R6,#10 D1: MOV R7,#50 DJNZ R7,$ DJNZ R6,D1 RET DELAY1 :MOV R6,#20 ;延時20ms D2 :MOV R7,#248 DJNZ R7,$ DJNZ R6,D2 RET TABLE1: DB 09H,01H,03H,02H,06H,04H,0CH,08H ;正轉(zhuǎn)表 DB 00 ;正轉(zhuǎn)結(jié)束 DB 08H,0CH,04H,06H,02H,03H,01H,09H ;反轉(zhuǎn)表 DB 00 ;反轉(zhuǎn)結(jié)束 ;反轉(zhuǎn)子程序 F_MTJ : MOV R1,#1 ;用于計電機轉(zhuǎn)數(shù) MOV R3,#0 ;用于計電機轉(zhuǎn)數(shù) F_MTJ1 : MOV R0,#09H ;反轉(zhuǎn)到TABLE取碼指針初值 F_M1TJ: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ F_MTJ1 ;是否取到結(jié)束碼 MOV P3,A ;輸出 LCALL CONV INC R0 ;取下一碼 INC R1 ;計數(shù) CJNE R1,#255, F_M1TJ ;循環(huán) MOV R1,#00H INC R3 ;計數(shù) CJNE R3,#2, F_M1TJ ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET END DB 09H,01H,03H,02H,06H,04H,0CH,08H ;正轉(zhuǎn)表 DB 00 ;正轉(zhuǎn)結(jié)束 DB 08H,0CH,04H,06H,02H,03H,01H,09H ;反轉(zhuǎn)表 DB 00 ;反轉(zhuǎn)結(jié)束 ;反轉(zhuǎn)子程序 F_MTJ : MOV R1,#1 ;用于計電機轉(zhuǎn)數(shù) MOV R3,#0 ;用于計電機轉(zhuǎn)數(shù) F_MTJ1 : MOV R0,#09H ;反轉(zhuǎn)到TABLE取碼指針初值 F_M1TJ: MOV P3,#00H MOV A,R0 MOV DPTR,#TABLE1 ;存表 MOVC A,@A+DPTR ;取表代碼 JZ F_MTJ1 ;是否取到結(jié)束碼 MOV P3,A ;輸出 LCALL CONV INC R0 ;取下一碼 INC R1 ;計數(shù) CJNE R1,#255, F_M1TJ ;循環(huán) MOV R1,#00H INC R3 ;計數(shù) CJNE R3,#2, F_M1TJ ;循環(huán) MOV P3,#0F0H ;計數(shù)滿停止工作 LJMP LOOP RET END

      單片機 匯編語言 硬件開發(fā)

      版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。

      上一篇:一篇搞定python入門基礎(一)
      下一篇:深度學習和目標檢測系列教程 1-300:什么是對象檢測和常見的8 種基礎目標檢測算法
      相關文章
      亚洲综合无码无在线观看| 久久精品国产精品亚洲艾 | 亚洲日本乱码卡2卡3卡新区| 亚洲夜夜欢A∨一区二区三区 | 日韩色日韩视频亚洲网站| 亚洲熟妇少妇任你躁在线观看| 亚洲一区精品视频在线| 亚洲精品国产福利片| 亚洲综合精品一二三区在线| 亚洲成色www久久网站夜月| 狠狠色伊人亚洲综合成人| 国产精品亚洲精品日韩已满| 亚洲精品国产精品乱码在线观看| 亚洲人成人77777网站| 亚洲日产无码中文字幕| 亚洲va中文字幕无码久久不卡| 久久亚洲高清观看| 亚洲Av熟妇高潮30p| 久久久久亚洲av无码专区喷水| 亚洲av成人无码久久精品| 久久久久亚洲Av无码专| 亚洲日韩乱码中文无码蜜桃臀| 亚洲免费视频播放| 亚洲中文无码永久免| 亚洲高清毛片一区二区| 日韩亚洲翔田千里在线| 亚洲精品国自产拍在线观看| 亚洲综合色视频在线观看| 亚洲乱色熟女一区二区三区丝袜 | 亚洲熟妇中文字幕五十中出| 国产l精品国产亚洲区在线观看| 国产成人亚洲精品青草天美| 久久亚洲私人国产精品vA | 国产精品亚洲专区无码WEB| 亚洲人AV永久一区二区三区久久| 亚洲熟妇丰满多毛XXXX| 亚洲AV一宅男色影视| 亚洲性无码av在线| 亚洲欧美国产精品专区久久| 综合一区自拍亚洲综合图区| 亚洲色偷偷狠狠综合网|