📄 ver30.asm
字号:
;用一片PIC16F877A控制上下两个电机运转程序(回转双重定位法)(用于滚动广告灯箱)2005/11/29
;注:直流无刷电机采用有位置传感器的12v直流无刷电机,齿轮箱速比38.4,用上电机对脉冲计数
;数据保存在BANK0和BANK1中,使系统可以保存18幅广告画参数的能力,每幅画的停留时间可以不同
;上电机有机械刹车.
;要求每当状态改变时就保存一次数据
;用另外一组PULSE进行计数
;电机转速固定运转
;采用多机联动,即一个广告画运行时其他广告画一起运转
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 ;延时计数器
count3
beepcount ;蜂鸣器计数
count4 ;数据保存个数
delay10scount1
delay10scount2
timer2ifcount ;timer2 interrupt flag count
voltagecompare ;电压比较值
remotetemp ;遥控器输入暂存
sensortemp ;HALL输入暂存
storedatacountreg ;需要保存数据的个数
stoptimereg ;停留时间寄存器
;以下为需要保存的数据
flag ;flag for motor status(00)
flag1 ;(01)
flag2 ;(02)
flag3 ;错误标志
count5 ;(03)
delaytemp ;延时数据
alldelaytemp
sametimespeedreg
setspeedreg ;电机设置速度寄存器(05)
uplowspeedreg
upsametimelowspeedreg
downlowspeedreg
downsametimelowspeedreg
pulsehig ;脉冲计数寄存器;(0c)
pulsemed ;(0d)
pulselow ;(0e)
pulsehig1 ;脉冲计数1
pulsemed1
pulselow1
tophigmax ;上限位置
topmedmax
toplowmax
tophig ;上限位置寄存器(0f)
topmed ;(10)
toplow ;(11)
lowspeedhig ;(12)
lowspeedmed ;(13)
lowspeedlow ;(14)
datamed1 ;第一次经过校正位置时的脉冲数(15)
datalow1 ;(16)
datamed2 ;第二次经过校正位置时的脉冲数(17)
datalow2 ;(18)
topdatacountreg ;上限数据个数(19)
advcount ;广告画数(1a)
advcounttemp ;广告画数暂存(1b)
topcount ;上限位置次数(1c)
endc
topstart equ 0a0h ;数据保存开始位置
;以上为需要保存的数据
;define i/o
;常数
#define speeddatalow d'0' ;电机低速运转的距离
#define speeddatamed d'3'
#define settimespeedadc d'255' ;设定参数时电机的转速初始值
#define settimespeedadcmax d'255' ;设定参数时电机的转速最大值
#define settimespeedadcmin d'255' ;设定参数时电机的转速最小值
#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' ;电机高速运转时的转速初始值
#define downhighspeedadc d'255' ;电机高速运转时的转速初始值
#define upsametimehighspeedadc d'190' ;电机同时运转时转速的初始值
#define upsametimelowspeedadc d'140' ;电机同时运转时转速的初始值
#define upsametimelowspeedadcmax d'180' ;电机同时运转时转速的初始值
#define upsametimelowspeedadcmin d'100' ;电机同时运转时转速的初始值
#define downsametimehighspeedadc d'190' ;电机同时运转时转速的初始值
#define downsametimelowspeedadc d'140' ;电机同时运转时转速的初始值
#define downsametimelowspeedadcmax d'180' ;电机同时运转时转速的初始值
#define downsametimelowspeedadcmin d'100' ;电机同时运转时转速的初始值
#define sametimespeedadc d'180' ;电机同时运转时转速的初始值
#define sametimespeedadcmax d'200' ;电机同时运转时转速的初始值
#define sametimespeedadcmin d'30' ;电机同时运转时转速的初始值
#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 ;低于该电压值时电机不能运转
#define advcountmax d'18' ;最多的广告画数
;#define storedatacount d'80' ;需要保存到EEPROM中的数据个数
#define delaytempstart d'6' ;10S延时初始值
#define delaytempmax d'250' ;最大值
#define delaytempmin d'3' ;最小值
#define beephightonecount d'250' ;高音次数
#define beeplowtonecount d'15' ;低音次数
#define brakecontrol porte,0 ;控制电机刹车
#define beepcontrol porte,1 ;控制蜂鸣器发声
#define relaycontrol porte,2 ;电瓶继电器控制
#define remotemask b'00001111' ;遥控数据提取屏蔽
#define remote portc ;遥控数据输入
#define enableupmotor portc,4 ;控制上电机运转
#define enabledownmotor portc,5 ;控制下电机运转
#define startpulsesignal portc,6 ;开始脉冲信号
#define directionsignal portc,7 ;方向信号
#define offmask b'00010101' ;直流无刷电机输出屏蔽
#define driveport portd ;驱动口
#define driveporttris trisd
#define upsensormask b'00000111' ;上电机霍尔元件信号输入屏蔽
#define downsensormask b'00111000' ;下电机霍尔元件信号输入屏蔽
#define sensorport portb ;直流无刷电机霍尔元件信号输入
#define startpulseinput portb,6
#define directioninput portb,7
;设置状态时按键分配
#define increasekey d'8' ;增加状态(1)
#define decreasekey d'4' ;减小状态(2)
#define updownkey d'12' ;上升下降(3)
#define modetorunkey d'14' ;设置状态TO运行状态(7)
#define zerokey d'2' ;置0(4)
#define storekey d'10' ;保存一副广告画参数(5)
#define setspeedkey d'6' ;电机设置转速(6)
#define sametimespeedkey d'1' ;同时运转转速
;运行状态时按键分配
#define runtomodekey d'12' ;运行状态TO设置状态(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' ;使转速为缺省值(8)
;电机运行时按2键停止后按键分配
#define highspeedkey d'12' ;增加高速运转转速(3)
#define medspeedkey d'2' ;减小高速转速(4)
#define lowspeedkey d'10' ;增加低速运转转速(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 ;中间位置停止标志
#define voltagelowflag flag,2 ;电压低标志
#define starttime flag,3 ;电机在启动时间
#define storeflag flag,4 ;是否已保存数据
#define ebrakeflag flag,5 ;电机电刹车
#define lowspeedflag flag,6 ;低速运行标志
#define positionflag flag1,0
#define store1flag flag1,1
#define store2flag flag1,2
#define secondcount flag1,3
#define topflag flag1,4 ;上电机运转结束
#define bottomflag flag1,5 ;下电机运转结束
#define topsetflag flag1,6 ;上端设置按钮已按
#define runmodeflag flag1,7 ;模式状态标志
#define needupsensorflag flag2,0 ;需要上电机HALL信号输入标志
#define needpulsecountflag flag2,1 ;需要计数标志
#define updirectionflag flag2,2 ;上升状态标志
#define downdirectionflag flag2,3 ;下降状态标志
#define addpulsecountflag flag2,4 ;需要脉冲加计数
#define notrunvoltagestopflag flag2,5 ;不能运行电压时电机停止标志
#define defaultflag flag2,6 ;缺省标志
#define changeparameterflag flag2,7 ;改变参数标志
#define toperrorflag flag3,0 ;上限位置超标志
#define bottomerrorflag flag3,1 ;下限位置超标志
#define lockerrorflag flag3,2 ;发生堵转错误
#define mainflag flag3,3 ;该控制器是否为主控制器
#define finishflag flag3,4 ;一幅画是否正常运转完成
#define voltagetest porta,0 ;电压检测
#define overcurrent porta,1 ;过流检测
#define position porta,2 ;位置校正输入
#define systemerror porta,3 ;系统发生错误
#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 ;用于判断电机是否堵转
clrf lastdownsensor ;initialize last sensor reading
clrf lastupsensor
bcf relaycontrol ;接通蓄电池
bsf brakecontrol ;刹车起作用
bcf beepcontrol
bcf status,irp ;间接寻址BANK0,1
call readdatasub ;读取上次保存的数据
bcf mainflag ;先假定它为副控制器
call mainchecksub ;判断是否为主控制器
;movlw 0ffh ;eeprom中速度数据是否为FFH
;subwf setspeedreg,w
;btfss status,z
;goto oversetspeedbran ;不是则跳过速度设置
;bcf lockerrorflag
movlw settimespeedadc ;是则设置缺省速度
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 ;系统没有错误
;设置电机初始状态
bsf pclath,3h
call motornotrunsub
bcf pclath,3h
btfsc lockerrorflag ;电机是否发生过堵转
call lockerrorhowtodosub
call delaysub
call delaysub
call delaysub
call motorlocksub ;电机电刹车起作用
call calculatevoltagesub ;计算继电器吸合断开电压
mainloop
call checkhallinputsub ;检查HALL输入
btfsc mode ;是否处于模式设置状态?
goto modeset ;是则调用MODEset
goto normalrunstart1 ;不是则到正常运转
modeset
bcf runmodeflag ;处于设置参数状态
bcf storeflag
modesetbranch
movlw remotemask
andwf remote,w ;读取遥控器输入数据
movwf remotetemp
movlw increasekey ;是否为increasekey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call increasekeysub ;=0则调用increasekeysub
movlw decreasekey ;是否为decreasekey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call decreasekeysub ;=0则调用decreasekeysub
movlw updownkey ;是否为updown按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call updownkeysub ;=0则调用updownkeysub
movlw modetorunkey ;是否为modetorunkey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
call modetorunkeysub ;=0则调用modetorunkeysub
movlw zerokey ;是否为zerokey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call zerokeysub ;=0则调用zerokeysub
movlw storekey ;是否为storekey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call storekeysub ;=0则调用storekeysub
movlw setspeedkey ;是否为setspeedkey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call setspeedkeysub ;=0则调用
movlw sametimespeedkey ;是否为sametimespeedkey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z
call sametimespeedkeysub ;=0则调用sametimespeedkeysub
call cannotrunvoltagesub ;电压是否低于规定值
btfsc runmodeflag ;是否仍处于参数设置状态
goto normalrunstart ;不是则转到normalrunstart
btfss mode ;是否为状态设置?
goto normalrunstart ;不是则正常运转
goto modesetbranch
;正常运行开始
normalrunstart
bsf finishflag
btfsc mode
goto modeset
btfss runmodeflag
goto modesetbranch
call writedatasub ;保存数据
normalrunstart1
btfsc toperrorflag ;是否发生上限位置超错误
call toperrorhowtodosub
btfsc bottomerrorflag ;是否发生下限位置超错误
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 ;数据重新读取
movf advcount,w
movwf advcounttemp ;广告画数
;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 ;处于上升状态
upnormalrun1
upnormalrun
btfsc stopflag
goto waitupstartrun1
btfsc notrunvoltagestopflag
goto upcall1 ;如由于停电引起则upcall
btfsc mainflag
goto continueupbranch ;为主控制器则直接运转
btfss finishflag ;一幅画已完成?
goto continueupbranch ;没有完成则应完成该幅画
upcheckinput
btfsc mode
goto modeset ;处于参数设置状态
call voltagecomparesub ;比较电压低于规定值则断开蓄电池并保存数据
btfsc startpulseinput ;检测有没有负脉冲发生
goto upcheckinput
call delaysub
call delaysub
btfsc startpulseinput
goto upcheckinput
btfss directioninput ;是否向上运行
goto upcheckinput ;不是则等待向上运
continueupbranch
incf topcount,f ;指向下一组地址
call getdatafromramsub ;从RAM中提取数据
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 ;如没有按停止键则继续往复运转
waitupstartrun1
btfsc lockerrorflag ;是否发生堵转错误
call lockerrorhowtodosub
btfsc toperrorflag ;上限位置超?
call toperrorhowtodosub
;goto upcall2
;如按下停止键则等待按下开始运行键
waitupstartrun
movlw remotemask
andwf remote,w ;读取遥控器输入数据
movwf remotetemp
movlw increasekey ;是否为increasekey按钮
subwf remotetemp,w ;remotetemp-w
btfsc status,z ;=0?
goto upcall2
call presschangespeedkeysub ;是否按下速度变化键
;call writedatasub ;保存数据
call cannotrunvoltagesub ;电压低于规定值则关闭电源
btfsc mode
goto modeset ;处于参数设置状态
goto waitupstartrun
upnormalrunbranch1
decfsz advcounttemp,f
goto updelay10sbranch
bsf topflag ;处于最上端位置
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -