下面是此电瓶车充电保护器作品的外观图:
这是一个电瓶车充电器的附加装置,不对充电器做任何变动,而是将充电器插在该保护器上连成一体代替原充电器进行电瓶车的充电。
功能:1、充电达到设定的电压,自动断电停充,防过充。
2、满十小时自动停充电,电瓶有故障充不到设定电压,经十小时也停充。
3、能根据气温设定充电电压档次,能记忆设定的档次,无须每次设定。
4、用二进制数循环显示电压的十位个位小数位值。
用法:将充电器插在该保护器上连成一体,代替原充电器进行电瓶车的充电。插上220V交流后在15秒内左右慢摇保护器,使内置水银开关接通又断开(按键作用),温度档次依次增加,共分1~8档,对应环境温度是5℃-40℃。水银开关断开15秒后进入充电程序,水银开关不再起作用。
充足电的断充电指示可从原充电器指示灯看出,不另加指示灯。
读电压:显示过程是--四灯全亮(提示开始)、灭、十位、灭、个位、灭、小数一位、灭,循环不断。用四位二进制数表示0到9,读出数不难,记得四灯分别代表8、4、2、1,将亮灯的数相加就是了。0也显示为灭,可从时间上判别出来。
例:54.9显示为
○○○○ 开始
●○●○ 5
●○●● 4
○●●○ 9
为省事没用数码管,自己用的东西,简单实用为好。四个发光管也合用一个限流电阻,单片机复位用的电容电阻也省了,晶振也省了。
工作原理:用手机充电器拆来的电路板为装置提供5V电源。单片机AD转换测电压,每15秒进行一次。测得的电压与设定的终止电压比较,达到了就给继电器模块送一信号,收到信号继电器就断开充电器电源。单片机同时计时,满十时也发出停充电信号,满十天自动重启单片机进行充电管理(暑假长时间人不在家也没问题了)。
为避免单片机工作电压变动对电压测量的影响,用TL431提供一个基准电压,P1.1对其进行AD转换。电瓶电压1/15分压后用P1.0进行AD转换,然后用下式算出电瓶电压。
十五分之一电瓶电压:基准电压=电瓶AD值:基准电压的AD值
实测TL431稳压后是2.524伏,程序中采用的具体算法是:
电瓶电压伏特数=(电瓶AD值×37+电瓶AD值×86÷100)÷基准电压AD值
被除数是两个8位,除数是一个8位,我是用循环做减法的办法来求商。具体见源码。
分压电阻的调整,借助万用表反复细心调精密可调电阻,使阻值之比为14:1。
材料:单片机STC12C5204AD 继电器模块,手机充电器,交流插座等。
电路原理图:
单片机电路图
接线示意图:
组装接线示意图
制作过程:
装饰边角料做的外壳
拆解手机充电器
继电器模块
单片机正面
单片机背面
组装好
单片机编程源码如下:
- ;1/15取样,单片机工作电压约5V,能测电压达75V。
- ;改成最多充电10小时。十天后重启。
- ;使用EEPROM保存温度档。 ;2016年7月6日修改:
- ;使用汞开关设定温度档,使用EEPROM保存温度档。
- ;开机16秒内(大约)按键设定温度档数,若不按键,则默认上次的档数。有1,2,3,4,5,6,7,8共八档。
- ;设温度档后接通220V
- ;从温度5度起为第1档,10度为第2档,15度为第3档,……35度为第7档,40度为第8 档,0档同第8档。停下不按键约15秒自动进入下一环节。
- ;显示电瓶伏特数,按四灯亮、黑、十位、黑、个位、黑、小数位、黑,循环显示。四灯亮和黑是半秒,数字是1秒
- ;20H.0设置温度档[WENDU]子程序控制位,初值赋1,在等待按键的子程序[xunhuan]中清0.仅在开机初用一次。
- ;20H.2 显示控制位.走时置1,显示后清0,使得半秒进行一次显示。
- ;20H.3 秒标志
- ;21H.0
- ;21H.2 [Tuoliu]程序控制位,使程序只运行一次。
- ;21H.3
- ;21H.4是电瓶正常标志,初值赋1(正常),检测到电瓶充满或不正常将其清0,清0后要重启才能置1.
- ;21H.6充电10小时标志,初值为1,充电达10小时将其清0.清0后要重启才能置1.
- ;22H.0 走时用的20ms标志,在中断置1,走时中清0。
- ;22H.3 时标志
- ;22H.5 每15秒运行一次的标志位,走时置1.
- ;22H.7
- ;用检测到的电压AD值与设定的终止电压AD值进行比较,确定电瓶满或不正常(电压太低或无电瓶)关断220V供电。
- ;开机接通220V,电瓶充满(或不正常)关断,充电10小时关断,十天后单片机重启。
- ;P1.0--A/D转换
- ;P1.1--A/D转换测TL431电压
- ;P1.2--键,每按一次温度档数加1,在0--8之中循环,停下不按键约15秒自动进入下一环节。
- ;P1.7,P1.6,P1.5,P1.4接LED做温度档显示,点亮分别表示8,4,2,1,二进制数。
- ;P3.2--通过光耦控制220V通断 0-通 1-断
- ;***************
-
- ;***
- U_zhongzhixiao EQU 5EH ;终止电压小数寄存器
- U_zhongzhizheng EQU 5FH ;终止电压整数寄存器
- JSHQ_WEI EQU 65H ;显示第几位计数器
- XUN_JSHQ EQU 67H ;循环次数
- wendudang EQU 68H ;温度档数
- v_ZH EQU 5DH ;电瓶伏特整数寄存器
- V_XAO EQU 5CH ;电瓶伏特小数寄存器
- TL431_AD EQU 5BH ;TL431的AD值
- TL431_AD1 EQU 5AH ;TL431的AD值(第一次)
- jiace_adzhi1 EQU 58H ;第一次检测到的AD值
- ;xiu_adzhi EQU 6CH ;(修)终止电压AD值
- Jiace_ADzhi EQU 59H ;检测AD值 检测到的AD值
- JSHQ_15 EQU 6EH ;15秒计数器
- JSHQ_20mS EQU 70H ;20mS计数器 计20mS的个数
- JSHQ_S EQU 71H ;半秒计数器
- JSHQ_M EQU 72H ;分计数器
- JSHQ_H EQU 73H ;时计数器
- ;60H,61H,62H,63H,64H 用在显缓中
- beichushugao equ 75h ;被除数高位
- beichushudi EQU 76H ;被除数低位
- chushu EQU 77H ;除数
- zhengshang EQU 78H ;整数商
- XIAOSHUSHANG EQU 79H ;小数商
- YUSHU EQU 7AH ;余数
- LSSHU EQU 7BH ;临时存
- DISHU EQU 7CH ;低数 第二次的被除数的低位
- GAOSHU EQU 7DH ;高数 第二次的被除数的高位
- ADC_CONTR EQU 0BCH ;ADC控制寄存器
- ADC_RES EQU 0BDH ;A/D转换结果寄存器
- P1ASF EQU 09DH ;p1口模拟功能控制寄存器
- WDT_CONTR EQU 0C1H ;看门狗
- ;AUXR DATA 8EH ;选择1T与12T的寄存器
- IAP_CONTR EQU 0C7H ;下载/复位控制器
- jian EQU p1.2 ;鍵
- kong EQU p3.2 ;控 220V 0-通 1-断
- p1m1 equ 91h
- p1m0 equ 92h
- ;EEPROM有关的寄存器
- dat equ 0C2H
- drh equ 0C3H
- drl equ 0C4H
- cmd equ 0C5H
- trig equ 0C6H
- contr equ 0C7H
- ;****************
- ORG 0000H
- AJMP START
- ORG 000BH
- LJMP TIME_0
- ; ORG 001BH
- ORG 0030H
- START:
- ;其它初始化写在此
- MOV P1M1,#00000011B
- MOV P1M0,#00000000B ;P1.0 P1.1两个高阻输入做AD
- MOV P1,#00001111B
- setb kong ;断220V交流 设温度档后接通
- MOV 22H,#00100000B ;检测标志 1-检 0-不检 每15秒检测AD一次和处理显缓一次的标志位,走时置1,处理显缓后清0
- MOV 21H,#01010000B ;21h.4 电瓶 1-能充 0-不能充电(含无、充满)
- ;21H.6 初值1,充电10小时清0 。
- ;*用计数器0 初步设置定时中断 20MS中断 20毫秒@10.911MHz
- MOV SP,#80H ;设置堆栈区域
- ; ANL AUXR,#7FH ;定时器时钟12T模式 默认是12T模式 省略本句
- MOV TMOD,#00010001B ;定时器0定时器1都是 16位
- MOV TL0,#0F7H
- MOV TH0,#0B8H
- SETB EA
- SETB ET0
- SETB TR0 ;开放中断
-
- setb 20h.0 ;控制设置温度档程序的循环用
- ;*****************
- ;设置温度档 从EEPROM中读出保存值,一段时间内不按键,则使用该档值;如按键则改之,停下不动,过会儿保存并启用。
- LCALL DOUEEPROM ;读EEPROM中的保存值
- WENDU:
- jnb 20H.0,WENDUret ;0-跳
- LCALL doujian ;读键和健值处理
- LCALL XIANSHI ;显示
- LCALL xunhuan ;循环 次数
- AJMP WENDU
- WENDUret:
- LCALL clear_write ;先擦除EEPROM再写EEPROM保存温度档,然后关闭EEPROM
- nop
- ;********************
- ;设AD档 据wendudang中数字,设定终止电压
- ADdang:
- MOV A,wendudang
- cjne a,#1,ADdang1
- MOV U_zhongzhizheng,57
- mov U_zhongzhixiao,1 ;对应是57.11V 5度以下
- JMP ADdangRET
- ADdang1:
- cjne a,#2,ADdang2
- MOV U_zhongzhizheng,56
- mov U_zhongzhixiao,6 ;对应是56.64V 10度以下
- JMP ADdangRET
- ADdang2:
- cjne a,#3,ADdang3
- MOV U_zhongzhizheng,56
- mov U_zhongzhixiao,1 ;对应是56.16V 15度以下
- JMP ADdangRET
- ADdang3:
- cjne a,#4,ADdang4
- MOV U_zhongzhizheng,55
- mov U_zhongzhixiao,6 ;对应是55.68V 20度以下
- JMP ADdangRET
- ADdang4:
- cjne a,#5,ADdang5
- MOV U_zhongzhizheng,55
- mov U_zhongzhixiao,2 ;对应是55.20V 25度以下
- JMP ADdangRET
- ADdang5:
- cjne a,#6,ADdang6
- MOV U_zhongzhizheng,54
- mov U_zhongzhixiao,7 ;对应是54.72V 30度以下
- JMP ADdangRET
- ADdang6:
- cjne a,#7,ADdang7
- MOV U_zhongzhizheng,54
- mov U_zhongzhixiao,2 ;对应是54.24V 35度以下
- JMP ADdangRET
- ADdang7:
- cjne a,#8,ADdang8
- MOV U_zhongzhizheng,53
- mov U_zhongzhixiao,7 ;对应是53.76V 40度以下
- JMP ADdangRET
- ADdang8: ;剩下的就是 a=0了 同a=8 档
- MOV U_zhongzhizheng,53
- mov U_zhongzhixiao,7 ;对应是53.76V 40度以下
- ADdangRET:
- clr kong ;接通220V
- nop
- NOP
- ;进入主程序之前不能有RET,否则运行到此止。
- ;*****************
- ;主程序
- ZhuPRO:
- LCALL PRO_ZOUSHI ;走时 统计20mS的个数,计时,设立半秒标志、分标志、时标志 检测标志
- LCALL KAIJISHISHU ;开机时数 开机10小时停充电,开机240小时重新启动单片机。
- jnb 22h.5,zhu_a
- clr 22h.5 ;每15秒一次的标志位,走时置1,在此清0
- lcall jiaceTL431 ;检测TL431做基准电压的AD值
- LCALL jiacesheding ;检测(电瓶)设定 测出电瓶AD
- LCALL JISUAN ;计算 电瓶电压伏特数=(电瓶AD值×37+电瓶AD值×0.5)÷基准电压AD值 求出伏特整数和小数
- LCALL probijiao ;比较 电瓶电压与基准电压做比较 标记是否充满电
- lcall XIANhuan ;显缓 存放好要显示的十位、个位、小数位
- zhu_a:
- LCALL xiu_V ;显示电瓶电压
-
- lcall PROKongZhi ;控制 充满断电 十小时断电
- mov WDT_CONTR,#00111110B ;喂狗
- jmp ZhuPRO
-
- ;*************************** WENDU 温度 设温度档 *********************************
- ;DOUEEPROM ;读EEPROM中0000H处的保存值
- DOUEEPROM:
- mov contr,#84h ;设定操作时间
- mov cmd,#01h ;设定读操作
- mov drl,#00h ;设定存储单元地址低四位
- mov drh,#00h ;设定存储单元地址高四位 这里设0000h,也可选用其他单元
- mov trig,#5Ah ;准备触发
- mov trig,#0A5h ;触发
- nop
- mov wendudang,dat ;读数据写到RAM指定处
- ; mov wendudang,A ;读数据写到RAM指定处
- DOUEEPROMret:
- ret
- ;*************
- ;doujian ;读键
- doujian:
- setb jian
- nop
- nop
- lcall DELAY
- JB jian,doujianret ;未按下(p1.2), 1-跳
- lcall DELAY ;延时
- JB jian,doujianret
- inc wendudang ;温度档加1
- mov XUN_JSHQ,#0 ;循环计数清0
- mov a,#9
- cjne a,wendudang,doujian_1 ; 分0,1,2,3,4,5,6,7,8九档,最高8档
- mov wendudang,#0
- doujian_1:
- nop
- jb jian,doujian_1 ;1-跳 等待释放键
- lcall DELAY
- lcall DELAY
- doujianret:
- ret
- ;****************
- ;XIANSHI ;显示
- XIANSHI:
- mov a,wendudang
- cpl a ;取反
- swap a ;高低四位交换
- ANL A,#11110000B ;获高四位
- mov R0,a
- mov a,p1
- anl a,#00001111B ;获低四位
- orl a,R0 ;整合高低八位
- mov p1,a ;驱动LED
- XIANSHIret:
- ret
- ;****************
- ;xunhuan ;循环 次数
- xunhuan:
- lcall DELAY ;延时
- INC XUN_JSHQ ;循环计数加1
- mov a,XUN_JSHQ
- cjne a,#200,xunhuanret
- mov XUN_JSHQ,#0
- clr 20h.0 ;停止按键后循环200次约??秒,结束设温度档程序
- xunhuanret:
- RET
- ;******************
- ;延时 0.04秒
- DELAY:
- MOV R7,#250
- D1: MOV R6,#250
- DJNZ R6,$
- DJNZ R7,D1
- RET
- ;*****************
- ;先擦除再写入,然后关闭
- clear_write:
- mov contr,#84h ;设定操作时间
- mov cmd,#03h ;设定擦除操作
- mov drl,#00h ;设定存储单元地址低四位
- mov drh,#00h ;设定存储单元地址高四位 这里设0000h
- mov trig,#5AH ;准备触发
- mov trig,#0A5h ;触发
- nop
- nop
- ;---------写-------------------
- write:
- mov contr,#84h ;设定操作时间
- mov cmd,#02h ;设定写操作
- mov drl,#00h ;设定存储单元地址低四位
- mov drh,#00h ;设定存储单元地址高四位 这里设0000h
- ; MOV A,wendudang
- mov dat,wendudang ;wendudang中为准备写入的数据
- mov trig,#5AH ;准备触发
- mov trig,#0A5H ;触发
- nop
- nop
- ;=========关闭EEPROM====================
- off:
- mov contr,#0 ;禁止操作
- mov cmd,#0 ;去除操作命令
- mov trig,#0 ;防止命令误触发
- mov drl,#0 ;指向非EEPROM区
- mov drh,#80H ;指向非EEPROM区
- ret
-
- ;*********************************** 充电有关的计时 ******************************
- ;****************
- ;走时 统计20mS的个数,计时,设立半秒标志、分标志、时标志
- PRO_ZOUSHI:
- JNB 22H.0,PROARET ;20mS标志位
- INC JSHQ_20MS
- CLR 22H.0
- mov A,#25 ;25个20mS为半秒
- CJNE A,JSHQ_20mS,PROARET
- MOV JSHQ_20mS,#0
- inc jshq_S
- setb 20h.2 ;控制显示的半秒标志
- PROA_1:
- MOV A,#30
- CJNE A,JSHQ_S,PROARET
- MOV JSHQ_S,#0
- SETB 22H.5 ;15秒检测一次
- INC JSHQ_15
- MOV A,#4
- CJNE A,JSHQ_15,PROARET
- MOV JSHQ_15,#0
- INC JSHQ_M
- MOV A,#60 ;60分为1小时
- CJNE A,JSHQ_M,PROARET
- MOV JSHQ_M,#0
- setb 22h.3 ;时标志
- PROARET:
- RET
- ;********************
- ;开机时数 开机10小时停充电,开机240小时重新启动单片机。
- KAIJISHISHU:
- JNB 22H.3,KAIJISHISHURET
- clr 22h.3
- INC JSHQ_H
- MOV A,#10 ;最多充电10小时
- CJNE A,JSHQ_H,KAIJISHISHU_1
- CLR 21H.6 ;初值1,充电10小时清0。
- setb kong ;断220V交流
- JMP KAIJISHISHURET
- KAIJISHISHU_1:
- mov a,#240 ;十天重启
- cjne a,jshq_h,KAIJISHISHURET
- MOV IAP_CONTR,#00100000B ;热重启
- KAIJISHISHURET:
- RET
- ;*******************
- ;检测设定 每15秒进行一次 两次测电压相同 确定占空比 温度检测没使用
- jiacesheding:
- ; MOV P1,#11111111B ;关显示 再延时 防止电压波动对AD转换的影响
- ; LCALL DELAY ;延时0.4秒
- dianya:
- lcall PRO_ad ;AD转换测电瓶电压
- MOV jiace_adzhi1,jiace_adzhi
- mov jiace_adzhi,#0
- lcall PRO_ad ;AD转换测电瓶电压
- BiJiao: ;比较两次测电压结果 同-进入下一步 不同-重测
- mov a,jiace_adzhi1
- cjne a,jiace_adzhi,dianya
-
- jiaceshedingret:
- ret
- ;********************
- ;AD转换测电瓶电压
- PRO_ad:
- MOV P1ASF,#0000001B ;P1.0做AD检测
- MOV ADC_RES,#0 ;转换结果寄存器清零
- MOV ADC_CONTR,#11100000B
- nop
- nop
- nop
- nop
- mov a,#11101000b
- MOV ADC_CONTR,A ;开始A/D转换
- NOP ;在质询之前一定等候
- NOP
- NOP
- NOP
- WAIT:
- MOV A,ADC_CONTR ;等候完成的标志
- JNB ACC.4,WAIT ;转换完成标志位 不是1就转
- MOV ADC_CONTR,#01100000B ;关转换 清标志位
-
- MOV jiace_adzhi,ADC_RES ;读出AD值保存
- PRO_adRET:
- RET
- ;********************
- jiaceTL431:
- ; MOV P1,#11111111B ;关显示 再延时 防止电压波动对AD转换的影响
- ; LCALL DELAY ;延时0.4秒
- dianyaTL:
- lcall prTL431_ad ;AD转换测TL431的AD
- MOV TL431_AD1,TL431_AD
- mov TL431_AD,#0
- lcall prTL431_ad ;AD转换测TL431的AD
- BiJiaoTL: ;比较两次测电压结果 同-进入下一步 不同-重测
- mov a,TL431_AD1
- cjne a,TL431_AD,dianyaTL
- jiaceTL431ret:
- ret
- ;******************
- ;AD转换测TL431
- prTL431_ad:
- MOV P1ASF,#0000010B ;P1.1做AD检测
- MOV ADC_RES,#0 ;转换结果寄存器清零
- MOV ADC_CONTR,#11100001B
- nop
- nop
- nop
- nop
- mov a,#11101001b
- MOV ADC_CONTR,A ;开始A/D转换
- NOP ;在质询之前一定等候
- NOP
- NOP
- NOP
- TL431WAIT:
- MOV A,ADC_CONTR ;等候完成的标志
- JNB ACC.4,TL431WAIT ;转换完成标志位 不是1就转
- MOV ADC_CONTR,#11100001B ;关转换 清标志位
-
- MOV TL431_AD,ADC_RES ;读出AD值保存
- TL431_adRET:
- RET
- ;*******************
- ;比较 ;通过电瓶电压整数与终止电压整数比较,电瓶电压小数与终止电压小数比较,确定并标记电瓶有无充满.
- probijiao:
- clr c
- mov a,v_ZH ;电瓶电压整数
- CJNE A,U_zhongzhizheng,bijiao_1 ;电瓶电压整数与终止电压整数比较
- MOV A,V_XAO
- CJNE A,U_zhongzhixiao,bijiao_1 ;电瓶电压小数与终止电压小数比较
-
- bijiao_0:
- clr 21h.4 ;电瓶正常标志位 1--正常 0--充满(或不能充电)
- JMP bijiao_ret
- bijiao_1:
- JC bijiao_0 ;超过终止电压 C=1
-
- bijiao_ret:
- ret
-
- ;******************
- ; ;控制充断电
- PROKongZhi:
- jb 21h.4,pro_a ;电瓶正常标志 1-正常 0-不正常 无电瓶 或充满
- setb kong ;通过光耦控制220V通断 0-通 1-断
- pro_a:
- JB 21H.6,PROKongZhiRET
- setb kong ;通过光耦控制220V通断 0-通 1-断
- PROKongZhiRET:
- RET
- ;****************
- ;显缓
- XIANhuan:
- MOV A,v_ZH ;电瓶伏特整数
- MOV B,#10
- DIV AB
- MOV 61H,B ;个位
- MOV 60H,A ;十位
- MOV 62H,V_XAO ;小数
-
- MOV 63H,#0 ;黑屏的数字
- mov 64h,#00001111B ;四灯全亮
- XIANhuan_ret:
- ret
- ;***************
- ; xiu_V 显伏特数 十、个位、小数位分别显示,每位显示2秒,黑屏1秒,三位显示完黑屏3秒。
- xiu_V:
- JNB 20H.2,XianZ ;每秒运行一次
- CLR 20H.2
- INC JSHQ_WEI
- MOV A,#11
- CJNE A,JSHQ_WEI,xiu_V_1
- MOV JSHQ_WEI,#0
- mov R1,60H ;显十位
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_1:
- MOV A,#1 ;显示十位
- CJNE A,JSHQ_WEI,xiu_V_2
- nop ;保持原显示就行了
- ;mov R1,60H
- ;LCALL PROXIAN
- XianZ: jmp xiu_VRET ;中间跳板
- xiu_V_2:
- MOV A,#2 ;黑屏
- CJNE A,JSHQ_WEI,xiu_V_3
- mov R1,63H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_3:
- MOV A,#3 ;显示个位
- CJNE A,JSHQ_WEI,xiu_V_4
- mov R1,61H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_4:
- MOV A,#4 ;显示个位
- CJNE A,JSHQ_WEI,xiu_V_5
- nop ;保持原显示就行了
- ;mov R1,61H
- ;LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_5:
- MOV A,#5 ;黑屏
- CJNE A,JSHQ_WEI,xiu_V_6
- mov R1,63H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_6:
- MOV A,#6 ;显示小数位
- CJNE A,JSHQ_WEI,xiu_V_7
- mov R1,62H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_7:
- MOV A,#7 ;显示小数位
- CJNE A,JSHQ_WEI,xiu_V_8
- nop ;保持原显示就行了
- ;mov R1,62H
- ;LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_8:
- MOV A,#8 ;黑屏
- CJNE A,JSHQ_WEI,xiu_V_9
- mov R1,63H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_9:
- MOV A,#9 ;四灯全亮
- CJNE A,JSHQ_WEI,xiu_V_10
- mov R1,64H
- LCALL PROXIAN
- JMP xiu_VRET
- xiu_V_10:
- nop ;保持原显示就行了
- ;mov R1,63H ;黑屏
- ;LCALL PROXIAN
- xiu_VRET:
- RET
- ;***************
- ;显示
- PROXIAN:
- MOV A,R1
- cpl a ;取反
- swap a ;高低四位交换
- ANL A,#11110000B ;获高四位
- mov R0,a
- mov a,p1
- anl a,#00001111B ;获低四位
- orl a,R0 ;整合高低八位
- mov p1,a ;驱动LED
- RET
- ;*******************************
- ;计算 jì suàn 电瓶电压伏特数=(电瓶AD值×37+电瓶AD值×0.86)÷基准电压AD值 TL431稳压后是2.524伏
- ;求出伏特整数和一位小数
- JISUAN:
- MOV v_ZH,#0 ;存伏特整数 先清0
- mov V_XAO,#0 ;伏特小数 先清0
- mov r2,#0
- mov r3,#0
- ;电瓶AD值×37
- MOV A,Jiace_ADzhi ;电瓶AD值
- MOV B,#37
- MUL AB
- MOV R2,A ;37倍的积的低8位 存R2
- MOV R3,B ;37倍的积的高8位 存R3
- ;电瓶AD值×86
- MOV A,Jiace_ADzhi
- mov b,#86 ;
- MUL AB ;86倍的积高位在B低位在A 高位在B
- ;除以100
- MOV beichushugao,B ;被除数高位
- MOV beichushudi,A ;被除数低位
- MOV chushu,#100 ;除数
- mov zhengshang,#0 ;整数商
- mov XIAOSHUSHANG,#0 ;小数商
- mov YUSHU,#0 ;余数
-
- LCALL PROCHU
- ;电瓶AD值×0.86的整数部分已经在zhengshang
- ;电瓶AD值×37与电瓶AD值×0.86两积之和
- mov a,zhengshang
- ADD A,R2
- MOV R2,A
- JNC JISUAN_1 ;0-跳
- INC R3
- clr c ;以上完成了(电瓶AD值×37+电瓶AD值×0.86) 值的高位在R3,低位在R2
- JISUAN_1:
- ;下面用减法代除法做[÷基准电压AD值]部分
- MOV beichushugao,R3 ;被除数高位
- MOV beichushudi,R2 ;被除数低位
- MOV chushu,TL431_AD ;除数
- mov zhengshang,#0
- mov XIAOSHUSHANG,#0
- mov YUSHU,#0
-
- LCALL PROCHU
- MOV v_ZH,zhengshang ;伏特整数
- MOV V_XAO,XIAOSHUSHANG ;伏特小数
- RET
- ;*********************
- ;除法 被除数有高8位低8位,除数只有8位,商有8位整数1位小数
- ;beichushugao ;被除数高位
- ;beichushudi ;被除数低位
- ;chushu ;除数
- ;zhengshang EQU 78H ;整数商
- ;XIAOSHUSHANG EQU 79H ;小数商
- ;YUSHU EQU 7AH ;余数
- ;LSSHU EQU 7BH ;临时存
- ; DISHU 低位 第二次的被除数低位
- ;GAOSHU 高位 第二次的被除数高位
- PROCHU:
- MOV A,#0
- CJNE A,beichushugao,PROCHU_0 ;高位不是0 跳
- MOV A,beichushudi
- jmp PROCHU_A ;跳到高位是0,求低位的商
- PROCHU_0: ;求高位不是0部分的商
- MOV A,beichushudi
- PROCHU_01:
- SUBB A,chushu
- INC zhengshang
- JNC PROCHU_01
- DJNZ beichushugao,PROCHU_01
- PROCHU_A: ;高位是0,求低位的商
- ; MOV LSSHU,A ;备份
- SUBB A,chushu
- INC zhengshang
- JNC PROCHU_A ;c=0 循环再减
- CLR C ;有借位,表示多减了一次
- ; DEC zhengshang ;恢复
- ; MOV A,LSSHU ;恢复
- ;*************求小数**********
- MOV B,#10 ;求小数,先将被除数乘10
- MUL AB
- MOV GAOSHU,B ;高位
- MOV DISHU,A ;低位
- PROCHU_B:
- MOV A,#0
- CJNE A,GAOSHU,PROCHU_B0
- MOV A,DISHU
- JMP PROCHU_C ;跳到高位是0 求低位商
- PROCHU_B0:
- MOV A,DISHU
- PROCHU_B01:
- SUBB A,chushu
- INC XIAOSHUSHANG
- JNC PROCHU_B01
- DJNZ GAOSHU,PROCHU_B01
- PROCHU_C: ;高位是0 求低位商
- MOV LSSHU,A
- SUBB A,chushu
- INC XIAOSHUSHANG
- JNC PROCHU_C ;c=0 循环再减
- CLR C ;有借位,表示多减了一次
- ; DEC XIAOSHUSHANG ;恢复 实测显示数据偏小所以删此句
- MOV A,LSSHU ;恢复
- MOV YUSHU,A ;余数
- ret
- ;****************
-
- ;**********************************************************************
- TIME_0: ;20毫秒@10.911MHz
- PUSH ACC
- PUSH PSW
- MOV TL0,#0F7H
- MOV TH0,#0B8H
- SETB 22H.0 ;20mS标志 专供走时用
- POP PSW
- POP ACC
- RETI
- ;************************
- pppuuu:
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- lcall START
- nop
- nop
- nop
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
源码和hex.rar
(8.02 KB, 下载次数: 41)
|