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

📄 实验25.asm

📁 实验25-50%占空比下PWM正反转调速实验参考程序,基于pic16f877a
💻 ASM
字号:
;---------------------------------------------------------------------------------------
;50%占空比下PWM正反转调速实验参考程序(实验25.asm)
;---------------------------------------------------------------------------------------
LIST		P=16F877				;COUNTER、TEMP、COUNT
INCLUDE	"P16F877.INC"    				;S1H、S1L、R1H、R1Z、R1L变量已定义
;---------------------------------------------------------------------------------------
FSR_TEP		EQU	50H				;FSR保护缓冲器
INF_TEP		EQU	51H				;INDF保护缓冲器
PR2_TEP		EQU	52H
CCPR1L_TEP	EQU	53H
;---------------------------------------------------------------------------------------
;主程序
;---------------------------------------------------------------------------------------
		ORG	0000H				;系统复位地址
		NOP					;MPLAB需要
		GOTO	ST				;转到主程序
;---------------------------------------------------------------------------------------
;中断服务程序
;---------------------------------------------------------------------------------------
		ORG	0004H
		GOTO	IEIE				;跳转中断服务程序
ST		MOVLW   .30				;设置连续按下时间,定时的倍数
       	 	MOVWF   TIMES
		BSF	STATUS,RP0			;选择数据存储器体1
		CLRF	TRISD				;设置RD端口为输出
		MOVLW   B'10000111'			;设置TMR0基本定时65536 s
MOVWF   	OPTION_REG
		MOVLW	0FFH				;定义周期寄存器
		MOVWF	PR2
		MOVWF	PR2_TEP
		MOVLW	1FH				;定义RB端口低5位为输入
		MOVWF	TRISB
		MOVLW	B'11010000'			;定义RC3/SCK、RC5/SDO输出、RC4/SDI输入
		MOVWF	TRISC 	
		CLRF	SSPSTAT				;清除SMP、CKE位
		BCF	STATUS,RP0			;选择数据存储器体0
		MOVLW	01H
		MOVWF	PORTD				;RD0端线输出为高电平
		MOVLW	0CH				;定义CCP为PWM调制方式
		MOVWF	CCP1CON	
		MOVLW	B'00000011'			;定义定时器TMR1工作方式
		MOVWF	T2CON
		MOVLW	B'00110010'             	;设置SSP控制方式:取FOSC/64、SPI主控、CKP=1
		MOVWF	SSPCON
		CALL	CHUSHIHUA			;调用初始化子程序
 		MOVLW	80H				;1s参数送入脉宽变量及后备脉宽变量
		MOVWF	CCPR1L 				;定义脉宽初值
		MOVWF	CCPR1L_TEP
		CALL	XSCHULI				;调用数据处理子程序
       		MOVLW   B'10100000'			;开放TMR0中断
        	MOVWF   INTCON
      		CLRF    TMR0				;时间常数清零
		BSF	T2CON,TMR2ON			;启动TMR2定时
RB0		BTFSS	PORTB,0				;判断RB0是否按下
		GOTO	RB1				;没有按下转判RB1
		CALL	DELAY10MS			;RB0按下,调用10ms延时
		BTFSS	PORTB,0				;再判RB0是否按下
		GOTO	RB1				;没有按下转判RB1	
PP0		BTFSC	PORTB,0				; RB0按下,转判RB0是否释放
		GOTO	PP0				;没有释放等待
		CALL	DELAY10MS			;RB0释放,调用10ms延时
		BTFSC	PORTB,0				;再判断RB0是否释放 	
		GOTO	PP0				;没有释放等待
		MOVF	PR2_TEP,W			;取出后备周期寄存器
		SUBLW	0FFH				;与0FFH相减
		BTFSC	STATUS,Z			;是否相等
		GOTO	ADDRB0				
		INCF	PR2_TEP,1			;未到0FFH直接加1
ADDRB0		CALL	XSCHULI				;已是0FFH不再加1,直接进入数据处理
RB1     	BTFSS	PORTB,1				;判断RB1是否按下
		GOTO	RB2				;没有按下转判RB2
		CALL	DELAY10MS			;RB1按下,调用10ms延时
		BTFSS	PORTB,1				;再判RB1是否按下
		GOTO	RB2				;没有按下转判RB2
PP1		BTFSC	PORTB,1				;RB1按下,转判RB1是否释放
		GOTO	PP1				;没有释放等待
		CALL	DELAY10MS			;RB1释放,调用10ms延时
		BTFSC	PORTB,1				;再判断RB1是否释放
		GOTO	PP1				;没有释放等待
		MOVF	PR2_TEP,W			;取出后备周期寄存器
		SUBLW	00H				;比较是否到0
		BTFSC	STATUS,Z			;是否相等
		GOTO	SUBRB1				;相等,不再减1,直接进入数据处理	
		DECF	PR2_TEP,1			;不相等(后备周期大于后备周脉宽),直接减1
SUBRB1		CALL	XSCHULI 			;调用数据处理子程序
RB2		BTFSS	PORTB,2				;判断RB2是否按下
		GOTO	RB3				;没有按下转判RB3
		CALL	DELAY10MS			;RB2按下,调用10ms延时
		BTFSS	PORTB,2				;再判RB2是否按下
		GOTO	RB3				;没有按下转判RB3	
PP2		BTFSC	PORTB,2				; RB2按下,转判RB2是否释放
		GOTO	PP2				;没有释放等待
		CALL	DELAY10MS			;RB2释放,调用10ms延时
		BTFSC	PORTB,2				;再判断RB2是否释放
		GOTO	PP2				;没有释放等待
		BSF	PORTD,0 			;RD0端口引脚输出为高电平(正转)
		MOVLW	01H
		MOVWF	67H				;在八段显示器的最高位输出1
CALL		XSHI					;调用显示子程序
RB3  	   	BTFSS	PORTB,4				;判断RB4是否按下
		GOTO	RB0				;没有按下转判RB0
		CALL	DELAY10MS			;RB4按下,调用10ms延时
		BTFSS	PORTB,4				;再判RB0是否按下
		GOTO	RB0				;没有按下转判RB0	
PP3		BTFSC	PORTB,4				; RB4按下,转判RB4是否释放
		GOTO	PP3				;没有释放等待
		CALL	DELAY10MS			;RB4释放,调用10ms延时
		BTFSC	PORTB,4				;再判断RB4是否释放
		GOTO	PP3				;没有释放等待
		BCF	PORTD,0 			;RD0端口引脚输出为低电平(反转)
		CLRF	67H				;在八段显示器的最高位输出0
		CALL	XSHI				;调用显示子程序
		GOTO	RB0
;------------------------------------------------------------------------------------------
;10MS软件延时子程序DELAY10MS
;------------------------------------------------------------------------------------------
DELAY10MS	MOVLW	0DH			  	;外循环常数
		MOVWF	20H			  	;外循环寄存器
LOOP1   	MOVLW	0FFH				;内循环常数
		MOVWF	21H			  	;内循环寄存器
LOOP2		DECFSZ	21H			  	;内循环寄存器递减
		GOTO	LOOP2			  	;继续内循环
		DECFSZ	20H			 	;外循环寄存器递减
		GOTO	LOOP1			 	;继续外循环
		RETURN					;子程序返回
;------------------------------------------------------------------------------------------
;数据处理子程序
;------------------------------------------------------------------------------------------
XSCHULI		BCF	STATUS,C			;进位标志清零
		RRF	PR2_TEP,W			;除2
		MOVWF	CCPR1L				;送给脉宽寄存器
MOVF		PR2_TEP,W				;取出后备周期参数
		BSF	STATUS,RP0			;选择数据存储器体1
		MOVWF	PR2				;后备周期参数送入周期寄存器
		BCF	STATUS,RP0			;选择数据存储器体0 	
		MOVWF	S1L				;周期参数送入口变量
		CLRF	S1H
		CALL	BINTOBCD			;调用二进制至BCD码转换
		MOVF	R1Z,W				;百位直接送入62H
		MOVWF	62H
		MOVF	R1L,W				;分离十位和个位分别送入61H、60H
		ANDLW	0FH				;屏蔽高4位送数据缓冲区60H
		MOVWF	60H
		SWAPF	R1L,W
		ANDLW	0FH				;屏蔽高4位送数据缓冲区61H	
		MOVWF	61H
		MOVF	PORTD
		CALL	XSHI				;调用显示子程序
		RETURN					;子程序返回
;------------------------------------------------------------------------------------------
;二进制到BCD码转换子程序
;------------------------------------------------------------------------------------------
BINTOBCD	MOVLW	10H			   	;循环向左移位16次
		MOVWF	COUNT
		CLRF	R1H				;输出类变量清0
		CLRF	R1Z
		CLRF	R1L
LOOP		RLF	S1L			   	;二进制数据单元逐位移入BCD码单元
		RLF	S1H				;右移一位
		RLF	R1L				;右移一位
		RLF	R1Z				;右移一位
		RLF	R1H				;右移一位
		DECFSZ	COUNT				;递减判断是否为0
		GOTO	ADJDET
		RETLW	00H				;返回
ADJDET		MOVLW	R1L
		MOVWF	FSR
		CALL	ADJBCD				;调整低8位R1L
		MOVLW	R1Z
		MOVWF	FSR
		CALL	ADJBCD				;调整中8位R1Z
		MOVLW	R1H
		MOVWF	FSR
		CALL	ADJBCD				;调整高8位R1H
		GOTO	LOOP
;------------------------------------------------------------------------------------------
;逐位调整
;------------------------------------------------------------------------------------------
ADJBCD		MOVLW	03H
		ADDWF	INDF,W				;是否LSD加3
		MOVWF	TEMP
		BTFSC	TEMP,3				;是否大于4
		MOVWF	INDF				;确定LSD加3
		MOVLW	30H
		ADDWF	INDF,W				;是否MSD加3
		MOVWF	TEMP
		BTFSC	TEMP,7				;是否大于4
		MOVWF	INDF				;确定MSD加3
		RETLW	00H
;------------------------------------------------------------------------------------------
;显示驱动子程序
;------------------------------------------------------------------------------------------
XSHI		CLRF	PORTE				;清0
		MOVLW	67H				;设置显示缓冲器的数据地址
		MOVWF	FSR
LO1P		MOVF	INDF,W				;取出数据
		CALL	BMA				;查询对应编码
		CALL	OUTXSH		        	;利用SPI方式输出编码数据
		DECF	FSR
		BTFSS	FSR,4				;直到8位数码全部输出
		GOTO	LO1P				
		RETURN					;子程序返回
;------------------------------------------------------------------------------------------
;SPI方式输出编码数据子程序
;------------------------------------------------------------------------------------------
OUTXSH		MOVWF	SSPBUF				;送至SSPBUF后开始逐位发送
LO1P1		BSF	STATUS,RP0              	;选择体1
		BTFSS	SSPSTAT,BF			;是否发送完毕
		GOTO	LO1P1				;否,继续查询
		BCF	STATUS,RP0			;发送完毕,选择体0
		MOVF	SSPBUF,W			;移空SSPBUF
		RETURN					;子程序返回		
;------------------------------------------------------------------------------------------
;8位数码全暗,仅仅最高位给出"-"键控提示符
;------------------------------------------------------------------------------------------
JKZT		MOVLW	60H		        	;除最高位外,均设置为全暗
		MOVWF	FSR
TUN		MOVLW	0AH
		MOVWF	INDF				;采用间接寻址送数
		INCF	FSR
		BTFSS	FSR,3				;是否完成8个单元置数
		GOTO	TUN
		MOVLW	01H				;最高位67H单元送"-"编码
		MOVWF	67H
		RETURN					;子程序返回
;------------------------------------------------------------------------------------------
;初始化子程序(67H-60H缓冲存储器分别赋值01-07),从数码最高位67H开始点亮,延时1S
;------------------------------------------------------------------------------------------
CHUSHIHUA
		CALL	JKZT		               	;首先调用监控子程序
		CALL	XSHI                       	;输出显示
		MOVLW	67H
		MOVWF	FSR		               	;从最低位赋值,采用间接寻址
		MOVLW	00H
		MOVWF	COUNTER	                  	;给出赋值数据,从1开始
QT		MOVF	COUNTER,W
		MOVWF	INDF				;采用间接寻址
		MOVF	FSR,W
		MOVWF	FSR_TEP				;保护FSR
		CALL	XSHI				;数码刷新
		CALL	DELAY				;调用1S延时
		MOVF	FSR_TEP,W			;恢复FSR
		MOVWF	FSR
		DECF	FSR				;地址减1
		INCF	COUNTER	                 	;赋值数据加1
		BTFSS	COUNTER,3			;8位赋值是否结束	
		GOTO	QT
		CALL	JKZT		                ;首先调用监控子程序
		CALL	XSHI			        ;数码显示刷新
	     	RETURN					;子程序返回
;------------------------------------------------------------------------------------------
;编码查询
;------------------------------------------------------------------------------------------
BMA		ADDWF	PCL,F				;加偏移量
		RETLW	3FH				;"0" 编码
		RETLW	06H				;"1" 编码
		RETLW	5BH				;"2" 编码
		RETLW	4FH				;"3" 编码
		RETLW	66H				;"4" 编码
		RETLW	6DH				;"5" 编码
		RETLW	7DH				;"6" 编码
		RETLW	07H				;"7" 编码
		RETLW	7FH				;"8" 编码
		RETLW	6FH				;"9" 编码
		RETLW	00H 		     		;"暗" 编码
		RETLW	40H				;"-" 编码
;------------------------------------------------------------------------------------------
;中断服务子程序
;------------------------------------------------------------------------------------------
IEIE    	BCF     INTCON,T0IF			;清除中断标志位
        	DECFSZ  TIMES,F				;中断倍数递减是否为零
        	GOTO   	POP				;不为零,直接中断返回			
TP0     	BTFSC   PORTB,0				;为零,TMR0定时倍数时间到,判断RB0按下否?
        	GOTO    XYZ0				;RB0按下
        	GOTO    TP1				;RB0没有按下, 跳去判断RB1
XYZ0    	MOVF	PR2_TEP,W			;周期寄存器是否为FFH
		SUBLW	0FFH
		BTFSC	STATUS,Z			;考察Z标志位
		GOTO	IERB0				;为FFH不再递增
		INCF	PR2_TEP,F			;不为FFH,执行递增
IERB0		CALL	XSCHULI				;转入数据处理
        	CALL    DELAY100MS			;延时100ms
        	GOTO    TP0				;再次重复判断
TP1     	BTFSC   PORTB,1				;判断RB1按下否?
        	GOTO    XYZ1				;RB1按下
        	GOTO    POP1				;RB1没有按下, 直接中断返回
XYZ1    	MOVF	PR2_TEP,W			;周期寄存器是否为00H
		SUBLW	00H						
		BTFSC	STATUS,Z			;考察Z标志位
		GOTO	IERB1				;为00H不再递减
		DECF	PR2_TEP,F			;不为00H,执行递减
IERB1		CALL	XSCHULI				;转入数据处理
        	CALL    DELAY100MS			;延时100ms
        	GOTO    TP1				;再次重复判断
POP     	CLRF    TMR0				;TMR0单次时间常数清零
        	RETFIE					;中断返回
POP1    	CLRF    TMR0				;TMR0单次时间常数清零
        	MOVLW   .30				;重新设置连续按下时间的定时倍数
        	MOVWF   TIMES
        	RETFIE					;中断返回
;----------------------------------------------------------------------------------------
;100MS延时子程序
;----------------------------------------------------------------------------------------
DELAY100MS	
		MOVLW	83H				;外循环常数
		MOVWF	20H				;外循环寄存器
LO2		MOVLW	0FFH				;中循环常数
		MOVWF	21H				;中循环寄存器
L01		DECFSZ	21H,F				;中循环寄存器递减
		GOTO	L01				;继续中循环
		DECFSZ	20H,F				;外循环寄存器递减
		GOTO	LO2				;继续外循环
		RETURN					;返回
;------------------------------------------------------------------------------------------
;1S延时
;------------------------------------------------------------------------------------------
DELAY		MOVLW	06H				;外循环常数
		MOVWF	22H				;外循环寄存器
LQ3		MOVLW	0EBH				;中循环常数
		MOVWF	20H				;中循环寄存器
LQ2		MOVLW	0ECH				;中循环寄存器递减
		MOVWF	21H				;继续中循环
LQ1		DECFSZ	21H,F				;外循环寄存器递减
		GOTO	LQ1				;继续外循环
		DECFSZ	20H,F				;外循环寄存器递减
		GOTO	LQ2
		DECFSZ	22H,F				;继续外循环
		GOTO	LQ3	
		RETURN

;------------------------------------------------------------------------------------------
		END
;------------------------------------------------------------------------------------------

⌨️ 快捷键说明

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