專(zhuān)注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命
提供開(kāi)發(fā)工具、應(yīng)用測(cè)試 完善的開(kāi)發(fā)代碼案例庫(kù)分享
從全面的產(chǎn)品導(dǎo)入到強(qiáng)大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無(wú)限潛能!
提供新的芯片及解決方案,提升客戶(hù)產(chǎn)品競(jìng)爭(zhēng)力
提供最新的單片機(jī)資訊,行業(yè)消息以及公司新聞動(dòng)態(tài)
《簡(jiǎn)易四路搶答器》
;該搶答器供不多于4個(gè)參賽隊(duì)或者個(gè)人的搶答比賽場(chǎng)合使用。每個(gè)參賽隊(duì)的座位前
;安裝1只搶答按鈕開(kāi)關(guān)(用板上的S9、S10、S11、S12)和一個(gè)信號(hào)燈(D4、D5、D6、D7)。
;主持人座位前裝一只復(fù)原開(kāi)關(guān)(板上S3)、1只蜂鳴器(板上BUZ1)和一個(gè)搶答器工作狀態(tài)
;指示燈(D10),每當(dāng)主持人口頭發(fā)出號(hào)令之后.哪個(gè)隊(duì)先按下座位上的按鈕開(kāi)關(guān),該座位的信
;號(hào)燈就先被點(diǎn)亮,同時(shí)封鎖其他按鈕開(kāi)關(guān)的活動(dòng).并且熄滅主持人座位上的狀態(tài)指示燈和發(fā)出
;三聲類(lèi)似于電話振鈴的提示聲,以聲明此次搶答動(dòng)作已經(jīng)完成.在主持人確認(rèn)后,按下復(fù)原按鈕
;,狀態(tài)指示燈重新點(diǎn)亮,并且同時(shí)發(fā)出"笛-笛-"聲,為下一次搶答作好準(zhǔn)備.
;程序文件名:"MCD-INTBUZ.ASM"
;*********************************************************************
;程序清單
;*********************************************************************
tmr0 equ 1h ;定義定時(shí)器/計(jì)數(shù)器0寄存器地址
status equ 3h ;定義狀態(tài)寄存器地址
option_reg equ 81h ;定義選項(xiàng)寄存器地址
option_temp equ 0a6h ;(在BACK1)定義選項(xiàng)寄存器的備份寄存器的地址
intcon equ 0bh ;定義中斷控制寄存器地址
portc equ 7h ;定義端口RC的數(shù)據(jù)寄存器地址
trisc equ 87h ;定義端口RC的方向控制寄存器地址
portb equ 06h ;定義端口RB的數(shù)據(jù)寄存器地址
trisb equ 86h ;定義端口RB的方向控制寄存器地址
c equ 0 ;定義進(jìn)位標(biāo)志位的位地址
z equ 2 ;定義0標(biāo)志位的位地址
w equ 0 ;定義傳送目標(biāo)寄存器為W的指示位
f equ 1 ;定義傳送目標(biāo)寄存器為RAM的指示位
t0if equ 2 ;定義TMR0中斷標(biāo)志位的位地址
t0ie equ 5 ;定義TMR0中斷使能位的位地址
inte equ 4 ;定義外部中斷使能位的位地址
intf equ 1 ;定義外部中斷標(biāo)志位的位地址
count equ 20h ;定義一個(gè)計(jì)數(shù)器變量
count1 equ 24h ;定義一個(gè)計(jì)數(shù)器變量
count2 equ 25h ;定義一個(gè)計(jì)數(shù)器變量
count3 equ 27h ;定義一個(gè)計(jì)數(shù)器變量
count4 equ 28h ;定義一個(gè)計(jì)數(shù)器變量
portb_b equ 21h ;為PORTC定義一個(gè)備份寄存器
w_temp equ 7fh ;為W在體0和體1定義2個(gè)備份寄存器
;w_temp equ 0ffh ;(若是16F873/4,則需保留FFH單元)
status_temp equ 23h ;為STATUS定義一個(gè)備份寄存器
rp0 equ 5h ;定義狀態(tài)寄存器中的頁(yè)選位RP0
;******************復(fù)位向量和中斷向量***********************
org 000h ;
nop ;設(shè)置一條ICD必須的空操作指令
goto main ;
org 0004h ;
goto serv ;跳轉(zhuǎn)到中斷服務(wù)子程序
;*******************主程序************************************
main
bsf status,rp0 ;
movlw 0 ;
movwf trisc ;設(shè)置RC口全部為輸出
movlw 0ffh ;
movwf trisb ;設(shè)置RB口全部為輸入
movlw 02h ;設(shè)置選項(xiàng)寄存器:上拉電阻啟用;INT下降沿觸發(fā)
movwf option_reg ;分頻器給TMR0;分頻比1:8
bcf status,rp0 ;
movlw 90h ;
movwf intcon ;開(kāi)發(fā)INT中斷
clrf portc ;RC口燈全滅
loop
movf portb,w ;讀取RB口數(shù)據(jù)
iorlw b'11100001' ;送RB口的數(shù)到備份寄存器并將除S9、S10、S11、S12以外的位全部送1
movwf portb_b ;
xorlw 0ffh ;沒(méi)有鍵按下轉(zhuǎn)LOOP繼續(xù)檢測(cè)
btfsc status,z ;
goto loop ;
call delay10ms ;防抖動(dòng)廷時(shí)
movf portb,w ;
iorlw b'11100001' ;
xorwf portb_b,0 ;再次讀取RB口的數(shù)據(jù),與前一次讀的數(shù)相同則鍵值有效
btfsc status,z ;
goto loop ;
comf portb_b,w ;取反以便使被按下按鍵的位為1,其它位為0
movwf portc ;送RC口顯示
call tone3t ;調(diào)用發(fā)聲三次子程序
loop1
comf portb,w ;檢測(cè)按鍵是否有松開(kāi)
andlw b'00011110' ;
btfsc status,z ;
goto loop ;松開(kāi)了返回
goto loop1 ;沒(méi)松開(kāi)繼續(xù)檢測(cè)
;*********************中斷服務(wù)子程序*****************************
serv
;********************保存護(hù)現(xiàn)場(chǎng)部分*******************************
movwf w_temp ;保護(hù)W
swapf status,w ;保護(hù)STATUS
clrf status ;選擇體0
movwf status_temp ;將STATUS存入體0的備份寄存器
;********************* 調(diào)查中斷源**********************************
btfsc intcon,intf ;檢查不是INT中斷,返回
goto intserv ;是!轉(zhuǎn)到INT中斷處理部分
goto retfie0 ;
;*********************INT中斷處理部分******************************
intserv
clrf portc ;令全部燈熄滅
bsf portc,7 ;點(diǎn)亮D10,表示就緒
call tone630 ;調(diào)用高音子程序
call delay ;調(diào)用1S廷時(shí)子程序
call tone630 ;調(diào)用低音子程序
bcf intcon,intf ;清除INT中斷標(biāo)志位
;*************************恢復(fù)現(xiàn)場(chǎng)部分*****************************
retfie0
swapf status_temp,w ;恢復(fù)STATUS
movwf status ;
swapf w_temp,f ;恢復(fù)W
swapf w_temp,w ;
retfie ;中斷返加
;*************************低音調(diào)發(fā)生子程序(500HZ/50MS)*************
tone500
movlw .50 ;循環(huán)次數(shù)寄存器賦初值
movwf count ;50=500HZx0.05Sx2
t5lop
bcf intcon,t0if ;清除TRM0溢出中斷標(biāo)志位
movlw .131 ;給TMR0裝入初值256-125=131
movwf tmr0 ;啟動(dòng)定時(shí)器
t5here
btfss intcon,t0if ;定時(shí)器溢出否
goto t5here ;否!循環(huán)栓測(cè)
movlw b'01000000' ;只將BIT6置位
xorwf portc,f ;只將RC6(BUZ)腳電平反轉(zhuǎn),其余不變
decfsz count,f ;循環(huán)次數(shù)遞減,為0,跳一步
goto t5lop ;不為0,跳回
return ;返回
;**************************高音調(diào)發(fā)生子程序(630HZ/50MS)*****************
tone630
movlw .63 ;循環(huán)次數(shù)寄存器賦初值
movwf count1 ;63=630HZx0.05Sx2
t6lop
bcf intcon,t0if ;清除TRM0溢出中斷標(biāo)志位
movlw .157 ;給TMR0裝入初值157=256-99
movwf tmr0 ;啟動(dòng)定時(shí)器
t6here
btfss intcon,t0if ;定時(shí)器溢出否
goto t6here ;否!循環(huán)栓測(cè)
movlw b'01000000' ;只將BIT6置位
xorwf portc,f ;只將RC6(BUZ)腳電平反轉(zhuǎn),其余不變
decfsz count1,f ;循環(huán)次數(shù)遞減,為0,跳一步
goto t6lop ;不為0,跳回
return ;返回
;*********************發(fā)聲1S子程序(1S=10x(50ms+50ms)***********
tonels
movlw .10 ;循環(huán)次數(shù)寄存器賦初值
movwf count2 ;
t1lop
call tone500 ;調(diào)用低音子程序
call tone630 ;調(diào)用高音子程序
decfsz count2,f ;循環(huán)次數(shù)遞減,為0,跳一步
goto t1lop ;不為0,跳回
return ;返回
;*********************TMR0廷時(shí)子程序1S(1S=16x256x(256-12)US)********
delay
bsf status,rp0 ;設(shè)置文件寄存器體1
movf option_reg,w ;保護(hù)選項(xiàng)寄存器內(nèi)容
movwf option_temp ;
movlw 07h ;重設(shè)選項(xiàng)寄存器;上拉電阻啟用,INT下降沿觸發(fā)
movwf option_reg ;分頻器給TRM0;分頻比值設(shè)為1:256
bcf status,rp0 ;恢復(fù)到文件寄存器體0
movlw .16 ;循環(huán)利用TMROP定時(shí)16次
movwf count3 ;溢出次數(shù)寄存器
d1lop
bcf intcon,t0if ;清除TMR0溢出中斷標(biāo)志位
bcf intcon,t0ie ;清除TMR0溢出中斷使能位
movlw .12 ;給TMR0裝入初值12=256-244
movwf tmr0 ;啟動(dòng)定時(shí)器
here
btfss intcon,t0if ;用查詢(xún)法檢測(cè)TMR0溢出否
goto here ;否!返回
decfsz count3,f ;是!溢出次數(shù)減1,為0,跳一步
goto d1lop ;否!循環(huán)利用TMR0
bsf status,rp0 ;設(shè)置文件寄存器體1
movf option_temp,w ;恢復(fù)選項(xiàng)寄存器內(nèi)容
movwf option_reg ;
bcf status,rp0 ;恢復(fù)到文件寄存器體0
return ;返回
;*************************斷續(xù)發(fā)聲3次報(bào)警子程序***********************
tone3t
movlw .3 ;循環(huán)次數(shù)寄存器賦初值
movwf count4 ;
t3lop
call tonels ;調(diào)用發(fā)聲1S子程序
call delay ;調(diào)用廷時(shí)1S子程序
decfsz count4,f ;循環(huán)次數(shù)遞減,為0,跳一步
goto t3lop ;不為0,跳回
return ;返回
;**************************軟件廷時(shí)10MS子程序****************************
delay10ms
movlw .13 ;將外層循環(huán)參數(shù)值送到30H
movwf 30h ;
lp0
movlw 0ffh ;將內(nèi)層循環(huán)參數(shù)值送到31H
movwf 31h ;
lp1
decfsz 31h,1 ;變量31H內(nèi)容遞減,若為0則跳躍
goto lp1 ;跳轉(zhuǎn)到LP1
decfsz 30h,1 ;變量30H內(nèi)容遞減,若為0則跳躍
goto lp0 ;跳轉(zhuǎn)到LP0
return ;返回主程序
end ;源程序結(jié)束
;***************************************************
; 進(jìn)入該實(shí)戰(zhàn)演練的工序流程如下:
; 1.創(chuàng)建源文件和編輯源文件;在此介紹一種不同于前面講的創(chuàng)建源文件的方法,用Windows附件中的”記事本”
; 這個(gè)為大家所熟知和好用的文件編輯器,并且可以方便的加入中文注釋.不過(guò)有兩點(diǎn)需要注意,一是注釋前面的
; 分號(hào)”;”必須用西文半角輸入;二是必須用”.asm”擴(kuò)展名存儲(chǔ)到事先建立的一個(gè)專(zhuān)用子目錄下.
; 2.打開(kāi)MPLAB集成開(kāi)發(fā)環(huán)境:首先在WINDOWS環(huán)境下,選用開(kāi)始>程序>Microchip MPLAB>MPLAB命令,啟動(dòng)MPLAB
; 并進(jìn)入MPLAB的桌面.
; 3.創(chuàng)建項(xiàng)目:選用菜單File>New或Project>New Project,在事先建立的一個(gè)專(zhuān)用子目錄下創(chuàng)建一個(gè)新項(xiàng)目,將
; 用記事本創(chuàng)建的源文件加入到該項(xiàng)目中.
; 4.建立項(xiàng)目中的目標(biāo)文件:選擇菜單Project >Build All(項(xiàng)目>建立所有文件),MPLAB將自動(dòng)調(diào)用MPASM將項(xiàng)目
; 文件管理下的源文件(.asm)匯編成十六進(jìn)制的目標(biāo)文件(.hex).
; 5.ICD參數(shù)設(shè)置:通過(guò)菜單命令Project>Edit Project或者Option>Development Mode,將開(kāi)發(fā)模式設(shè)置為
; ”MPLAB ICD Debugger”,點(diǎn)擊OK按鈕,打開(kāi)ICD的工作窗口,在調(diào)試階段,可以按照說(shuō)明書(shū)圖2-10設(shè)置各項(xiàng),但需注意
; OSCILLATOR應(yīng)設(shè)置為XT方式,尤其需要說(shuō)明的是,選中“Enable Debug Mode”(使能調(diào)試模式)選項(xiàng),在向目
; 標(biāo)單片機(jī)燒寫(xiě)機(jī)器碼程序時(shí),會(huì)將調(diào)試臨控程序同時(shí)寫(xiě)入單片機(jī)的指定程序存儲(chǔ)器區(qū)域,然后才允許用ICD方式調(diào)試。
; 6.電路設(shè)置:將演示板的S1全部拔到ON,S4全部拔到OFF,S13的第1、第5拔到ON,第6、第7拔到OFF ,LCD不要插在演示板上,
; 以使端口C只與8只發(fā)光二極管接通;將用于選擇頻率的插針跳線插到”XT OSC”位置上,板上93CXX、24CXX應(yīng)拿下。
; 7.向目標(biāo)單片機(jī)燒寫(xiě)目標(biāo)程序:用戶(hù)在點(diǎn)擊功能按鈕”Program”向目標(biāo)單片機(jī)燒寫(xiě)機(jī)器碼程序時(shí),會(huì)等待一段時(shí)間,
; 并且在條狀的狀態(tài)信息欄中,出現(xiàn)提示信息。有一點(diǎn)需要引起注意,就是PIC16F87X單片機(jī)的FLASH程序存儲(chǔ)器的擦寫(xiě)
; 周期是有限的,大約為1000次,應(yīng)盡量節(jié)省它的使用壽命。
; 8.運(yùn)行和調(diào)試用戶(hù)程序和用戶(hù)電路:在各項(xiàng)參數(shù)設(shè)置好后,將ICD的工作窗口最小化,利用前面講的”運(yùn)行及調(diào)試”中介
; 紹的幾種方法進(jìn)行調(diào)試.當(dāng)用自動(dòng)單步方式調(diào)試時(shí),建議臨時(shí)禁止廷時(shí)子程序發(fā)揮作用,具體的方法是,可在CALL DELAY指
; 令前添加一個(gè)分號(hào),并且重新匯編一次.為了學(xué)習(xí)目的,在調(diào)試過(guò)程中可以人為地加入一些軟件漏洞(BUG)或硬件故障,來(lái)模
; 仿單片機(jī)端口引腳的片內(nèi)或片外故障.
; 9.定型燒寫(xiě)目標(biāo)單片機(jī);經(jīng)過(guò)多次重復(fù)上述步驟的反復(fù)修改和調(diào)試,使得程序和電路在聯(lián)機(jī)狀態(tài)完全正常,這時(shí)可以進(jìn)行
; 定型燒寫(xiě),即將ICD窗口中的”Enable Debug Mode”(使能調(diào)試模式)選項(xiàng)消除,不再將調(diào)試臨控程序?qū)懭雴纹瑱C(jī)中.
; 10.獨(dú)立運(yùn)行驗(yàn)收:上一步中的燒寫(xiě)過(guò)程完成后,即可將ICD模塊和ICD仿真頭(或演示板)之間的6芯電纜斷開(kāi),讓單片機(jī)在
; 演示板獨(dú)立運(yùn)行,觀察實(shí)際效果.
;
;