?? ver30.asm
字號:
;用一片PIC16F877A控制上下兩個電機運轉(zhuǎn)程序(回轉(zhuǎn)雙重定位法)(用于滾動廣告燈箱)2005/11/29
;注:直流無刷電機采用有位置傳感器的12v直流無刷電機,齒輪箱速比38.4,用上電機對脈沖計數(shù)
;數(shù)據(jù)保存在BANK0和BANK1中,使系統(tǒng)可以保存18幅廣告畫參數(shù)的能力,每幅畫的停留時間可以不同
;上電機有機械剎車.
;要求每當(dāng)狀態(tài)改變時就保存一次數(shù)據(jù)
;用另外一組PULSE進(jìn)行計數(shù)
;電機轉(zhuǎn)速固定運轉(zhuǎn)
;采用多機聯(lián)動,即一個廣告畫運行時其他廣告畫一起運轉(zhuǎn)
list p=16f877A
#include "p16f877a.inc"
;Define variable storage
cblock 0x20
upmotoradc ;up motor pwm threshold(20)
downmotoradc ;down motor pwm threshold(21)
adcvoltage
turnonvoltagereg ;繼電器吸合電壓
turnoffvoltagereg ;繼電器斷開電壓
lastupsensor ;last read up motor sensor data
lastdownsensor ;last read down motor sensor data
lastsensortemp
updriveword ;six bit motor drive data
downdriveword
bottomhig
bottommed
bottomlow
count2 ;延時計數(shù)器
count3
beepcount ;蜂鳴器計數(shù)
count4 ;數(shù)據(jù)保存?zhèn)€數(shù)
delay10scount1
delay10scount2
timer2ifcount ;timer2 interrupt flag count
voltagecompare ;電壓比較值
remotetemp ;遙控器輸入暫存
sensortemp ;HALL輸入暫存
storedatacountreg ;需要保存數(shù)據(jù)的個數(shù)
stoptimereg ;停留時間寄存器
;以下為需要保存的數(shù)據(jù)
flag ;flag for motor status(00)
flag1 ;(01)
flag2 ;(02)
flag3 ;錯誤標(biāo)志
count5 ;(03)
delaytemp ;延時數(shù)據(jù)
alldelaytemp
sametimespeedreg
setspeedreg ;電機設(shè)置速度寄存器(05)
uplowspeedreg
upsametimelowspeedreg
downlowspeedreg
downsametimelowspeedreg
pulsehig ;脈沖計數(shù)寄存器;(0c)
pulsemed ;(0d)
pulselow ;(0e)
pulsehig1 ;脈沖計數(shù)1
pulsemed1
pulselow1
tophigmax ;上限位置
topmedmax
toplowmax
tophig ;上限位置寄存器(0f)
topmed ;(10)
toplow ;(11)
lowspeedhig ;(12)
lowspeedmed ;(13)
lowspeedlow ;(14)
datamed1 ;第一次經(jīng)過校正位置時的脈沖數(shù)(15)
datalow1 ;(16)
datamed2 ;第二次經(jīng)過校正位置時的脈沖數(shù)(17)
datalow2 ;(18)
topdatacountreg ;上限數(shù)據(jù)個數(shù)(19)
advcount ;廣告畫數(shù)(1a)
advcounttemp ;廣告畫數(shù)暫存(1b)
topcount ;上限位置次數(shù)(1c)
endc
topstart equ 0a0h ;數(shù)據(jù)保存開始位置
;以上為需要保存的數(shù)據(jù)
;define i/o
;常數(shù)
#define speeddatalow d'0' ;電機低速運轉(zhuǎn)的距離
#define speeddatamed d'3'
#define settimespeedadc d'255' ;設(shè)定參數(shù)時電機的轉(zhuǎn)速初始值
#define settimespeedadcmax d'255' ;設(shè)定參數(shù)時電機的轉(zhuǎn)速最大值
#define settimespeedadcmin d'255' ;設(shè)定參數(shù)時電機的轉(zhuǎn)速最小值
#define uplowspeedadc d'220'
#define uplowspeedadcmax d'220'
#define uplowspeedadcmin d'220'
#define downlowspeedadc d'220'
#define downlowspeedadcmax d'220'
#define downlowspeedadcmin d'220'
#define uphighspeedadc d'255' ;電機高速運轉(zhuǎn)時的轉(zhuǎn)速初始值
#define downhighspeedadc d'255' ;電機高速運轉(zhuǎn)時的轉(zhuǎn)速初始值
#define upsametimehighspeedadc d'190' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define upsametimelowspeedadc d'140' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define upsametimelowspeedadcmax d'180' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define upsametimelowspeedadcmin d'100' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define downsametimehighspeedadc d'190' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define downsametimelowspeedadc d'140' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define downsametimelowspeedadcmax d'180' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define downsametimelowspeedadcmin d'100' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define sametimespeedadc d'180' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define sametimespeedadcmax d'200' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define sametimespeedadcmin d'30' ;電機同時運轉(zhuǎn)時轉(zhuǎn)速的初始值
#define updirupstartadc d'0' ;初始ADC值
#define updirdownstartadc d'80'
#define downdirupstartadc d'80'
#define downdirdownstartadc d'0'
#define downdirdownaccadc d'8' ;加速度
#define downdirupaccadc d'8'
#define updirdownaccadc d'8'
#define updirupaccadc d'8'
#define bottommin d'230' ;pulse1起始值
#define bottomcompare d'115' ;pulse1下端比較值,小于該值表面畫布可能下拉
#define delttop d'115' ;pulse1上限位置最多可以的值
#define deltturnoffvoltage 0ah ;電壓比較值(22DCV)(2.65v以下為7bh,2.65v以上為80h)6b
#define deltturnonvoltage 8h ;電壓比較值(22.5V)(2.65v以下為7dh,2.65v以上為82h)6d
#define cannotrunvoltage 60h ;低于該電壓值時電機不能運轉(zhuǎn)
#define advcountmax d'18' ;最多的廣告畫數(shù)
;#define storedatacount d'80' ;需要保存到EEPROM中的數(shù)據(jù)個數(shù)
#define delaytempstart d'6' ;10S延時初始值
#define delaytempmax d'250' ;最大值
#define delaytempmin d'3' ;最小值
#define beephightonecount d'250' ;高音次數(shù)
#define beeplowtonecount d'15' ;低音次數(shù)
#define brakecontrol porte,0 ;控制電機剎車
#define beepcontrol porte,1 ;控制蜂鳴器發(fā)聲
#define relaycontrol porte,2 ;電瓶繼電器控制
#define remotemask b'00001111' ;遙控數(shù)據(jù)提取屏蔽
#define remote portc ;遙控數(shù)據(jù)輸入
#define enableupmotor portc,4 ;控制上電機運轉(zhuǎn)
#define enabledownmotor portc,5 ;控制下電機運轉(zhuǎn)
#define startpulsesignal portc,6 ;開始脈沖信號
#define directionsignal portc,7 ;方向信號
#define offmask b'00010101' ;直流無刷電機輸出屏蔽
#define driveport portd ;驅(qū)動口
#define driveporttris trisd
#define upsensormask b'00000111' ;上電機霍爾元件信號輸入屏蔽
#define downsensormask b'00111000' ;下電機霍爾元件信號輸入屏蔽
#define sensorport portb ;直流無刷電機霍爾元件信號輸入
#define startpulseinput portb,6
#define directioninput portb,7
;設(shè)置狀態(tài)時按鍵分配
#define increasekey d'8' ;增加狀態(tài)(1)
#define decreasekey d'4' ;減小狀態(tài)(2)
#define updownkey d'12' ;上升下降(3)
#define modetorunkey d'14' ;設(shè)置狀態(tài)TO運行狀態(tài)(7)
#define zerokey d'2' ;置0(4)
#define storekey d'10' ;保存一副廣告畫參數(shù)(5)
#define setspeedkey d'6' ;電機設(shè)置轉(zhuǎn)速(6)
#define sametimespeedkey d'1' ;同時運轉(zhuǎn)轉(zhuǎn)速
;運行狀態(tài)時按鍵分配
#define runtomodekey d'12' ;運行狀態(tài)TO設(shè)置狀態(tài)(3)
#define stopandrunkey d'10' ;停止 運行(5)
#define stoptimekey d'2' ;停頓時間(4)
#define allstoptimekey d'6' ;改變所有的停止時間(6)
#define allstoptime3key d'14' ;使所有時間為10秒(7)
#define defaultspeedkey d'1' ;使轉(zhuǎn)速為缺省值(8)
;電機運行時按2鍵停止后按鍵分配
#define highspeedkey d'12' ;增加高速運轉(zhuǎn)轉(zhuǎn)速(3)
#define medspeedkey d'2' ;減小高速轉(zhuǎn)速(4)
#define lowspeedkey d'10' ;增加低速運轉(zhuǎn)轉(zhuǎn)速(5)
#define stoptime1minkey d'6' ;停留時間1min(6)
#define stoptime5minkey d'14' ;停留5MIN(7)
#define stoptime10minkey d'1' ;停留10min(8)
#define directionbit flag,0 ;direction bit is flag register bit 0
#define stopflag flag,1 ;中間位置停止標(biāo)志
#define voltagelowflag flag,2 ;電壓低標(biāo)志
#define starttime flag,3 ;電機在啟動時間
#define storeflag flag,4 ;是否已保存數(shù)據(jù)
#define ebrakeflag flag,5 ;電機電剎車
#define lowspeedflag flag,6 ;低速運行標(biāo)志
#define positionflag flag1,0
#define store1flag flag1,1
#define store2flag flag1,2
#define secondcount flag1,3
#define topflag flag1,4 ;上電機運轉(zhuǎn)結(jié)束
#define bottomflag flag1,5 ;下電機運轉(zhuǎn)結(jié)束
#define topsetflag flag1,6 ;上端設(shè)置按鈕已按
#define runmodeflag flag1,7 ;模式狀態(tài)標(biāo)志
#define needupsensorflag flag2,0 ;需要上電機HALL信號輸入標(biāo)志
#define needpulsecountflag flag2,1 ;需要計數(shù)標(biāo)志
#define updirectionflag flag2,2 ;上升狀態(tài)標(biāo)志
#define downdirectionflag flag2,3 ;下降狀態(tài)標(biāo)志
#define addpulsecountflag flag2,4 ;需要脈沖加計數(shù)
#define notrunvoltagestopflag flag2,5 ;不能運行電壓時電機停止標(biāo)志
#define defaultflag flag2,6 ;缺省標(biāo)志
#define changeparameterflag flag2,7 ;改變參數(shù)標(biāo)志
#define toperrorflag flag3,0 ;上限位置超標(biāo)志
#define bottomerrorflag flag3,1 ;下限位置超標(biāo)志
#define lockerrorflag flag3,2 ;發(fā)生堵轉(zhuǎn)錯誤
#define mainflag flag3,3 ;該控制器是否為主控制器
#define finishflag flag3,4 ;一幅畫是否正常運轉(zhuǎn)完成
#define voltagetest porta,0 ;電壓檢測
#define overcurrent porta,1 ;過流檢測
#define position porta,2 ;位置校正輸入
#define systemerror porta,3 ;系統(tǒng)發(fā)生錯誤
#define direction porta,5 ;方向控制
#define mode porta,4 ;模式控制
org 0x000 ;startup vector
clrf pclath ;ensure page bits are cleared
goto initialize ;go to the begin of program
org 0x004 ;interrupt vector location
retfie
;**************
;主程序
;**************
initialize
clrf bottomhig ;下限位置清零
clrf bottommed
movlw d'10'
movwf bottomlow
clrf timer2ifcount
movlw b'00010101'
movwf driveport
banksel trisa ;select bank of trisa
;setup i/o
movlw b'00001111'
movwf trisc ;0-3輸入,4-7輸出
banksel portc
bsf startpulsesignal
bsf directionsignal
bcf enableupmotor
bcf enabledownmotor
banksel trisa
clrf driveporttris ;set motor drivers as outputs
movlw b'00110111' ;a/d on ra0
movwf trisa
movlw b'11111111'
movwf trisb ;輸入
movlw b'00000000'
movwf trise ;0-2輸出
;setup timer0
movlw b'01010000' ;timer0,1:2,portb 弱上拉,
movwf option_reg
;setup adc (bank1)
movlw b'00001110' ;adc left justified,an0 only
movwf adcon1
banksel adcon0
;setup adc(bank0)
movlw b'11000001' ;adc clock from int rc,an0,adc on
movwf adcon0
;bsf adcon0,go ;start adc
movlw b'01111111' ;timer2的prescale為1:16,后分頻比為1:16,on,
movwf t2con ;用于判斷電機是否堵轉(zhuǎn)
clrf lastdownsensor ;initialize last sensor reading
clrf lastupsensor
bcf relaycontrol ;接通蓄電池
bsf brakecontrol ;剎車起作用
bcf beepcontrol
bcf status,irp ;間接尋址BANK0,1
call readdatasub ;讀取上次保存的數(shù)據(jù)
bcf mainflag ;先假定它為副控制器
call mainchecksub ;判斷是否為主控制器
;movlw 0ffh ;eeprom中速度數(shù)據(jù)是否為FFH
;subwf setspeedreg,w
;btfss status,z
;goto oversetspeedbran ;不是則跳過速度設(shè)置
;bcf lockerrorflag
movlw settimespeedadc ;是則設(shè)置缺省速度
movwf setspeedreg
movlw uplowspeedadc
movwf uplowspeedreg
movlw downlowspeedadc
movwf downlowspeedreg
movlw sametimespeedadc
movwf sametimespeedreg
movlw upsametimelowspeedadc
movwf upsametimelowspeedreg
movlw downsametimelowspeedadc
movwf downsametimelowspeedreg
oversetspeedbran
bcf voltagelowflag
bcf systemerror ;系統(tǒng)沒有錯誤
;設(shè)置電機初始狀態(tài)
bsf pclath,3h
call motornotrunsub
bcf pclath,3h
btfsc lockerrorflag ;電機是否發(fā)生過堵轉(zhuǎn)
call lockerrorhowtodosub
call delaysub
call delaysub
call delaysub
call motorlocksub ;電機電剎車起作用
call calculatevoltagesub ;計算繼電器吸合斷開電壓
mainloop
call checkhallinputsub ;檢查HALL輸入
btfsc mode ;是否處于模式設(shè)置狀態(tài)?
goto modeset ;是則調(diào)用MODEset
goto normalrunstart1 ;不是則到正常運轉(zhuǎn)
modeset
bcf runmodeflag ;處于設(shè)置參數(shù)狀態(tài)
bcf storeflag
modesetbranch
movlw remotemask
andwf remote,w ;讀取遙控器輸入數(shù)據(jù)
movwf remotetemp
movlw increasekey ;是否為increasekey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call increasekeysub ;=0則調(diào)用increasekeysub
movlw decreasekey ;是否為decreasekey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call decreasekeysub ;=0則調(diào)用decreasekeysub
movlw updownkey ;是否為updown按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call updownkeysub ;=0則調(diào)用updownkeysub
movlw modetorunkey ;是否為modetorunkey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call modetorunkeysub ;=0則調(diào)用modetorunkeysub
movlw zerokey ;是否為zerokey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call zerokeysub ;=0則調(diào)用zerokeysub
movlw storekey ;是否為storekey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call storekeysub ;=0則調(diào)用storekeysub
movlw setspeedkey ;是否為setspeedkey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call setspeedkeysub ;=0則調(diào)用
movlw sametimespeedkey ;是否為sametimespeedkey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call sametimespeedkeysub ;=0則調(diào)用sametimespeedkeysub
call cannotrunvoltagesub ;電壓是否低于規(guī)定值
btfsc runmodeflag ;是否仍處于參數(shù)設(shè)置狀態(tài)
goto normalrunstart ;不是則轉(zhuǎn)到normalrunstart
btfss mode ;是否為狀態(tài)設(shè)置?
goto normalrunstart ;不是則正常運轉(zhuǎn)
goto modesetbranch
;正常運行開始
normalrunstart
bsf finishflag
btfsc mode
goto modeset
btfss runmodeflag
goto modesetbranch
call writedatasub ;保存數(shù)據(jù)
normalrunstart1
btfsc toperrorflag ;是否發(fā)生上限位置超錯誤
call toperrorhowtodosub
btfsc bottomerrorflag ;是否發(fā)生下限位置超錯誤
call bottomerrorhowtodosub
call threelowtonesub ;低音
call delaysub
call delaysub
call delaysub
call threehightonesub ;高音
btfsc topflag
goto downnormalrunstart
btfsc bottomflag
goto upnormalrunstart
btfsc updirectionflag
goto upnormalrun
btfsc downdirectionflag
goto downnormalrun
goto mainloop
upnormalrunstart ;上升開始
;call readdatasub ;數(shù)據(jù)重新讀取
movf advcount,w
movwf advcounttemp ;廣告畫數(shù)
;clrf topcount ;第一副畫開始
movlw d'0'
movwf topcount
movf bottomlow,w ;是則置0
movwf pulselow
movf bottommed,w
movwf pulsemed
movf bottomhig,w
movwf pulsehig
clrf count5
bcf bottomflag ;不再處于下端位置
bsf updirectionflag ;處于上升狀態(tài)
upnormalrun1
upnormalrun
btfsc stopflag
goto waitupstartrun1
btfsc notrunvoltagestopflag
goto upcall1 ;如由于停電引起則upcall
btfsc mainflag
goto continueupbranch ;為主控制器則直接運轉(zhuǎn)
btfss finishflag ;一幅畫已完成?
goto continueupbranch ;沒有完成則應(yīng)完成該幅畫
upcheckinput
btfsc mode
goto modeset ;處于參數(shù)設(shè)置狀態(tài)
call voltagecomparesub ;比較電壓低于規(guī)定值則斷開蓄電池并保存數(shù)據(jù)
btfsc startpulseinput ;檢測有沒有負(fù)脈沖發(fā)生
goto upcheckinput
call delaysub
call delaysub
btfsc startpulseinput
goto upcheckinput
btfss directioninput ;是否向上運行
goto upcheckinput ;不是則等待向上運
continueupbranch
incf topcount,f ;指向下一組地址
call getdatafromramsub ;從RAM中提取數(shù)據(jù)
call subspeeddatalowsub ;計算需要減速的位置
goto upcall
upcall1
bcf notrunvoltagestopflag
goto upcall
upcall2
bcf stopflag
upcall
bcf storeflag
call writedatasub
bsf pclath,3h
call upsub ;電機上升
bcf pclath,3h
btfss stopflag
goto upnormalrunbranch1 ;如沒有按停止鍵則繼續(xù)往復(fù)運轉(zhuǎn)
waitupstartrun1
btfsc lockerrorflag ;是否發(fā)生堵轉(zhuǎn)錯誤
call lockerrorhowtodosub
btfsc toperrorflag ;上限位置超?
call toperrorhowtodosub
;goto upcall2
;如按下停止鍵則等待按下開始運行鍵
waitupstartrun
movlw remotemask
andwf remote,w ;讀取遙控器輸入數(shù)據(jù)
movwf remotetemp
movlw increasekey ;是否為increasekey按鈕
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
goto upcall2
call presschangespeedkeysub ;是否按下速度變化鍵
;call writedatasub ;保存數(shù)據(jù)
call cannotrunvoltagesub ;電壓低于規(guī)定值則關(guān)閉電源
btfsc mode
goto modeset ;處于參數(shù)設(shè)置狀態(tài)
goto waitupstartrun
upnormalrunbranch1
decfsz advcounttemp,f
goto updelay10sbranch
bsf topflag ;處于最上端位置
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -