|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
上次制作的电风扇长定时+自然风,一直觉得不自然,现在升级加了个“渐慢——渐快”变化方式和慢速档(按编码器开关3次快速进入转速调整),用起来不那么生硬,仍然保留间歇通/断电方式。升级版需增加一个过零检测电路接到外部中断INT0,编码器的A、B、K改接P3.3(INT1)、P3.4、P3.5,不能用按键代替编码器了,转速调整共设20级,再往上调变化不明显,意义不大。改变可控硅导通角的调速方式电机会产生嗡嗡响的噪音,所以采用每间隔1~20个过零检测信号脉冲,截止一个正半周一个负半周的调速方式,但也有缺点,低速时电机会有抖动现象,只要速度不调得太低,影响不大。本人只知道一点点汇编语言,别的语言也不懂,从自学编程到现在,算起来平均一年编程不到一次,并不熟练,应该会有很多不规范和罗嗦的地方
原理图:
源程序:
- ;STC89C51RC+TM1637显示模块+EC11编码器,电风扇长定时+自然风汇编程序
- ;杨小强,2020年7月
- ;晶振:11.0592MHz
- ;显示:(TM1637)4位数码管显示模块
- ;调整、设置:EC11带开关5脚旋转编码器
- ;电源:闲置5V手机充电器
- ;
- ;最长定时99小时59分59秒;自然风周期可调,有渐慢——渐快、间歇通/断电两种方式可选择
- ;如果过零检测不接或者有故障将没有慢速功能,自然风自动改为间歇通/断电方式
- ;
- ;按编码器开关1次:常速/自然风切换
- ;按编码器开关2次:常速/慢速切换。两次按键动作之间不大于0.6秒
- ;按编码器开关3次:快速进入慢速时的转速调整,1~20级;自然风状态渐慢时降到这里设置的转速。
- ; 12级以上时转速调整变化不明显,自然风状态将没有渐慢——渐快循环。
- ; 60秒无任何操作或按编码器开关自动保存并退出。
- ;
- ;长按编码器开关5秒以上15秒以内,松开按键后进入设置状态,设置完第7项按编码器开关1次后又跳转到第一项
- ;退出设置状态:15秒无任何操作或按编码器开关2次自动保存并退出。
- ;根据数码管左边显示的数字进行以下各项设置,通过旋转编码器加或减,按编码器开关1次进入下一项设置:
- ;一、显示1——设置自然风状态时,常速——慢速周期时长,10~60秒,默认20秒
- ;二、显示2——设置自然风间歇通/断电方式时常速通电时长,最短为1秒;最长为上一项所设的周期减3秒
- ;三、显示3——设置3小时以下定时调整时,编码器每转动一格的增(减)值:5、10、15、20、25、30分钟,默
- ; 认10分钟,3小时以上增(减)值30分钟;10小时以上增(减)值1个小时;20小时以上增(减)值2个小时
- ;四、显示4——设置电风扇插电就自动填入的定时时间,0~30小时,默认8小时
- ;五、显示5——设置数码管亮度,1~8级,默认为3级
- ;六、显示6——设置自然风方式,0=渐慢——渐快变化方式,1=间歇通/断电方式
- ;七、显示7——设置慢速状态时的转速,1~20级,本项60秒无任何操作自动保存并退出。
- ;
- ;长按编码器开关15秒:恢复各项默认设置,数码管显示88:88
- ;设置保存失败显示5秒E1
- ;
- ;--------------------------- 端口定义 ---------------------------
- CLK EQU P1.5 ;接显示模块TM1637的CLK
- DIO EQU P1.6 ;接显示模块TM1637的DIO
- GLJC EQU P3.2 ;过零检测,外部中断INT0
- EC11A EQU P3.3 ;接编码器的A引脚,外部中断INT1
- EC11B EQU P3.4 ;接编码器的B引脚
- EC11K EQU P3.5 ;接编码器的按键开关引脚
- RLED EQU P0.4 ;慢速状态LED指示灯,低电平亮;单片机发生复位时也亮
- LED EQU P0.5 ;自然风状态LED指示灯,低电平亮
- MOC EQU P0.7 ;接MOC3022光控可控硅,低电平时风扇电机通电
- ;--------------------------- 位地址及RAM的使用 ---------------------------
- ;(20H)第0位:1=编码器已经转动,等待主程序处理,0=没有转动或主程序已处理
- ;(20H)第1位:1=编码器顺时针正转;0=编码器逆时针反转
- ;(20H)第2位:1=自然风状态;0=正常状态
- ;(20H)第3位:1=禁止;0=允许。进行各项设置时使用,允许/禁止检查剩余时间
- ;(20H)第4位:1=闪烁显示;0=不闪烁。进行各项设置时用
- ;(20H)第5位:1=不显示,0=显示,数字及冒号闪烁时用,由T0中断每0.5秒取反一次
- ;(20H)第6位:1=主程序显示3秒88:88或5秒E1;0=正常
- ;(20H)第7位:1=慢速状态;0=常速。“常速/慢速”切换
- ;(21H)第8位:1=允许;0=禁止。渐变控制标志
- ;(21H)第9位:1=渐快;0=渐慢。渐变控制时的调速方向
- FWBZ1 EQU 022H ;复位判断标志1,也作EEPROM数据判断标志
- FWBZ2 EQU 023H ;复位判断标志2,也作EEPROM数据判断标志
- ZRFZQ EQU 024H ;自然风时状态常速——慢速变化周期时长
- ZRFSJ EQU 025H ;自然风时电机常速通电时长
- BMQZJ EQU 026H ;编码器每转动一小格的增(减)值
- SDDS EQU 027H ;上电就自动设定的定时时间(小时)
- SMGLD EQU 028H ;数码管亮度
- ZRFFS EQU 029H ;自然风方式
- MSZTZS EQU 02AH ;慢速状态转速
- DSSJS EQU 02BH ;定时时间,时
- DSSJF EQU 02CH ;定时时间,分
- DSSJM EQU 02DH ;定时时间,秒
- ZQ EQU 02EH ;T0、INT0中断使用,自然风常速——慢速周期时长
- SJ EQU 02FH ;T0、INT0中断使用,自然风时电机常速通电时长
- SJJS EQU 030H ;时间计数,每10毫秒减1,为0后定时时间减1秒,重新放入定义的计数值
- MJS EQU 031H ;按键处理时用,秒计数,每秒减1,直到为0
- SSSC EQU 032H ;闪烁时长,每秒减1,直到为0
- XSHC1 EQU 033H ;上次显示的内容,与当前不同就立即显示,相同就每0.5秒显示一次
- XSHC2 EQU 034H ;上次显示的内容,与当前不同就立即显示,相同就每0.5秒显示一次
- XXSZ EQU 035H ;下限数值,进行各项设置时用
- SXSZ EQU 036H ;上限数值,进行各项设置时用
- WCZSJ EQU 037H ;无操作时间,进行各项设置时用
- ZXM1 EQU 038H ;显示用,待发送到TM1637的字形码1
- ZXM2 EQU 039H ;显示用,待发送到TM1637的字形码2
- ZXM3 EQU 03AH ;显示用,待发送到TM1637的字形码3
- ZXM4 EQU 03BH ;显示用,待发送到TM1637的字形码4
- DSZJ EQU 03CH ;加减定时时间使用
- JCGLMC1 EQU 03DH ;检查过零脉冲用
- JCGLMC2 EQU 03EH ;检查过零脉冲用
- GLMC EQU 03FH ;过零脉冲计数
- DDMC EQU 040H ;断电脉冲计数
- MSZS EQU 041H ;T0、INT0中断使用,设置的转速级数
- JBJS1 EQU 042H ;T0、INT0中断使用,渐变计数
- JBJS2 EQU 043H ;T0、INT0中断使用,渐变计数
- JKTZSJ EQU 044H ;渐快——渐慢变化调整时用
- DISPL EQU 045H ;设置要显示的目标:
- ;0=显示定时时间
- ;1=显示1——设置自然风状态时的常速——慢速周期时长
- ;2=显示2——设置自然风时电机常速通电时长
- ;3=显示3——设置3小时以下定时调整时,编码器每转动一小格的增(减)值
- ;4=显示4——设置上电自动填入的定时时间
- ;5=显示5——设置数码管亮度
- ;6=显示6——设置自然风方式
- ;7=显示7——设置慢速时的转速
- ;--------------- 看门狗、EEPROM特殊功能寄存器地址 ---------------
- AUXR EQU 08EH ;辅助寄存器
- WDT_CONTR EQU 0E1H ;看门狗地址
- IAP_DATA EQU 0E2H ;数据寄存器,读出、写入的数据放在此处
- IAP_ADDRH EQU 0E3H ;地址寄存器高八位
- IAP_ADDRL EQU 0E4H ;地址寄存器低八位
- IAP_CMD EQU 0E5H ;命令寄存器,0=关闭,1=读,2=写,3=擦除
- IAP_TRIG EQU 0E6H ;命令触发寄存器,每次操作先放入46H再放入B9,命令立即被触发起动
- IAP_CONTR EQU 0E7H ;控制寄存器,Flash操作允许/禁止及等待时间
- ENABLE_IAP EQU 083H ;定义Flash操作等待时间及允许IAP/ISP/EEPROM操作的常数,时钟<12MHz时为83H
- ;=====================================================================================
- ORG 0000H
- LJMP START
- ORG 0003H ;外部中断INT0入口
- LJMP INT_0 ;外部中断INT0入口
- ORG 000BH ;T0中断入口
- LJMP T0INT ;T0中断入口
- ORG 0013H ;外部中断INT1入口
- LJMP INT_1 ;外部中断INT1入口
- ORG 0030H ;程序代码始址安排在30H
- ;----------------------------------------------------------------------------------------
- ;定义时间计数值,当定时时间实际走时误差较大时,可调整此数值使误差减小
- ;例如每分钟快7秒,就把此数值改为112D(7秒÷60秒×100≈12,12+100=112);每分钟慢6秒,就
- ;把此数值改为90D(6秒÷60秒×100=10,100-10=90)
- ;----------------------------------------------------------------------------------------
- HMJS: DB 100D ;定义时间计数值,100表示100×10毫秒=1秒,后面的D表示是十进制数
- ;--------------- 定时器0中断(10毫秒产生一次中断) ---------------
- T0INT: PUSH ACC
- PUSH PSW
- LCALL TIME ;处理各项时间
- LCALL DISPLAY ;显示
- LCALL JCGLMC ;检查过零检测脉冲,如果有故障就由本中断控制可控硅、LED指示灯
- POP PSW
- POP ACC
- RETI
- ;--------------- 外部中断INT0,接过零检测电路,控制转速、状态LED指示灯 ---------------
- INT_0: PUSH ACC
- PUSH PSW
- LCALL Control ;根据条件控制可控硅、状态LED指示灯
- POP PSW
- POP ACC
- RETI
- ;------ 外部中断INT1,P3.3接编码器A引脚 ------
- INT_1: SETB EC11B ;拉高编码器B引脚电平
- PUSH PSW
- JB 00H,INT1_2 ;如果位地址0H为1就退出中断处理程序,等待主程序处理
- SETB 00H ;把位地址00H置为1,表示编码器已转动,等待主程序处理
- JB EC11B,INT1_1 ;如果编码器B引脚为1(高电平)就转移,说明是顺时针正转
- CLR 01H ;是0(低电平),逆时针反转,把位地址01H置为0
- LJMP INT1_2
- INT1_1: SETB 01H ;是顺时针正转,把位地址01H置为1
- INT1_2: POP PSW
- RETI
- ;--------------- 设置各项默认值 ----------------
- SZMRZ: MOV ZRFZQ,#20 ;自然风状周期时长(秒)
- MOV ZRFSJ,#5 ;自然风间歇通/断电方式时的电机通电时长(秒)
- MOV BMQZJ,#10 ;编码器每转动一小格的+、-值(分钟))
- MOV SDDS,#8 ;上电就自动设定的定时时间(小时)
- MOV SMGLD,#3 ;数码管亮度,8级亮度最高
- MOV ZRFFS,#0 ;自然风方式,0=渐慢——渐快循环方式
- MOV MSZTZS,#8 ;慢速状态转速
- RET
- ;--------------- T0、INT0、INT1中断设置 ----------------
- SETINT: ANL AUXR,#7FH ;定时器时钟12T模式
- ANL TMOD,#0F0H ;设置定时器模式
- MOV TL0,#000H ;设置定时初值,10毫秒产生一次中断(晶振:11.0592MHz)
- MOV TH0,#0DCH ;设置定时初值,10毫秒产生一次中断(晶振:11.0592MHz)
- CLR TF0 ;清除TF0标志
- SETB ET0 ;允许定时器0中断
- SETB TR0 ;定时器0开始计时
- SETB IT0 ;设外部中断INT0为下降沿触发
- SETB EX0 ;允许外部中断INT0
- SETB PX0 ;设外部中断INT0为高优先级
- SETB IT1 ;设外部中断INT1为下降沿触发
- SETB EX1 ;允许外部中断INT1
- SETB EA ;允许全局中断
- RET
- ;---- 启动看门狗及喂狗,11.0592MHz预分频数=4(142.2毫秒),00111001B(39H) ----
- WG: MOV WDT_CONTR,#00111001B
- RET
- ;********************************* 主程序开始 ********************************
- START: MOV SP,#050H ;设置堆栈指针
- MOV A,FWBZ1 ;
- CJNE A,#0C8H,START0 ;
- MOV A,FWBZ2 ;检查复位判断标志,不相同说明是初次上电,从初始化开始运行
- CJNE A,#0D9H,START0 ;
- LCALL SETINT ;中断设置
- CLR RLED ;RAM内容没变,说明是被干扰等原因复位,不是初次上电,点亮复位LED指示灯
- MOV A,DISPL ;
- CJNE A,#7,SAT ;不管是什么原因复位,只要RAM不被改变就跳过初始化,继续运行
- LJMP STARTD ;
- SAT: CJNE A,#6,SAT0 ;
- LJMP STARTC
- SAT0: CJNE A,#5,SAT1 ;
- LJMP STARTB ;
- SAT1: CJNE A,#4,SAT2 ;
- LJMP STARTA ;
- SAT2: CJNE A,#3,SAT3 ;根据DISPL的内容跳转到复位前的位置
- LJMP START9 ;
- SAT3: CJNE A,#2,SAT4 ;
- LJMP START8 ;
- SAT4: CJNE A,#1,START2 ;
- LJMP START7 ;
- START0: CLR A
- MOV R0,#30H ;
- MOV R1,#20H ;
- START1: MOV @R1,A ;初始化,从RAM地址20H开始清零30H个字节
- INC R1 ;
- DJNZ R0,START1 ;
- LCALL SETINT ;初始化,中断设置
- MOV FWBZ1,#0C8H ;初始化,放入复位判断标志1到RAM
- MOV FWBZ2,#0D9H ;初始化,放入复位判断标志2到RAM
- LCALL REEP ;初始化,读EEPROM保存的各项设置,如果没有就设为默认值并保存
- SETB RLED ;初始化,设RLED为高电平,复位LED指示灯不亮
- ;
- START2: LCALL WG ;喂狗
- MOV DISPL,#0 ;设置要显示的目标,0=显示定时时间
- CLR 06H ;位地址06H置为0,显示定时时间
- JNB 00H,START3 ;如果位地址00H为0(编码器没有转动)就转移
- SETB EC11A ;拉高编码器A引脚电平
- SETB EC11B ;拉高编码器B引脚电平
- JNB EC11A,START3 ;如果仍为0(低电平)就转移,说明还没有旋转到卡点位置
- JNB EC11B,START3 ;如果仍为0(低电平)就转移,说明还没有旋转到卡点位置
- LCALL DSSJZJ ;AB引脚都为高电平了,已经旋转到卡点位置,根据方向增减定时时间
- CLR 00H ;把位地址00H置为0,表示已经响应并处理编码器旋转动作
- START3: LCALL SKEY ;扫描编码器按键开关
- JNC START2 ;没有按键动作(C=0)就转移
- LCALL KEY ;有按键动作,调用编码器按键开关处理子程序
- CJNE A,#1,START4 ;如果不是按下1次(正常/自然风切换)就转移
- JNB 07H,STAT2 ;如果当前不是慢速状态就转移
- CLR 07H ;是慢速状态,位地址第07位置为0,先退出慢速状态
- STAT1: SETB RLED ;关LED2
- LJMP START2
- STAT2: CPL 02H ;位地址第02位取反,自然风/正常状态切换
- MOV MSZS,MSZTZS ;把设置的慢速状态转速放入MSZS
- MOV ZQ,#0
- MOV SJ,#0
- LJMP START2
- START4: CJNE A,#2,STAT3 ;如果不是2(正常/慢速之间切换)就转移
- CPL 07H ;是按2次,位地址第07位取反,“正常/慢速”状态切换
- JNB 07H,STAT1 ;如果取反后不是慢速状态就转移,关LED2
- CLR RLED ;是慢速状态,点亮LED2
- LJMP START2
- STAT3: CJNE A,#3,START5 ;如果不是3(设置慢速状态时的转速)就转移
- LCALL MSSZ ;设置慢速状态时的转速
- LJMP START2
- START5: CJNE A,#5,START7 ;如果不是5(恢复默认设置)就转移
- LCALL SZMRZ ;恢复各项默认设置
- SETB 06H ;把位地址06H设置为1,数码管显示3秒88:88
- MOV SSSC,#3 ;3秒
- MOV ZXM1,#0FFH ;8
- MOV ZXM2,#0FFH ;8
- MOV ZXM3,#0FFH ;8
- MOV ZXM4,#0FFH ;8
- LCALL DISP ;显示
- START6: MOV A,SSSC
- LCALL WG ;喂狗
- JNZ START6 ;等待SSSC为0秒
- LCALL WSET ;保存设置
- LCALL KEYEX ;等待按键松开
- LJMP START2
- START7: MOV DISPL,#1 ;是4,进入各项设置,1=显示“1——设置自然风状态时通断电周期时长”
- LCALL ZQSZ ;周期时长设置
- JNZ START8 ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2 ;是15秒无操作自动保存返回,设置结束
- START8: MOV DISPL,#2 ;2=显示“2——设置自然风时电机通电时长”
- LCALL TDSC ;通电时长设置
- JNZ START9 ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2
- START9: MOV DISPL,#3 ;3=显示“3——设置2小时以下定时调整时,编码器每转动一格的增(减)值”
- LCALL BMQZJZ ;编码器增减值设置
- JNZ STARTA ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2
- STARTA: MOV DISPL,#4 ;4=显示“4——设置插电自动填入的定时时间”
- LCALL SDDSSJ ;上电定时时间设置(小时)
- JNZ STARTB ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2
- STARTB: MOV DISPL,#5 ;5=显示“5——设置数码管亮度”
- LCALL LDSZ ;亮度设置
- JNZ STARTC ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2
- STARTC: MOV DISPL,#6 ;6=显示“6——设置自然风方式”
- LCALL FSSZ ;自然风方式设置
- JNZ STARTD ;如果是按下编码器按键开关返回,就转移,进行下一项设置
- LJMP START2
- STARTD: MOV DISPL,#7 ;7=显示“7——设置慢速时的转速”
- LCALL MSSZ ;慢速转速设置
- JNZ START7 ;如果是按下编码器按键开关返回,就转移到第一项设置
- LJMP START2 ;是15秒无操作自动保存返回,设置结束
- ;-------------------------------------------------------------------------------------
- ;子程序:根据编码器旋转方向加减定时时间。
- ;3小时及以下,按设置的值加减:5、10、15、20、25、30分钟
- ;3小时以上每次增(减)30分钟;10小时以上每次增(减)1个小时;20小时以上每次增(减)2个小时
- ;-------------------------------------------------------------------------------------
- DSSJZJ: MOV DSSJM,#59 ;先放入59到定时时间(秒)
- MOV A,DSSJS ;装入定时时间(时)
- CJNE A,#20,DSZJ1 ;当前“时”是否等于或大于20
- DSZJ1: JC DSZJ2 ;小于就转移
- MOV DSZJ,#2 ;等于或大于20,加减2个小时
- LJMP DSZJ4
- DSZJ2: CJNE A,#10,DSZJ3 ;当前“时”是否等于或大于10
- DSZJ3: JC DSZJ8 ;小于就转移
- MOV DSZJ,#1 ;等于或大于10,加减1个小时
- DSZJ4: JNB 01H,DSZJ6 ;如果位地址01H为0(逆时针反转)就转移
- ADD A,DSZJ ;是正转,加
- CJNE A,#100,DSZJ5 ;加完后是否等于或大于100
- DSZJ5: JC DSZJ7 ;如果小于就转移,把A放回到DSSJS
- MOV DSSJS,#99 ;已经大于99了,直接设置为99:59:59
- MOV DSSJF,#59 ;已经大于99了,直接设置为99:59:59
- RET
- DSZJ6: SUBB A,DSZJ ;是反转,减
- DSZJ7: MOV DSSJS,A ;把计算结果放入DSSJS
- RET
- DSZJ8: MOV DSZJ,BMQZJ ;把设置的“增(减)值”放入DSZJ
- CJNE A,#3,DSZJ11 ;当前“时”不是3就转移
- JB 01H,DSZJ12 ;是3,如果位地址01H为1(正转)就转移,把DSZJ处的“增(减)值”改为30(分钟)
- MOV A,DSSJF ;是反转,装入定时时间(分)
- JZ DSZJ13 ;如果当前“分”为0(3:00)就转移,按设置的增(减)值减
- CJNE A,#30,DSZJ9 ;“分”不为0,是否等于或大于30
- DSZJ9: JC DSZJ10 ;小于就转移,把0放入定时时间(分),使时间变为3:00
- SUBB A,#30 ;等于或大于,减30分
- MOV DSSJF,A ;把计算结果放入定时时间(分)
- RET
- DSZJ10: MOV DSSJF,#0 ;小于30,把0放入定时时间(分),使时间变为3:00
- RET
- DSZJ11: JC DSZJ13 ;小于3就转移
- DSZJ12: MOV DSZJ,#30 ;大于3:00,把DSZJ处的“增(减)值”改为30(分钟)
- DSZJ13: MOV A,DSSJF ;装入定时时间(分)
- JNB 01H,DSZJ16 ;如果位地址01H为0(逆时针反转)就转移
- ADD A,DSZJ ;是正转,当前“分”直接加DSZJ处的“增(减)值”
- CJNE A,#60,DSZJ14 ;加完后“分”是否等于或大于60
- DSZJ14: JC DSZJ15 ;小于60就转移,把A放入定时时间(分)
- SUBB A,#60 ;等于或大于60,就减60,然后小时加1
- MOV DSSJF,A ;把A放入定时时间(分)
- MOV A,DSSJS ;装入“时”
- INC A ;小时加1
- MOV DSSJS,A
- CJNE A,#3,DSZJ19 ;加完后“时”不是3就转移,退出
- CLR A ;加完后大于3:00了,把0放入定时时间(分),使时间变为3:00
- DSZJ15: MOV DSSJF,A
- RET
- DSZJ16: CJNE A,DSZJ,DSZJ17 ;是逆时针反转,当前“分”是否等于或大于DSZJ处的“增(减)值”
- DSZJ17: JC DSZJ20 ;小于就转移
- SUBB A,DSZJ ;等于或大于,定时时间(分)减“增(减)值”
- MOV DSSJF,A ;把计算结果放入定时时间(分)
- JZ DSZJ18 ;如果“分”为0就转移
- RET
- DSZJ18: CJNE A,DSSJS,DSZJ19 ;如果“时”不为0就转移
- MOV DSSJM,A ;“时、分”都为0,“秒”也清零
- DSZJ19: RET
- DSZJ20: MOV A,DSZJ ;“分”小于“增(减)值”,装入DSZJ处的“增(减)值”
- CLR C ;进位标志清0
- SUBB A,DSSJF ;“增(减)值”减“定时时间(分)”
- MOV DSSJF,A ;减完后的结果暂时放入DSSJF
- MOV A,#60
- SUBB A,DSSJF ;60减上面的计算结果,得出定时时间(分),然后小时减1
- MOV DSSJF,A ;得出的数放入定时时间(分)
- MOV A,DSSJS ;装入定时时间(时)
- JZ DSSJQL ;如果“时”为0就转移(不够减了,把定时时间清零)
- DEC DSSJS ;“时”不为0,减1
- RET
- DSSJQL: CLR A
- MOV DSSJS,A ;定时时间清零
- MOV DSSJF,A ;定时时间清零
- MOV DSSJM,A ;定时时间清零
- RET
- ;----------------------------------------------------------------------------------------
- ;设置自然风周期时长
- ;----------------------------------------------------------------------------------------
- ZQSZ: MOV XXSZ,#10 ;下限为10秒
- MOV SXSZ,#60 ;上限为60秒
- LCALL LDSZ1 ;设置
- PUSH ACC
- MOV A,ZRFZQ ;装入自然风周期
- SUBB A,#3 ;减
- CJNE A,ZRFSJ,ZQSZ1
- ZQSZ1: JNC ZQSZ2 ;减完后等于或大于就转移
- MOV ZRFSJ,A ;小于,修改为减3后的数
- LCALL WSET ;保存设置
- ZQSZ2: POP ACC
- RET
- ;----------------------------------------------------------------------------------------
- ;设置自然风时电机常速通电时长,最短为1秒;最长为上一项所设的周期减3秒
- ;----------------------------------------------------------------------------------------
- TDSC: MOV A,ZRFZQ ;装入“自然风周期”
- SUBB A,#3 ;减
- MOV SXSZ,A ;放入上限值
- MOV XXSZ,#1 ;下限为1秒
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;设置2小时以下定时调整时,编码器每转动一小格的增(减)值,5、10、15、20、25、30分钟
- ;----------------------------------------------------------------------------------------
- BMQZJZ: MOV XXSZ,#5 ;下限为5
- MOV SXSZ,#30 ;上限为30
- MOV R4,#5 ;调整时的加减步长值
- LJMP LDSZ2
- ;----------------------------------------------------------------------------------------
- ;设置插电就自动填入的定时时间,0~30小时
- ;----------------------------------------------------------------------------------------
- SDDSSJ: MOV XXSZ,#0 ;下限为0小时
- MOV SXSZ,#30 ;上限为30小时
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;设置数码管亮度,1~8级,8级亮度最高
- ;----------------------------------------------------------------------------------------
- LDSZ: MOV XXSZ,#1 ;下限为1
- MOV SXSZ,#8 ;上限为8
- LDSZ1: MOV R4,#1 ;调整时的加减步长值
- LDSZ2: MOV WCZSJ,#15 ;无操作等待时间15秒
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;设置自然风方式,0=渐慢——渐快变化方式,1=间歇通/断电方式
- ;----------------------------------------------------------------------------------------
- FSSZ: MOV XXSZ,#0 ;下限
- MOV SXSZ,#1 ;上限
- LJMP LDSZ1
- ;----------------------------------------------------------------------------------------
- ;设置慢速时的转速,1~20级,本项60秒无任何操作自动保存并退出。
- ;----------------------------------------------------------------------------------------
- MSSZ: MOV DISPL,#7 ;7=显示“7——慢速状态时的转速设置”
- MOV XXSZ,#1 ;下限
- MOV SXSZ,#20 ;上限
- MOV R4,#1 ;调整时的加减步长值
- MOV WCZSJ,#60 ;无操作等待时间60秒
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;子程序:根据XXSZ、SXSZ设定的上下限范围、编码器旋转方向,调整DISPL指向的对象。
- ;无操作10秒后开始闪烁显示,15秒自动保存并退出;有按键动作就保存并退出
- ;入口参数:下限值放入XXSZ;上限值放入SXSZ;R4=加、减步长值
- ;出口参数:15秒无操作或按下2次以上自动保存退出A=0;按编码器按键开关1次保存退出A=1
- ;----------------------------------------------------------------------------------------
- SZTZ: MOV MJS,WCZSJ ;装入无操作等待时间到MJS
- CLR 03H ;位地址03H置为0,允许检查剩余时间
- SZTZ1: LCALL SKEY ;扫描编码器按键开关
- JNC SZTZ2 ;没有按键动作(C=0)就转移
- LCALL KEY ;有按键动作,调用编码器按键开关处理子程序
- CJNE A,#2,SZTZ11
- SZTZ11: JNC SZTZ3 ;如果是按下2次以上就转移
- CLR 04H ;把位地址04H置为0,不闪烁显示
- LCALL WSET ;保存设置
- MOV A,#1 ;按编码器按键开关1次保存退出A=1
- RET
- SZTZ2: JB 00H,SZTZ4 ;如果位地址00H为1(编码器已经转动)就转移
- MOV A,MJS ;没有转动,装入秒计数到寄存器A
- JZ SZTZ3 ;如果秒计数为0(15秒无操作)就转移
- JB 03H,SZTZ1 ;不为0,如果位地址03H为1就转移,不检查剩余时间
- CJNE A,#5,SZTZ1 ;检查剩余时间,如果不是5秒就转移,继续扫描编码器
- SETB 04H ;还剩5秒,把位地址04H置为1,设置为闪烁显示
- MOV SSSC,A ;闪烁时长5秒放入SSSC
- SETB 03H ;位地址03H置为1,禁止检查剩余时间
- LJMP SZTZ1
- SZTZ3: CLR 04H ;15秒时间到,把位地址04H置为0,不闪烁显示
- LCALL WSET ;保存设置
- CLR A ;15秒无操作自动保存退出A=0
- RET
- SZTZ4: CLR 04H ;编码器已经转动,把位地址04H置为0,不闪烁显示
- SETB EC11A ;拉高编码器A引脚电平
- SETB EC11B ;拉高编码器B引脚电平
- JNB EC11A,SZTZ ;如果仍为0(低电平)就转移,说明还没有旋转到卡点位置
- JNB EC11B,SZTZ ;如果仍为0(低电平)就转移,说明还没有旋转到卡点位置
- MOV A,DISPL ;AB引脚都为高电平,已经旋转到卡点位置了,装入要设置的目标项
- DEC A ;减1
- ADD A,#ZRFZQ ;加上各项设置的起始地址
- MOV R0,A ;把得出的具体地址放入R0
- JB 01H,SZTZ7 ;如果位地址01H为1(顺时针正转)就转移
- MOV A,XXSZ ;是反转,装入下限数值到A寄存器
- ADD A,R4 ;加步长值
- MOV MJS,A ;把下限值+步长值的结果暂时放入MJS
- MOV A,@R0 ;装入R0指向的RAM地址的调整对象数值
- CJNE A,MJS,SZTZ5 ;调整对象数值与“下限值+步长值”比较
- SZTZ5: JC SZTZ6 ;如果调整对象数值小于“下限值+步长值”(不够减)就转移
- SUBB A,R4 ;等于或大于,减步长值
- MOV @R0,A ;把计算结果放回去
- LJMP SZTZ10
- SZTZ6: MOV @R0,XXSZ ;不够减了,直接放入下限值
- LJMP SZTZ10
- SZTZ7: MOV A,@R0 ;是正转,装入R0指向的RAM地址的调整对象数值
- ADD A,R4 ;加步长值
- CJNE A,SXSZ,SZTZ8 ;加完后与上限数值比较
- SZTZ8: JC SZTZ9 ;如果小于就转移
- MOV @R0,SXSZ ;等于或大于,直接放入上限值
- LJMP SZTZ10
- SZTZ9: MOV @R0,A ;小于上限数值,把计算结果放回去
- SZTZ10: CLR 00H ;把位地址00H置为0,表示已经处理编码器旋转动作
- LJMP SZTZ
- ;----------------------------------------------------------------------------------------
- ;子程序:编码器按键开关处理
- ;出口参数:A=1(按了1次);A=2(按了2次);A=3(按了3次);A=4长按达到了5秒;A=5长按达到了15秒
- ;----------------------------------------------------------------------------------------
- KEY: MOV MJS,#15 ;放入等待时间,15秒
- KEY1: MOV A,MJS ;装入等待时间
- JNZ KEY2 ;如果不为0就转移,时间未到
- MOV A,#5 ;为0,时间到了,放入5到A寄存器,长按达到了15秒
- RET
- KEY2: LCALL SKEY ;扫描按键
- JC KEY1 ;如果C=1(按键还没松开),就继续扫描
- CJNE A,#10,KEY3 ;按键松开了,剩余时间与10比较,不等于就转移
- LJMP KEY4 ;等于10,长按时间达到了5秒(15-10=5)
- KEY3: JNC KEY5 ;大于10就转移
- KEY4: MOV A,#4 ;等于或小于10,放入4到A寄存器,长按时间达到了5秒以上
- RET
- KEY5: LCALL KEYA ;大于10,按下的时间小于5秒,扫描按键600毫秒
- JZ KEY6 ;如果600毫秒内有按键动作就转移
- RET ;600毫秒内没有按键动作,这时A=1(按了1次),退出
- KEY6: LCALL KEYEX ;等待第二次按键松开
- LCALL KEYA ;按键松开了,扫描按键600毫秒
- JZ KEY7 ;如果600毫秒内有按键动作就转移
- MOV A,#2 ;600毫秒内没有按键动作,A=2(按了2次)
- RET
- KEY7: LCALL KEYEX ;等待第三次按键松开
- MOV A,#3 ;第三次按键松开了,A=3(按了3次)
- RET
- ;------------------ 扫描按键开关600毫秒,有按键动作A=0,无按键动作A=1 ------------------
- KEYA: PUSH 03H
- MOV 03H,#60 ;等待600毫秒,10*60=600毫秒
- KEYB: MOV A,SJJS ;装入(10)毫秒计数
- KEYC: CJNE A,SJJS,KEYD ;如果不相同就转移,说明时间已经过了10毫秒
- LCALL SKEY ;扫描按键
- JC KEYE ;如果有按键动作(C=1)就转移
- LJMP KEYC
- KEYD: DJNZ 03H,KEYB ;03H减1,不为0就转移,继续扫描
- POP 03H
- MOV A,#1 ;600毫秒等待时间已到,A=1没有按键动作
- RET
- KEYE: POP 03H
- CLR A ;600毫秒内有按键动作A=0
- RET
- ;------------------ 等待按键松开 ------------------
- KEYEX: LCALL SKEY ;扫描按键
- JC KEYEX ;如果C=1(按键还没松开),就继续扫描
- RET
- ;------------------ 按键开关扫描,未按C=0,已按下C=1 ------------------
- SKEY: SETB EC11K ;按键开关设为高电平
- JNB EC11K,SKEY1 ;为0(低电平)就转移,表示按键开关已经被按下
- SKEY0: CLR C ;为1(高电平),C置为0,没有按键动作
- LCALL WG ;喂狗
- RET
- SKEY1: PUSH 00H ;按键已被按下,延时10毫秒
- PUSH 01H ;延时10毫秒
- MOV 00H,#87 ;延时10毫秒
- MOV 01H,#10 ;延时10毫秒
- SKEY2: DJNZ 01H,SKEY2 ;延时10毫秒
- DJNZ 00H,SKEY2 ;延时10毫秒
- POP 01H ;延时10毫秒
- POP 00H ;延时10毫秒
- SETB EC11K ;延时结束后再次把按键开关设为高电平
- JB EC11K,SKEY0 ;为1就转移,按键开关未被有效按下
- SETB C ;为1,按键动作有效,置C为1
- LCALL WG ;喂狗
- RET
- ;*************************** 以下为EEPROM操作子程序 **********************************
- ;STC89C51RC有4K字节的EEPROM,由8个扇区组成,每个扇区512字节,地址2000H-2FFFH
- ;第1扇区:2000H~21FFH,第2扇区:2200H~23FFH……第8扇区:2E00H~2FFFH
- ;-------------------------------------------
- ;读一字节,A=读出的数据
- Byte_Read:
- MOV IAP_CONTR,#ENABLE_IAP ;打开IAP功能,设置Flash操作等待时间(83H)
- MOV IAP_CMD,#01 ;设置为IAP/ISP/EEPROM字节读模式命令(1)
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被触发起动
- NOP
- MOV A,IAP_DATA ;读出的数据在IAP_DATA单元中,送入累加器A
- RET
- ;-------------------------------------------
- ;字节编程,A=需写入的数据
- Byte_Program:
- MOV IAP_CONTR,#ENABLE_IAP ;打开IAP功能,设置Flash操作等待时间(83H)
- MOV IAP_CMD,#02 ;设置为IAP/ISP/EEPROM字节编程模式命令(2)
- MOV IAP_DATA,A ;要编程的数据先送进IAP_DATA寄存器
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被触发起动
- RET
- ;-------------------------------------------
- ;擦除扇区
- Sector_Erase:
- MOV IAP_CONTR,#ENABLE_IAP ;打开IAP功能,设置Flash操作等待时间(83H)
- MOV IAP_CMD,#03 ;设置为IAP/ISP/EEPROM扇区擦除模式命令(3)
- MOV IAP_TRIG,#46H ;先送46H
- MOV IAP_TRIG,#0B9H ;再送B9H,ISP/IAP命令立即被触发起动
- NOP
- RET
- ;---------- 读EEPROM保存的各项设置,如果没有就设置为默认值并保存 ------------
- REEP: LCALL RE00 ;读EEPROM保存的各项设置
- MOV A,SDDS ;装入“上电就自动设定的定时时间(小时)”
- JZ REEP0 ;如果是0就转移,退出
- MOV DSSJS,A ;放入“定时时间(小时)”
- MOV DSSJM,#59 ;放入59到“定时时间(秒)”
- REEP0: RET
- RE00: MOV IAP_ADDRH,#020H ;从第一个扇区开始搜索,地址的高8位
- RE01: MOV IAP_ADDRL,#0 ;从第一个扇区开始搜索,地址的低8位
- LCALL Byte_Read ;读第一个字节,返回:A=读出的数据
- CJNE A,FWBZ1,RE03 ;是否保存在当前扇区,不是就转移到RE03
- INC IAP_ADDRL ;EEPROM字节地址增1
- LCALL Byte_Read ;读第二个字节
- CJNE A,FWBZ2,RE03 ;第二个字节是否相符
- MOV R1,#ZRFZQ ;相符,从ZRFZQ开始放置读出的设置值
- MOV R2,#7 ;总共7个字节
- RE02: INC IAP_ADDRL ;EEPROM字节地址增1
- LCALL Byte_Read ;读一个字节,返回:A=读出的数据
- MOV @R1,A ;放到R1指向的RAM地址
- INC R1 ;RAM地址增1
- DJNZ R2,RE02 ;未读完就继续
- RET ;读完了,退出
- RE03: MOV A,IAP_ADDRH ;装入扇区地址的高8位
- ADD A,#2 ;扇区增1
- MOV IAP_ADDRH,A ;放入IAP_ADDRH
- CJNE A,#30H,RE01 ;如果未搜索完最后一个扇区+2(2EH+2=30H)就转移,继续搜索
- LCALL SZMRZ ;已经搜索全部八个扇区,未找到保存的内容,设置为默认值
- MOV R0,#8 ;总扇区数量,共8个扇区
- LJMP WSET3 ;跳转到WSET3保存设置
- ;------------------ 保存设置,不固定保存到某个扇区,各扇区轮流使用 ------------------
- WSET: MOV R0,#8 ;扇区总数量,共8个扇区
- MOV IAP_ADDRH,#020H ;从第一个扇区开始搜索上次保存的设置
- WSET1: MOV IAP_ADDRL,#0 ;地址低位指向第一个字节
- LCALL Byte_Read ;读第一个字节,返回:A=读出的数据
- CJNE A,FWBZ1,WSET7 ;如果与EEPROM数据判断标志1不相同就转移
- INC IAP_ADDRL ;第一个字节相同,EEPROM字节地址增1
- LCALL Byte_Read ;读第二个字节
- CJNE A,FWBZ2,WSET7 ;如果与EEPROM数据判断标志2不相同就转移
- MOV IAP_ADDRL,#0 ;是在当前扇区,地址指向扇区第一个字节
- LCALL Sector_Erase ;擦除当前扇区,另换一个扇区保存
- WSET2: MOV A,IAP_ADDRH ;装入扇区地址高位到寄存器A
- CJNE A,#020H,WSET3 ;当前扇区地址高位如果不是20H(第一个扇区)就转移
- MOV IAP_ADDRH,#30H ;是20H,把IAP_ADDRH设置为最后一个扇区+2(2EH+2=30H)
- WSET3: DEC IAP_ADDRH ;减1
- DEC IAP_ADDRH ;再减1,指向上一个扇区首址
- MOV IAP_ADDRL,#0 ;低8位指向扇区第一个字节
- LCALL Sector_Erase ;擦除整个扇区
- MOV R1,#FWBZ1 ;要保存的内容始址
- MOV R2,#9 ;共9个字节
- WSET4: MOV A,@R1 ;装入R1指向的RAM地址的内容到A
- LCALL Byte_Program ;字节编程(写入EEPROM)
- INC IAP_ADDRL ;EEPROM地址加1
- INC R1 ;RAM地址增1
- DJNZ R2,WSET4 ;未保存完就继续
- MOV IAP_ADDRL,#0 ;保存完了,扇区地址低位指向0(当前扇区首址)
- LCALL Byte_Read ;读出来检查看是否写入成功
- CJNE A,FWBZ1,WSET5 ;如果与EEPROM数据判断标志1不相同就转移
- INC IAP_ADDRL ;EEPROM地址加1
- LCALL Byte_Read ;读第二个字节
- CJNE A,FWBZ2,WSET5 ;如果与EEPROM数据判断标志2不相同就转移
- RET ;成功了,退出
- WSET5: DJNZ R0,WSET2 ;如果未试完8个扇区就转移到WSET2继续往前一个扇区写
- SETB 06H ;已经试完8个扇区,都失败了,位地址06H置为1
- MOV SSSC,#5 ;显示E1五秒
- MOV ZXM1,#0 ;消隐码
- MOV ZXM2,#079H ;E
- MOV ZXM3,#006H ;1
- MOV ZXM4,#0 ;消隐码
- LCALL DISP ;显示
- WSET6: MOV A,SSSC
- LCALL WG ;喂狗
- JNZ WSET6 ;等待SSSC为0秒
- CLR 06H ;显示结束,位地址06H置为0
- RET
- WSET7: MOV A,IAP_ADDRH ;装入扇区地址高位
- ADD A,#2 ;加2,指向下一个扇区首址
- MOV IAP_ADDRH,A ;放回IAP_ADDRH
- CJNE A,#30H,WSET1 ;如果未到最后一个扇区地址高位+2(2EH+2=30H)就转移到WSET1继续搜索
- LJMP WSET3 ;是30H,已经搜索完所有扇区,未找到上次保存的数据,跳转到WSET3保存当前设置
- ;***************************************** 以上为EEPROM操作子程序 ********************************************
- ;-------------------------------------------------------------------
- ;子程序:外部中断INT0调用,根据条件控制可控硅、状态LED指示灯
- ;-------------------------------------------------------------------
- Control:MOV A,JCGLMC1
- JZ CTL01
- DEC JCGLMC1 ;JCGLMC1不为0就减1
- CTL01: SETB LED ;先熄灭自然风LED指示灯
- JNB 07H,CTL02 ;如果位地址07H位为0(不是固定慢速状态)就转移
- MOV MSZS,MSZTZS ;是固定慢速状态,把设置的转速放入到MSZS
- LJMP CTL03
- CTL02: JNB 02H,CTL03 ;如果位地址02H为0(常速状态)就转移
- CLR LED ;为1,自然风状态,点亮LED指示灯
- CTL03: MOV A,DSSJM ;装入定时时间(秒)到寄存器A
- JNZ CTL05 ;不是0就转移
- MOV A,DSSJF ;装入定时时间(分)到寄存器A
- JNZ CTL05 ;不是0就转移
- MOV A,DSSJS ;装入定时时间(时)到寄存器A
- JNZ CTL05 ;不是0就转移
- CTL04: SETB MOC ;定时时间为0,置MOC为高电平,断电
- RET
- CTL05: JB 07H,CTL07 ;如果位地址07H位为1(处于固定慢速状态)就转移
- JNB 02H,CTL06 ;如果位地址02H为0(常速状态)就转移,通电
- MOV A,ZRFFS ;装入自然风方式
- JZ CTL07 ;如果为渐慢——渐快变化方式就转移
- MOV A,SJ ;是通/断电方式,装入自然风时电机常速通电时长
- JZ CTL04 ;如果为0就转移,断电
- CTL06: CLR MOC ;通电
- RET
- CTL07: MOV A,DDMC ;装入断电(截止)脉冲计数
- JZ CTL08 ;如果是0就转移
- SETB MOC ;可控硅断电
- DEC DDMC ;计数减1
- RET
- CTL08: CLR MOC ;断电(截止)脉冲计数已经为0,可控硅通电
- MOV A,GLMC ;装入过零信号脉冲计数
- JNZ CTL09 ;不是0就转移
- MOV GLMC,MSZS ;是0,重新装入调速级数(过零信号脉冲计数)
- MOV DDMC,#2 ;设置断电(截止)脉冲计数
- RET
- CTL09: DEC GLMC ;过零信号脉冲计数减1
- RET
- ;---------------------------------------------------------------------------------------------
- ;子程序:T0中断调用,检查过零检测脉冲,如果有故障就由本子程序控制可控硅、LED指示灯
- ;---------------------------------------------------------------------------------------------
- JCGLMC: MOV A,JCGLMC1
- JNZ JCGL1 ;JCGLMC1不为0就转移
- MOV JCGLMC1,#1 ;为0,过零检测正常,重新放入检查计数
- MOV JCGLMC2,#10 ;重新放入计数,检查10个周期(100毫秒)
- RET
- JCGL1: MOV A,JCGLMC2
- JZ JCGL2 ;JCGLMC2是0就转移,说明已经检查了10个周期(100毫秒)
- DEC JCGLMC2 ;减1(10毫秒)
- RET
- JCGL2: MOV JCGLMC2,#10 ;为0,无过零脉冲,过零检测有故障或不存在,重新放入检查计数
- SETB LED ;先熄灭自然风LED指示灯
- JNB 02H,JCGL3 ;如果位地址02H为0(常速状态)就转移
- JB 07H,JCGL3 ;如果位地址07H位为1(固定慢速状态)就转移
- CLR LED ;为自然风状态,点亮LED指示灯
- JCGL3: MOV A,DSSJM ;装入定时时间(秒)到寄存器A
- JNZ JCGL5 ;不是0就转移
- MOV A,DSSJF ;装入定时时间(分)到寄存器A
- JNZ JCGL5 ;不是0就转移
- MOV A,DSSJS ;装入定时时间(时)到寄存器A
- JNZ JCGL5 ;不是0就转移
- JCGL4: SETB MOC ;是0,置MOC为高电平,断电
- RET
- JCGL5: JNB 02H,JCGL6 ;如果位地址02H为0(常速状态)就转移,通电
- JB 07H,JCGL6 ;如果位地址07H位为1(固定慢速状态)就转移,通电
- MOV A,SJ ;装入自然风时电机常速通电时长
- JZ JCGL4 ;如果为0就转移,断电
- JCGL6: CLR MOC ;通电
- RET
- ;------------------------------------------------------------------------------------------
- ;子程序:T0中断调用,时间计数及倒计时处理、自然风速度渐变控制
- ;------------------------------------------------------------------------------------------
- TIME: LCALL TSD ;自然风时的渐快、渐慢变化控制
- MOV A,SJJS ;装入(10)毫秒时间计数
- JZ TIME2 ;如果是0就转移
- DEC SJJS ;不是0,减1
- CJNE A,#50,TIME1 ;如果不是50就转移退出
- CPL 05H ;位地址第05位取反,数字及冒号闪烁时用,每0.5秒取反一次
- TIME1: RET
- TIME2: CPL 05H ;是0,位地址第05位取反,数字及冒号闪烁时用,每0.5秒取反一次
- MOV DPTR,#HMJS ;把定义的时间计数值地址装入数据指针DPTR
- MOVC A,@A+DPTR ;从程序存储区装入时间计数值到A寄存器
- MOV SJJS,A ;时间计数值放入SJJS,重新计数
- MOV A,MJS ;装入秒计数
- JZ TIME3 ;如果是0就转移
- DEC MJS ;不是0,减1秒
- TIME3: MOV A,SSSC ;装入闪烁时长秒计数
- JZ TIME4 ;如果是0就转移
- DEC SSSC ;不是0,减1秒
- TIME4: LCALL ZRFCL ;自然风时间处理
- MOV A,DSSJM ;装入定时时间(秒)到寄存器A
- JZ TIME6 ;如果是0就转移
- CJNE A,#59,TIME5 ;如果不是59秒就转移
- MOV A,DSSJF ;是59秒,检查“时”
- JNZ TIME5 ;不是0就转移
- MOV A,DSSJS ;检查“分”
- JNZ TIME5 ;不是0就转移
- MOV DSSJM,A ;“时、分”都是0,把“秒”也清零
- RET
- TIME5: DEC DSSJM ;不是0,减1秒
- RET
- TIME6: MOV A,DSSJF ;装入定时时间(分)到寄存器A
- JZ TIME7 ;如果是0就转移
- DEC DSSJF ;不是0,减1分
- MOV DSSJM,#59 ;把59放入定时时间(秒)
- RET
- TIME7: MOV A,DSSJS ;装入定时时间(时)到寄存器A
- JZ TIME8 ;如果是0就转移,退出
- DEC DSSJS ;不是0,小时减1
- MOV DSSJM,#59 ;把59放入定时时间(秒)
- MOV DSSJF,#59 ;把59放入定时时间(分)
- TIME8: RET
- ;自然风时间处理
- ZRFCL: MOV A,SJ ;装入自然风时电机常速通电时间到寄存器A
- JZ ZRFCL1 ;是0就转移
- DEC SJ ;减1秒
- ZRFCL1: MOV A,ZQ ;装入自然风变化周期时长
- DEC ZQ ;先减1
- JNZ ZRFCL3 ;如果不是0就转移
- MOV ZQ,ZRFZQ ;是0,重新装入设置值
- MOV SJ,ZRFSJ ;是0,重新装入设置值
- LCALL JBJS ;设置渐变调整的间隔计数(T0中断次数)和允许/禁止标志
- MOV MSZS,#20 ;放入最大转速级数
- CLR 09H ;位地址09H置0,渐慢调整
- ZRFCL2: RET
- ZRFCL3: CJNE A,JKTZSJ,ZRFCL4 ;如果“渐快调整时间”未到就转移
- LCALL JBJS ;设置渐变调整的间隔计数(T0中断次数)和允许/禁止标志
- MOV MSZS,MSZTZS ;放入设置的慢速状态转速
- SETB 09H ;位地址09H置1,渐快调整
- ZRFCL4: RET
- ;自然风时的渐快、渐慢变化控制
- TSD: JB 08H,TSD1 ;如果位地址08H为1(允许渐变控制)就转移
- RET
- TSD1: MOV A,MSZS
- CJNE A,#12,TSD2
- TSD2: JC TSD3 ;小于12级就转移,按设置的间隔计数(T0中断次数)调速
- MOV A,JBJS2 ;转速级数12以上调速时,变化不明显,所以每120毫秒就调一次
- SUBB A,JBJS1 ;设置的渐变调整间隔计数(T0中断次数)减已过去的时间
- CJNE A,#12,TSD3 ;不是12(120毫秒)就转移,按设置的间隔计数(T0中断次数)调速
- LJMP TSD4 ;到120毫秒了,调速。
- TSD3: MOV A,JBJS1 ;装入渐变调整间隔计数(T0中断次数)
- JZ TSD4 ;如果是0(时间到)就转移
- DEC JBJS1 ;非0,时间未到,减1
- RET
- TSD4: MOV JBJS1,JBJS2 ;重新放入设置的渐变调整间隔计数(T0中断次数)到JBJS1
- MOV A,MSZS ;装入转速级数
- JB 09H,TSD6 ;如果位地址09H为1(渐快)就转移
- CJNE A,MSZTZS,TSD5 ;渐慢,如果还没减到“设置的慢速状态转速”就转移
- CLR 08H ;位地址08H置为0,渐变结束
- RET
- TSD5: DEC MSZS ;减1(渐慢)
- RET
- TSD6: CJNE A,#20,TSD7 ;如果还没加到最大转速级数20就转移
- CLR 08H ;位地址08H置为0,渐变结束
- RET
- TSD7: INC MSZS ;加1(渐快)
- RET
- ;设置渐变调整的间隔计数(T0中断次数)和标志
- JBJS: JB 07H,JBJS_1 ;如果位地址07H位为1(固定慢速状态)就转移
- JB 02H,JBJS_2 ;如果位地址02H为1(自然风状态)就转移
- JBJS_1: CLR 08H ;是慢速状态或常速状态,位地址08H置为0,禁止渐变控制
- RET
- JBJS_2: MOV A,MSZTZS ;装入设置的慢速状态转速
- CJNE A,#12,JBJS_3
- JBJS_3: JNC JBJS_1 ;等于或大于12就转移,变化不明显,无渐变控制必要
- MOV A,ZRFZQ ;装入自然风变化周期(10~60秒)
- MOV B,#2
- DIV AB ;除2
- MOV JKTZSJ,A ;得出渐快调整的开始时间(5~30)
- DEC A ;减1,12级以上另外调速(1秒内完成)
- CJNE A,#26,JBJS_4 ;渐变的单个方向时间长度(4~29)是否大于26
- JBJS_4: JC JBJS_5 ;小于26就转移
- MOV A,#25 ;等于或大于26,修改为25
- JBJS_5: MOV B,#10
- MUL AB ;乘10后结果为40~250
- MOV B,A ;放入B寄存器
- MOV A,#12 ;最大级数11+1(12级以上不进行渐变控制,所以最大为11)
- SUBB A,MSZTZS ;减设置的慢速状态转速,得出要调整的级数数量(1~11)
- XCH A,B ;A、B寄存器内容交换
- DIV AB ;除级数数量(1~11)
- CJNE A,#26,JBJS_6 ;
- JBJS_6: JC JBJS_7 ;商小于26就转移
- MOV A,#25 ;商等于或大于26,修改为25
- JBJS_7: XCH A,B ;A、B寄存器内容交换
- JZ JBJS_9 ;如果余数为0就转移
- DEC A ;余数不为0,减1,修正误差
- CJNE A,#6,JBJS_8 ;
- JBJS_8: JC JBJS_9 ;余数小于6就转移
- MOV A,#5 ;余数等于或大于6,修改为5
- JBJS_9: MOV JBJS1,A ;暂时放入JBJS1
- XCH A,B ;A、B寄存器内容交换
- MOV B,#10
- MUL AB ;商乘10
- ADD A,JBJS1 ;加上余数,得出间隔计数(T0中断次数)
- MOV JBJS2,A
- SETB 08H ;位地址08H置为0,允许渐变控制
- RET
- ;------------------------------------------------------------------------------------------
- ;子程序:T0中断调用,显示定时时间及各项设置的内容
- ;------------------------------------------------------------------------------------------
- DISPLAY:JB 06H,DPYSZ1 ;如果位地址06H为1就转移退出,主程序显示88:88或E1
- MOV A,DISPL ;装入要显示的目标
- JZ DISPL0 ;如果是0(显示定时时间)就转移
- DPYSZ: PUSH ACC
- MOV DPTR,#SEGTAB ;查表获取字形码
- MOVC A,@A+DPTR ;查表获取字形码
- MOV ZXM1,A ;项目编号字形码放到待发送TM1637区1
- MOV ZXM2,#40H ;放入“-”的字形码到待发送TM1637区2
- POP ACC
- DEC A ;减1
- PUSH 01H
- MOV R1,#ZRFZQ ;各项设置值始址
- ADD A,R1 ;加上项目号
- MOV R1,A ;得出设置项目的实际地址放入R1
- MOV A,@R1 ;装入设置值
- POP 01H
- MOV B,A ;放入B寄存器
- CJNE A,XSHC1,DPYSZ3 ;当前设置值与显示缓存1不相同就转移,立即显示
- MOV A,SJJS ;相同,装入时间计数
- JNZ DPYSZ2 ;不是0就转移,每半秒(遇到50或0)显示一次
- LJMP DPYSZ3 ;是0,显示
- DPYSZ1: RET
- DPYSZ2: CJNE A,#50,DPYSZ1 ;不是50就转移退出,每半秒(遇到50或0)显示一次
- DPYSZ3: MOV XSHC1,B ;当前设置值放入显示缓存1
- JNB 04H,DPYSZ4 ;如果位地址04H为0(不闪烁)就转移
- JNB 05H,DPYSZ4 ;为1,闪烁显示,如果位地址05H为0(显示)就转移
- CLR A ;为1,处于闪烁显示中的“不显示”状态,放入消隐码
- MOV ZXM1,A ;放入消隐码
- MOV ZXM2,A ;放入消隐码
- MOV ZXM3,A ;放入消隐码
- MOV ZXM4,A ;放入消隐码
- LJMP disp ;跳转到disp,发送4个字节数据到TM1637显示
- DPYSZ4: MOV A,B ;当前设置值放入A寄存器
- LCALL DISPL6 ;转换并获取字形码放到待发送TM1637区3和4
- LJMP disp ;跳转到disp,发送4个字节数据到TM1637显示
- DISPL0: MOV A,DSSJS ;显示定时时间,装入定时时间(时)
- CJNE A,XSHC1,DISPL3 ;定时时间(时)与显示缓存1不相同就转移,显示
- MOV A,DSSJF
- CJNE A,XSHC2,DISPL3 ;定时时间(分)与显示缓存2不相同就转移,显示
- MOV A,SJJS ;时、分都相同,装入(10)毫秒时间计数
- JNZ DISPL2 ;不是0就转移
- LJMP DISPL3 ;是0,显示,每半秒(遇到50或0)显示一次
- DISPL1: RET
- DISPL2: CJNE A,#50,DISPL1 ;不是50就转移,每半秒(遇到50或0)显示一次
- DISPL3: MOV XSHC1,DSSJS ;当前时间放入显示缓存1
- MOV XSHC2,DSSJF ;当前时间放入显示缓存2
- MOV A,DSSJM ;
- JNZ DISPL4 ;检查当前定时时间是否全部为0,不是就转移
- MOV A,DSSJF ;
- JNZ DISPL4 ;检查当前定时时间是否全部为0,不是就转移
- MOV A,DSSJS ;
- JNZ DISPL4 ;检查当前定时时间是否全部为0,不是就转移
- CLR 05H ;定时时间为0,把位地址05H置为0,冒号不闪烁显示
- DISPL4: MOV A,DSSJS ;装入“时”
- MOV B,#10 ;转换为BCD码
- DIV AB ;转换为BCD码
- MOV DPTR,#SEGTAB ;查表获取字形码
- MOVC A,@A+DPTR ;查表获取字形码
- MOV ZXM1,A ;字形码放入待发送TM1637区1
- XCH A,B ;A、B寄存器内容交换
- MOVC A,@A+DPTR ;查表获取字形码
- JB 05H,DISPL5 ;如果05H为1就转移,不显示冒号
- ORL A,#10000000B ;为0,把最高位置为1,显示冒号(字形码的最高位为1就显示冒号)
- DISPL5: MOV ZXM2,A ;放入待发送TM1637区2
- MOV A,DSSJF ;装入“分”
- LCALL DISPL6 ;转换并获取字形码放到待发送TM1637区3和4
- LJMP disp ;跳转到disp,发送4个字节数据到TM1637显示
- DISPL6: MOV B,#10 ;转换为BCD码
- DIV AB ;转换为BCD码
- MOV DPTR,#SEGTAB ;查表获取字形码
- MOVC A,@A+DPTR ;查表获取字形码
- MOV ZXM3,A ;字形码放入待发送TM1637区3
- XCH A,B ;A、B寄存器内容交换
- MOVC A,@A+DPTR ;查表获取字形码
- MOV ZXM4,A ;字形码放入待发送TM1637区4
- RET
- ;------------------ 发送4个字节数据到TM1637显示,地址自动加1 ------------------
- disp: LCALL Srt
- MOV A,#040H ;数据命令设置40H:地址自动加1,写数据到显示寄存器
- LCALL Writebyte ;发送一个字节
- LCALL Stop
- NOP
- LCALL Srt
- MOV A,#0C0H ;地址命令设置C0H:初始地址为00H
- LCALL Writebyte ;发送一个字节
- PUSH 01H
- PUSH 06H
- MOV 06H,#4 ;发送4个字节数据
- MOV R1,#ZXM1 ;等待发送的字形码始址
- disp1: MOV A,@R1 ;装入要发送的字形码
- LCALL Writebyte ;发送一个字节
- INC R1 ;地址加1
- DJNZ 06H,disp1 ;如果还未发送完就继续
- POP 06H
- POP 01H
- LCALL Stop
- LCALL Srt
- MOV A,SMGLD ;装入设置的数码管亮度(1~8)
- ADD A,#087H ;加上87H后即为对应的亮度控制命令88H~8FH
- LCALL Writebyte ;按设置的亮度开显示
- LJMP Stop
- ;------------------ 发送8bit(一个字节)数据到TM1637,A=要发送的数据,从低位开始 ------------------
- Writebyte:
- PUSH 00H
- MOV 00H,#8 ;发送8位数据
- WBY1: CLR CLK ;拉低CLK
- JNB ACC.0,WBY2 ;A寄存器的低位(0位)如果为0就转移
- SETB DIO ;为1,拉高DIO
- SJMP WBY3
- WBY2: CLR DIO ;为0,拉低DIO
- WBY3: NOP
- NOP
- NOP
- NOP
- NOP
- SETB CLK ;拉高CLK
- CLR C ;进位标志清0
- RRC A ;A寄存器内容带进位循环右移
- DJNZ 00H,WBY1 ;如果还未发送完8bit数据就继续
- WBY4: CLR CLK ;8位数据发送完了
- NOP
- MOV 00H,#05 ;设置等待应答信号计数值,防止万一与TM1637通讯失败而造成死循环
- WBY5: DEC 00H ;减1,正常情况下ACK应答信号很快,第一次减1就会有应答
- MOV A,00H ;装入计数值到A
- JZ WBY6 ;如果为0就转移退出,说明与TM1637通讯失败,或TM1637不存在
- JB DIO,WBY5 ;不为0,判断TM1637发过来的ACK应答信号,未应答(为1,高电平)就转移
- WBY6: POP 00H
- NOP
- NOP
- NOP
- SETB CLK
- NOP
- NOP
- NOP
- RET
- ;------------------ Start子程序 ------------------
- Srt: SETB DIO ;拉高DIO
- SETB CLK ;拉高CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB DIO ;拉高DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR DIO ;拉低DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR CLK ;拉低CLK
- RET
- ;------------------ Stop子程序 ------------------
- Stop: CLR CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB CLK
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- SETB DIO
- NOP
- NOP
- NOP
- NOP
- NOP
- CLR CLK
- CLR DIO
- RET
- ;------------------ 字形表 ------------------
- SEGTAB:
- DB 00111111B ;0(3FH)
- DB 00000110B ;1(06H)
- DB 01011011B ;2(5BH)
- DB 01001111B ;3(4FH)
- DB 01100110B ;4(66H)
- DB 01101101B ;5(6DH)
- DB 01111101B ;6(7DH)
- DB 00000111B ;7(07H)
- DB 01111111B ;8(7FH)
- DB 01101111B ;9(6FH)
- DB 01110111B ;A(77H)
- DB 01111100B ;B(7CH)
- DB 00111001B ;C(39H)
- DB 01011110B ;D(5EH)
- DB 01111001B ;E(79H)
- DB 01110001B ;F(71H)
- DB 00000000B ;消隐码(00)
- ;------------------------------------------------------------------------------------------
- END
复制代码
电风扇长定时+自然风.rar
(149.27 KB, 下载次数: 13)
|
打赏
-
查看全部打赏
|