⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ver30.asm

📁 用一片单片机控制两个直流无刷电机运转,所以可有效的控制两个直流无刷电机的同步运转
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;用一片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 + -