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

📄 sensbldc.asm

📁 输入高电压时直流无刷电机的控制程序,可使用在家庭,工厂等没有直流电源的地方
💻 ASM
字号:
;**********************************************************************
;*                                                                    *
;用此软件控制高压直流无刷电机的运转(2007/5/7)
;*                                                                    *
;**********************************************************************
;    Filename:	    SensBLDC.asm                                      *
;**********************************************************************
;    Files required: p16f877.inc                                      *
;**********************************************************************
;    Notes: Sensored brushless motor control                          *
;**********************************************************************

	list      p=16f877            ; list directive to define processor
	#include <p16f877.inc>        ; processor specific variable definitions
	

;**********************************************************************
;*
;* Define variable storage
;*
	CBLOCK 0x20

	ADC		; PWM threshold is ADC result
	adctemp	;当前ADC的值
	LastSensor	; last read motor sensor data
	DriveWord	; six bit motor drive data
	sensortemp
	flag
	delaycount1
	delaycount2
	timer2ifcount
	ENDC

;**********************************************************************
;*
;* Define I/O
;*

#define	OffMask		B'00000000'
#define	DrivePort	PORTB
#define DrivePortTris	TRISB
#define	SensorMask	B'00000111'	;RA2,RA3,RA4分别对应SA,SB,SC
#define	SensorPort	PORTA

#define led1 portd,0	;灯1
#define led2 portd,1	;灯2
#define led3 portd,2	;灯3
#define RUNSTOPKEY PORTD,6	;运行停止键
#define directionkey portd,7 ;改变方向键
#define directionbit flag,0	;方向标志位
#define runstopbit flag,1	;运行标志,1代表运行,0代表停止
#define starttime flag,2	;软启动开始
#define errorflag flag,3	;错误标志
#define led4 portc,0	;灯4
#define overcurrent portc,1	;过流检测
#define voltagefault portc,2 ;电压检测

#define overtemp porte,2	;IGBT模块温度检测

#define startadc d'40'	;电机启动时的ADC
#define startendadc d'200'	;电机启动结束时的ADC
#define deltadc d'8'	;启动时增加的ADC
#define adcmin d'40'
#define deltstopadc d'8'	;停止时减小的ADC

;**********************************************************************
	org	0x000		; startup vector
	nop			; required for ICD operation
	clrf    PCLATH          ; ensure page bits are cleared
  	goto    Initialize      ; go to beginning of program


	ORG     0x004           ; interrupt vector location
	retfie                  ; return from interrupt

;**********************************************************************
;*
;* Initialize I/O ports and peripherals
;*

Initialize
	clrf	DrivePort	; all drivers off

	banksel TRISA
; setup I/O
	MOVLW B'11000000'	;PORTD7,6输入,其他输出
	movwf trisd
	MOVLW B'11111110'	;PORTC0输出,其他输入
	MOVWF TRISC

	clrf	DrivePortTris	; set motor drivers as outputs
	movlw	B'00011111'	; A/D on RA1,  Motor sensors on RA<4:2>
	movwf	TRISA		; 
; setup Timer0
	movlw	B'11010000'	; Timer0: Fosc, 1:2
	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 portd
	clrf flag
	clrf LastSensor	; initialize last sensor reading
	call Commutate	; determine present motor positon
	clrf ADC		; start speed control threshold at zero until first ADC reading
	bsf led1	;灯1亮
	bcf led2
	bcf led3
	bcf led4
mainloop
	btfss runstopkey	;按下runstopkey?
	goto mainrunloop
	btfss directionkey	;按下DIRECTIONKEY
	call directionsub	;是的则DIRECTIONSUB
	goto mainloop
mainrunloop		;运行
	bcf errorflag
	bcf led2
	bcf led3
	bcf led4
	call readadcsub
	bsf led2
	clrf tmr2
	clrf timer2ifcount

	clrf tmr1L	;TIMER1为0
	clrf tmr1h
	bsf t1con,tmr1on	;启动TIMER1
	bsf starttime	;电机处于起动时间
	movlw STARTADC	;开始启动时ADC的值
	movwf adc
increaserun	;加速运行(软启动)
	btfss starttime	;起动结束?
	goto normalrun	;正常运转
	BTFSs PIR1,TMR1IF	;TIMER1时间到
	goto normalrun	;正常运转
	bcf pir1,tmr1if	;清除tmr1if
	movlw deltadc
	addwf adc,f
	btfsc status,c	;是否超过255?
	goto adcgeadctemp	;是的则ADC>=ADCTEMP
	movlw startendadc		;没有超过则比较startendadc
	subwf adc,w
	btfss status,c
	goto normalrun	;adc<startendadc
adcgeadctemp		;adc>=startendadc
	movf adctemp,w
	movwf adc
	bcf starttime
	bcf t1con,tmr1on	;关闭TIMER1的运行
normalrun
	btfss starttime
	call readadcsub	;运行时读取ADCTEMP
	call runsub
	btfss voltagefault	;如电压超过242V或低于170V则电机停止运转
	goto voltagefaultstoprun
	btfsc errorflag
	goto errorstoprun
	btfsc directionkey	;是否停止?
	goto increaserun
	goto stoprun

errorstoprun
	bsf led4
	goto stoprun
voltagefaultstoprun
	bsf led4
	bsf led3
stoprun
	call norunsub	;减速停止
	bcf led2
	call delaysub
	call delaysub
	goto mainloop

;运行停止标志改变子程序
RUNSTOPSUB
	CALL DELAYSUB	;
	btfsc runstopkey
	return
	movlw b'00000010'
	xorwf flag,f
	return
;方向标志改变子程序
directionsub
	call delaysub
	btfsc directionkey
	return
	movlw b'00000001'
	xorwf flag,f
	return

delaysub
	movlw d'50'
	movwf delaycount1
delayloop1
	movlw d'100'
	movwf delaycount2
delayloop2
	decfsz delaycount2
	goto delayloop2
	decfsz delaycount1
	goto delayloop1
	return

norunsub
	clrf tmr1L	;TIMER1为0
	clrf tmr1h
	bsf t1con,tmr1on	;启动TIMER1
decreaserun	;减速运行(软停止)
	BTFSs PIR1,TMR1IF	;TIMER1时间到
	goto decreaserunbranch1	;正常运转
	bcf pir1,tmr1if	;清除tmr1if
	movlw deltstopadc
	subwf adc,f
	btfss status,c	;是否小于0
	goto enddecreaserun
decreaserunbranch1
	call runsub
	goto decreaserun
enddecreaserun
	bcf t1con,tmr1on	;关闭TIMER1的运行
	clrf driveport
	bcf runstopbit
	return
;运行子程序
runsub
	call	Commutate	; test for commutation change
	incfsz	ADC,w		; if ADC is 0xFF we're at full speed - skip timer add
	goto	PWM		; add timer 0 to ADC for PWM 

	movf	DriveWord,w	; force on condition
	goto	Drive		; continue
PWM
	movf	ADC,w		; restore ADC reading
	addwf	TMR0,w		; add it to current timer0
	movf	DriveWord,w	; restore commutation drive data
	btfss	STATUS,C	; test if ADC + timer0 resulted in carry
	andlw	OffMask		; no carry - supress high,low drivers
Drive
	btfsc overcurrent	;过流?
	goto drive2
	andlw offmask
	bsf led3
	goto drive1
drive2
	bcf led3
drive1	
	movwf	DrivePort	; enable motor drivers
;	return
lockcheck
	btfss pir1,tmr2if	;timer2溢出 
	return	;没有则返回
	bcf pir1,tmr2if
	incf timer2ifcount,f
	movlw d'100'
	subwf timer2ifcount,w
	btfss status,c	;timer2ifcount>某一固定值
	return	;不是则返回
	bsf errorflag	;是则电机发生错误
	clrf driveport	;电机停止运转
	clrf timer2ifcount
	clrf tmr2
	bsf led4
	return
	
ReadADCsub
;**********************************************************************
;*
;* If the ADC is ready then read the speed control potentiometer
;* and start the next reading
;*
	btfsc	ADCON0,NOT_DONE	; is ADC ready?
	return			; no - return

	movf	ADRESH,w	; get ADC result
	bsf	ADCON0,GO	; restart ADC
	movwf	ADC		; save result in speed control threshold
	movlw adcmin
	subwf adc,w		;adc<adcmin?
	btfsc status,c	
	goto adcgeadcmin
	movlw adcmin	;adc<adcmin则ADC=ADCMIN
	movwf adctemp
	movwf adc
	return
adcgeadcmin		;adc>=adcmin
	movf adc,w
	movwf adctemp
	return

;**********************************************************************
;*
;* Read the sensor inputs and if a change is sensed then get the
;* corresponding drive word from the drive table
;*
Commutate
	movf sensorport,w
	movwf sensortemp
	rrf sensortemp,f
	rrf sensortemp,f
	movlw	SensorMask	; retain only the sensor bits
	andwf	Sensortemp,w	; get sensor data
	xorwf	LastSensor,w	; test if motion sensed
	btfsc	STATUS,Z	; zero if no change
	return			; no change - back to the PWM loop
	
	clrf tmr2
	clrf timer2ifcount
	
	xorwf	LastSensor,f	; replace last sensor data with current
	btfss	DirectionBit	; test direction bit
	goto	FwdCom		; bit is zero - do forward commutation

				; reverse commutation
	movlw	HIGH RevTable	; get MS byte of table
	movwf	PCLATH		; prepare for computed GOTO
	movlw	LOW RevTable	; get LS byte of table
	goto	Com2
FwdCom				; forward commutation
	movlw	HIGH FwdTable	; get MS byte of table
	movwf	PCLATH		; prepare for computed GOTO
	movlw	LOW FwdTable	; get LS byte of table
Com2
	addwf	LastSensor,w	; add sensor offset
	btfsc	STATUS,C	; page change in table?
	incf	PCLATH,f	; yes - adjust MS byte

	call	GetDrive	; get drive word from table
	movwf	DriveWord	; save as current drive word
	return

GetDrive
	movwf	PCL
;**********************************************************************
;*
;* The drive tables are built based on the following assumptions:
;* 1) There are six drivers in three pairs of two
;* 2) Each driver pair consists of a high side (+V to motor) and low side (motor to ground) drive
;*3)ra2=sa,ra3=sb,ra4=sc
;*4)portb(5.4.3.2.1.0)控制L3.H3.H2.L2.H1.L1
FwdTable
	retlw	B'00000000'	; invalid(000)
	retlw	B'00100010'	; scsbsa(001)
	retlw	B'00001001'	; scsbsa(010)
	retlw	B'00101000'	; scsbsa(011)
	retlw	B'00010100'	; scsbsa(100)
	retlw	B'00000110'	; scsbsa(101)
	retlw	B'00010001'	; scsbsa(110)
	retlw	B'00000000'	; invalid(111)
RevTable
	retlw	B'00000000'	; invalid(000)
	retlw	B'00010001'	; scsbsa(001)/
	retlw	B'00000110'	; scsbsa(010)/
	retlw	B'00010100'	; scsbsa(011)/
	retlw	B'00101000'	; scsbsa(100)/
	retlw	B'00001001'	; scsbsa(101)/
	retlw	B'00100010'	; scsbsa(110)/
	retlw	B'00000000'	; invalid(111)

	END                       ; directive 'end of program'

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -