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

📄 battery.asm

📁 智能充电器实例 功能:通过定时器定时从AD上读取数据
💻 ASM
字号:
;----------------------------------
;                   智能充电器实例
;功能:通过定时器定时从AD上读取数据,根据不同的电压选择不同的控制
;     充电方案,使用PWM控制输出脉宽来控制电流
;-----------------------------------

	ORG	0000H
	LJMP    START
	ORG     0003H
	LJMP    EXTERN_INT            ;  外中断入口
    ORG     000BH
	LJMP    TIMER0_INT             ;  定时器中断入口
;-----------------------
;   程序开始,初始化各个寄存器以及标志位
;-----------------------
START:
    MOV SP,#050H                ;  设置堆栈
	MOV R0,#030H                ;  设置AD存储单元初始地址
	MOV IE,#0FFH                ;  打开所有中断
	MOV DPTR,#78FFH             ;  采集通道首地址,只使用一路AD就可以
	MOV R0,#40H
	MOV @R0,#00H                ;  清除方案选择位
    MOV R0,#40H
	MOV @R0,#00H                ;  清除方案选择触发位
	MOV R1,#042H
    MOV @R0,#00H                ;  清除定时器计数器
	LCALL TIMER1_INIT
;-----------------------
;   进入循环,查询标志位,采取不同的方案
;-----------------------

LOOP:   
    MOV R0,#30H              ;  30H是AD转换的地址,将数据和几个值进行比较,确定方案
    MOV A,@R0
	SUBB A,#30H   ; 当电压很小的时候,采用第一种方案,向引脚PWM发送占空比为10%的信号
	JC PROCESS_01
    MOV A,@R0
	SUBB A,#90H
	JC PROCESS_02 ; 当电压较小的时候,采用第二种方案,向引脚PWM发送占空比为20%的信号
	MOV A,@R0
	SUBB A,#90H
	JZ PROCESS_03 ; 当电压正好的时候,采用第三种方案,向引脚PWM发送占空比为50%的信号
	MOV A,#04H   ; 当电压超出的时候,采用第四种方案,向引脚PWM发送占空比为0%的信号
	LJMP PROCESS_04

CLEAR_FLAG:
    MOV R0,#40H                ;  清除方案选择位
	MOV @R0,#00H
	MOV R0,#41H                ;  清除触发位
	MOV @R0,#00H
	LJMP LOOP
PROCESS_01:
    MOV R1,#040H
	MOV @R1,#01H                ;  选择方案1
PROCESS_01_NEXT:
    SETB P2.0                   ;  将和PWM连接的管脚置高
	MOV R1,#0F0H
	MOV R0,#00H
PROCESS_01_01:
    DJNZ R1,PROCESS_01_01       
	DJNZ R0,PROCESS_01_01       ;  空跑16*256*2个周期
	CLR P2.0                    ;  将和PWM连接的管脚置低
    MOV R1,#070H
	MOV R0,#00H
PROCESS_01_02:
    DJNZ R1,PROCESS_01_02
	DJNZ R0,PROCESS_01_02       ;  空跑16*256*2*9个周期
    MOV R1,#041H                ;  当方案改变标志位到来的时候,清除标志并且重新进行判断
	CJNE @R1,#00H,CLEAR_FLAG
	SJMP PROCESS_01_NEXT
PROCESS_02:
    MOV R1,#040H
	MOV @R1,#02H                ;  选择方案2
PROCESS_02_NEXT:
    SETB P2.0                   ;  将和PWM连接的管脚置高
	MOV R1,#0E0H
	MOV R0,#00H
PROCESS_02_01:
    DJNZ R1,PROCESS_02_01       
	DJNZ R0,PROCESS_02_01       ;  空跑16*256*2个周期
	CLR P2.0                    ;  将和PWM连接的管脚置低
    MOV R1,#080H
	MOV R0,#00H
PROCESS_02_02:
    DJNZ R1,PROCESS_02_02
	DJNZ R0,PROCESS_02_02       ;  空跑16*256*2*8个周期
    MOV R1,#041H                ;  当方案改变标志位到来的时候,清除标志并且重新进行判断
	CJNE @R1,#00H,CLEAR_FLAG
	SJMP PROCESS_02_NEXT
PROCESS_03:
    MOV R1,#040H
	MOV @R1,#03H                ;  选择方案3
PROCESS_03_NEXT:
    SETB P2.0                   ;  将和PWM连接的管脚置高
	MOV R1,#0B0H
	MOV R0,#00H
PROCESS_03_01:
    DJNZ R1,PROCESS_03_01       
	DJNZ R0,PROCESS_03_01       ;  空跑16*256*2*2个周期
	CLR P2.0                    ;  将和PWM连接的管脚置低
    MOV R1,#0B0H
	MOV R0,#00H
PROCESS_03_02:
    DJNZ R1,PROCESS_03_02
	DJNZ R0,PROCESS_03_02       ;  空跑16*256*2*7个周期
    MOV R1,#041H                ;  当方案改变标志位到来的时候,清除标志并且重新进行判断
	CJNE @R1,#00H,CLEAR_FLAG
	SJMP PROCESS_03_NEXT
PROCESS_04:
	CLR P2.0
	MOV R1,#040H
	MOV @R1,#04H                ;  选择方案4
    MOV R1,#041H
	CJNE @R1,#00H,CLEAR_FLAG
	SJMP PROCESS_04
TIMER1_INIT:
    ANL TMOD,#0FH                  ;  设置定时器1为方式2
	ORL TMOD,#10H    
    MOV TMOD,#21H                  ;  定时器0工作在方式1
	MOV PCON,#080H  
    CLR TR1                       ;  禁止定时器1
	SETB EA
	SETB ET1
	SETB ET0
	SETB PT0                       ;  定时器0中断优于串口中断
    CLR TF1
	MOV TL0,#00H
	MOV TH0,#01FH                  ;  定时器0中断发生时间为62.5毫秒
    SETB TR0                       ;  使能定时器0
	CLR TF0
	RET; 
;-----------------------
;   进入定时器中断,每500毫秒设置一次标志位
;-----------------------
TIMER0_INT:
    PUSH ACC                      ;  累加器入栈
	PUSH PSW                      ;  程序状态字入栈
	MOV PSW,#18H                  ;  切换寄存器区域
	CLR TF0                        ;  清除定时器中断TF0
	CLR TR0                        ;  禁止定时器0
	MOV TL0,#00H
	MOV TH0,#01FH                  ;  定时器0中断发生时间为6
	CLR TF0                        ;  清除溢出中断位
    MOV R1,#042H
	INC @R1                        ;  增加计数器的值,到8为止,这样达到500毫秒
    CJNE @R1,#08H,TIMER0_READY
	MOV @R1,#00H                   ;  清除计数器的值
	MOV R1,#041H                   ;  设置标志位,每500毫秒重新选择方案
	MOV @R1,#01H
TIMER0_READY:
    SETB TR0                         ;  使能定时器0
    POP PSW                          ;  程序状态字出栈
	POP ACC                        ;  累加器出栈
    RETI
;-----------------------
;   进入外部中断,每进入一次读取ADC的值
;-----------------------

EXTERN_INT:
    PUSH ACC                        ;  累加器压栈
	PUSH PSW                        ;  程序状态字压栈
	MOV PSW,#010H                   ;  切换寄存器区域
	MOV DPTR,#78FFH                 ;  AD转换器首地址
	MOVX A,@DPTR                    ;  读入AD的值
	MOV R1,#030H                    ;  存储AD转换器的数据的地址
	MOV @R1,A                        ;  将AD的值读入该地址
	POP PSW                          ;  程序状态字出栈
	POP ACC                         ;  累加器出栈
    RETI
	END

⌨️ 快捷键说明

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