普通电风扇电机一般用调相法调速,对于象电加热器之类热惯量较大的,还可用调**来调温,即控制每秒内正弦波形个数.<br /> 调**当每秒内完整波形少于25个时,平均电压波动较大,负载的热惯性会起一个平衡作用,一般不低于10个.但用于惯量较小的风扇,就会有明显的抖晃了.<br /> 调相法调速缺点是不能过零触发,因此干扰毛刺较大.而调**可过零触发,干扰很小.<br /><br />下面是俺以前做过的一个小产品,可参考一下.<br /><br />lc.sch → <a href="https://bbs.21ic.com/upfiles/img/200711/2007112282813673.rar" target=_blank>https://bbs.21ic.com/upfiles/img/200711/2007112282813673.rar</a><br /><br />lc.asm → <a href="https://bbs.21ic.com/upfiles/img/200711/200711228352463.rar" target=_blank>https://bbs.21ic.com/upfiles/img/200711/200711228352463.rar</a><br /><br /><br /><br /><br /> ;<br />; ┏━━━━━━━━━━━┓<br />; ┃┏━━━━━━━━━┓┃<br />; ┃┃无线遥控开关接收器┃┃<br />; ┃┃ 源程序 ┃┃<br />; ┃┃ V1.0 01.03.18 ┃┃<br />; ┃┗━━━━━━━━━┛┃<br />; ┗━━━━━━━━━━━┛<br />;<br /> ORG 0000H<br /> AJMP CSH ;主程序进入点<br /> ORG 0003H<br /> LJMP WT0 ;外部中断WT0入口<br /> ORG 000BH<br /> AJMP TI0 ;定时中断T0入口<br /> ORG 001BH<br /> AJMP TI1 ;定时中断T1入口<br />;<br />;**********<br />;* 初始化 *<br />;**********<br />;<br /> ORG 0020H<br />CSH: MOV R0,#7FH ;内部RAM(00H~7FH)清零<br />CSH1: MOV @R0,#00H<br /> DJNZ R0,CSH1<br /> MOV SP,#60H ;堆栈60H~7FH,【使用89C2051】<br /> MOV TMOD,#00010010B ;T0作8位计数器 (自动装入),T1作16位计数器<br /> MOV TH0,#155 ;FFH-9BH=100D,12M/12/100D=10000HZ(100us)<br /> MOV TH1,#0ECH ;FFFFH-1388H=EC77H<br /> MOV TL1,#77H ;T1频率为12M/12/5000D=200HZ(5ms)<br />;<br /> SETB TCON.4 ;T0开始动作<br /> SETB IE.1 ;T0允许中断<br /> SETB TCON.6 ;T1开始动作<br /> SETB IE.3 ;T1开始中断<br /> SETB IE.0 ;INT0允许中断<br /> SETB TCON.0 ;INT0低电平触发<br /> SETB PT0 ;T0中断优先<br /> SETB IE.7 ;系统允许中断<br />;<br /> MOV 46H,#03<br /> LCALL BEL<br />;<br /> CLR 24H ;24.4H←"0"开一短键标志复位(关)<br /> CLR 26H ;24.6H←"0"开一短键标志复位(关)<br /> MOV 30H,#85 ;调相上电初始亮度(最暗)<br /> MOV 31H,#02 ;调功上电初始亮度(最暗)<br />;<br />;**********<br />;* 主程序 *<br />;**********<br />;<br />MAIN: NOP<br /> LCALL JS ;调用PT2272解码信号接收子程序<br /> LCALL DTCL ;调用PT2272解码信号处理子程序<br /> LJMP MAIN<br />;<br />;**********************<br />;* PT2272解码信号接收 *<br />;**********************<br />;<br />JS: JNB P1.2,JS5 ;P1.2="0",解码信号无效,转JS5<br />;<br /> JNB P1.4,JS2 ;不是调相键,转JS2继续<br /> SETB 0AH ;调相键有效标志置位<br />JS2: JNB P1.5,JS3 ;不是调功键,转JS3继续<br /> SETB 0BH ;调功键有效标志置位<br />JS3: JNB P1.6,JS4 ;不是开一键,转JS4继续<br /> SETB 0CH ;开一键有效标志置位<br />JS4: JNB P1.7,JS0 ;不是开二键,转JS0出口<br /> SETB 0DH ;开二键有效标志置位<br />JS0: RET<br />;<br />JS5: CLR 0AH ;调相键有效标志复位<br /> CLR 0BH ;调功键有效标志复位<br /> CLR 0CH ;开一键有效标志复位<br /> CLR 0DH ;开二键有效标志复位<br /> RET<br />;<br />;*************************************<br />;* 解码信号处理 *<br />;*-----------------------------------*<br />;* 【调相键】 P14H="1"键按下 *<br />;* 【调功键】 P15H="1"键按下 *<br />;* 【开一键】 P16H="1"键按下 *<br />;* 【开二键】 P17H="1"键按下 *<br />;*-----------------------------------*<br />;* 短键作开、关用 *<br />;* 长键作控制用(="0"减低,="1"增高) *<br />;*************************************<br />;<br />DTCL: JB 06H,TXK3 ;转TXK3,检查调相长键有否放开?<br /> JB 11H,TXK2 ;正在作调相短键定时,转TXK2<br /> JNB 0AH,DTL1 ;不是调相键,转DTL1继续<br />;**************<br />;* 调相键处理 *<br />;**************<br /> JB 10H,TXK1 ;正在作调相键按下消抖动延时,转TXK1<br /> SETB 10H ;22.0H←"1",调相键消抖动延时标志置位<br /> MOV 54H,#10 ;设置30ms键按下消抖动延时<br />TXK1: MOV A,54H<br /> CJNE A,#00,TXK0 ;30ms定时未到,转TXK0出口<br /> CLR 10H ;10H←"0",调相键消抖动延时标志复位<br /> JNB 0AH,TXK0 ;无效键入,转TXK0出口<br /> LCALL BEL1 ;蜂鸣一次<br /> SETB 11H ;11H←"1",调相长键定时已设置标志置位<br /> MOV 54H,#80 ;设置400ms长键定时<br />TXK2: MOV A,54H<br /> CJNE A,#00,TXK4 ;400ms长键定时未到,转TXK4检查有否放键<br /> JB 20H,TXK5 ;20H="1",调相短键已打开<br /> SETB 20H ;打开调相短键<br /> MOV A,30H<br /> SETB 21H ;30H<"50",蛮亮了,设置调暗方向<br /> CJNE A,#50,TXK6<br />TXK6: JC TXK5<br /> CLR 21H ;30H≥"50",蛮暗了,设置调亮方向<br />TXK5: CPL 21H ;21H←"X"调相长键标志取反<br /> SETB 06H ;06H←"1",调相长键标志置位<br /> MOV 46H,#01 ;长键蜂鸣<br /> LCALL BEL<br />TXK3: JB 0AH,TXK0 ;>400ms,键未放,保持长键,转TXK0<br /> CLR 11H ;11H←"1",调相长键定时已设置标志复位<br /> CLR 06H ;06H←"0",调相长键标志复位<br />TXK0: RET<br />;<br />TXK4: JB 0AH,TXK0 ;调相键未放,转TXK0<br />;************************<br />;* <400ms就放键,是短键 *<br />;************************<br /> CPL 20H ;20H←"X"调相短键标志取反<br /> CLR 11H ;11H←"1",调相长键定时已设置标志复位<br /> RET<br />;<br />DTL1: JB 07H,TGK3 ;转TGK3,检查调功长键有否放开?<br /> JB 13H,TGK2 ;正在作调功短键定时,转TGK2<br /> JNB 0BH,DTL2 ;不是调功键,转DTL2继续<br />;**************<br />;* 调功键处理 *<br />;**************<br /> JB 12H,TGK1 ;正在作调功键按下消抖动延时,转TGK1<br /> SETB 12H ;12H←"1",调功键消抖动延时标志置位<br /> MOV 54H,#10 ;设置10ms键按下消抖动延时<br />TGK1: MOV A,54H<br /> CJNE A,#00,TGK0 ;10ms定时未到,转TGK0出口<br /> CLR 12H ;12H←"0",调功键消抖动延时标志复位<br /> JNB 0BH,TGK0 ;无效键入,转TGK0出口<br /> SETB 13H ;13H←"1",调功长键定时已设置标志置位<br /> LCALL BEL1 ;蜂鸣一次<br /> MOV 54H,#80 ;设置400ms长键定时<br />TGK2: MOV A,54H<br /> CJNE A,#00,TGK4 ;400ms长键定时未到,转TGK4检查有否放键<br /> JB 22H,TGX5<br /> SETB 22H ;打开调功短键<br /> MOV A,31H<br /> CLR 23H ;31H≥"25",蛮暗了,设置调亮方向<br /> CJNE A,#12,TGX6<br />TGX6: JC TGX5<br /> SETB 23H ;31H<"25",蛮亮了,设置调暗方向<br />TGX5: CPL 23H ;23H←"X"调功长键标志取反<br /> SETB 07H ;07H←"1",调功长键标志置位<br /> MOV 46H,#01 ;蜂鸣二次<br /> LCALL BEL<br />TGK3: JB 0BH,TGK0 ;>400ms,键未放,保持长键,转TGK0<br /> CLR 13H ;13H←"1",调功长键定时已设置标志复位<br /> CLR 07H ;07H←"0",调功长键标志复位<br />TGK0: RET<br />;<br />TGK4: JB 0BH,TGK0 ;调功键未放,转TGK0<br />;************************<br />;* <400ms就放键,是短键 *<br />;************************<br /> CPL 22H ;22H←"X"调功短键标志取反<br /> CLR 13H ;13H←"0",调功长键定时已设置标志复位<br /> RET<br />;<br />DTL2: JB 08H,K1C2<br /> JNB 0CH,DTL3 ;不是开一键,转DTL3继续<br />;**************<br />;* 开一键处理 *<br />;**************<br /> JB 14H,K1C1 ;正在作开一键按下消抖动延时,转K1C1<br /> SETB 14H ;22.4H←"1",开一键消抖动延时标志置位<br /> MOV 54H,#10 ;设置30ms键按下消抖动延时<br />K1C1: MOV A,54H<br /> CJNE A,#00,K1C0 ;30ms定时未到,转K1C0出口<br /> CLR 14H ;22.4H←"0",开一键消抖动延时标志复位<br /> JNB 0CH,K1C0 ;无效键入,转K1C0出口<br /> LCALL BEL1 ;蜂鸣一次<br /> SETB 08H ;禁止开一键连续蜂鸣<br /> CPL 24H ;24.4H←"X"开一短键标志取反<br />K1C2: JB 0CH,K1C0 ;键未放,转K1C0<br /> CLR 08H ;允许开一键蜂鸣<br />K1C0: RET<br />;<br />DTL3: JB 09H,K2C2<br /> JNB 0DH,K2C0 ;不是开二键,转K2C0出口<br />;**************<br />;* 开二键处理 *<br />;**************<br /> JB 16H,K2C1 ;正在作开二键按下消抖动延时,转K2C1<br /> SETB 16H ;22.6H←"1",开二键消抖动延时标志置位<br /> MOV 54H,#10 ;设置30ms键按下消抖动延时<br />K2C1: MOV A,54H<br /> CJNE A,#00,K2C0 ;30ms定时未到,转K2C0出口<br /> CLR 16H ;22.6H←"0",开二键消抖动延时标志复位<br /> JNB 0DH,K2C0 ;无效键入,转K2C0出口<br /> SETB 09H ;禁止开二键连续蜂鸣<br /> LCALL BEL1 ;蜂鸣一次<br /> CPL 26H ;24.6H←"X"开二短键标志取反<br />K2C2: JB 0DH,K2C0 ;键未放,转K2C0<br /> CLR 09H ;允许开二键蜂鸣<br />K2C0: RET<br />;<br />;********<br />;* 蜂鸣 *<br />;********<br />;<br />BEL1: MOV 46H,#01<br />BEL: SETB 01H ;允许蜂鸣<br /> MOV 38H,#30 ;150ms蜂鸣定时<br /> RET<br />;<br />;***************************<br />;* 100us时标T0定时中断处理 *<br />;***************************<br />;<br />TI0: PUSH PSW ;PSW进栈<br /> SETB PSW.3 ;RS0←"1"<br /> CLR PSW.4 ;RS1←"0",选工作寄存区1(R08H ̄R0FH)<br /> PUSH ACC<br /> CPL P3.1<br /> MOV R1,#04 ;需延时计数器字节<br /> MOV R0,#50H ;延时计数器R50H~R53H<br />DY2: MOV A,@R0 ;读计数值<br /> JZ DY1 ;=0?是转DY1处理下一位<br /> DEC @R0 ;计数器减一<br />DY1: INC R0 ;计数器指针加一<br /> DJNZ R1,DY2 ;3字节到?<br />;*************************************<br />;* 调相滞后触发处理 (脉宽0.1ms) *<br />;* 40H装载当前调相触发滞后时间值 *<br />;* 40H每0.1ms减一,(40H最大为100) *<br />;* 40H="01"时P3.7←"0",触发脉冲前沿 *<br />;* 40H="00"时P3.7←"1",触发脉冲后沿 *<br />;*************************************<br /> JNB 20H,TCL0 ;20H="0",调相输出关<br /> JNB 30H,TCL0 ;30H="0",电压未过零,禁止调相触发定时<br /> JB 04H,TCL1<br /> MOV 40H,30H ;取出30H当前调相触发滞后时间值<br /> SETB 04H ;20.4H←"1",滞后触发已置初值<br />TCL1: DEC 40H ;当前调相触发滞后时间值减0.1ms<br /> MOV A,40H<br /> CJNE A,#01,TCL2<br /> CLR P3.7 ;P3.7←"0",调相触发脉冲前沿(脉宽0.1ms)<br />TCL0: POP ACC ;ACC出栈<br /> POP PSW ;PSW出栈【恢复进栈前寄存器区】<br /> RETI ;中断返回<br />;<br />TCL2: CJNE A,#00,TCL0<br /> CLR 04H ;04H←"0",触发定时器允许重置初值<br /> CLR 30H ;30H←"0",禁止调相触发定时<br /> SETB P3.7 ;P3.7←"1",调相触发脉冲后沿<br /> SJMP TCL0 ;出中断<br />;<br />;*************************<br />;* 5ms时标T1定时中断处理 *<br />;*************************<br />;<br />TI1: MOV TH1,#0ECH ;FFFFH-1388H=EC77H<br /> MOV TL1,#77H ;T0频率为12M/12/5000D=1388H=200HZ(5ms)<br /> PUSH PSW ;PSW进栈<br /> CLR PSW.3 ;RS0←"0"<br /> SETB PSW.4 ;RS1←"1",选工作寄存区2(R10H ̄R17H)<br /> PUSH ACC<br />;<br /> CPL P3.0 ;看门狗定时100Hz(10ms)<br />;<br /> MOV R1,#02 ;需延时计数器字节<br /> MOV R0,#54H ;延时计数器R54H~R55H<br />DY4: MOV A,@R0 ;读计数值<br /> JZ DY3 ;=0?是转DY1处理下一位<br /> DEC @R0 ;计数器减一<br />DY3: INC R0 ;计数器指针加一<br /> DJNZ R1,DY4 ;3字节到?<br />;****************<br />;* 蜂鸣定时处理 *<br />;****************<br /> JB 05H,TT9 ;05H="1",正在作关蜂鸣定时,转TT9<br /> JB 02H,TT9K ;02H="1",正在作开蜂鸣定时,转TT9K<br /> JNB 01H,TT8 ;01H="0",禁止蜂鸣处理,转TT8继续<br /> CLR P1.3 ;开蜂鸣<br /> SETB 02H ;02H←"1",开蜂鸣定时<br />TT9K: DEC 38H ;蜂鸣10ms计数器减一<br /> MOV A,38H ;取出蜂鸣10ms计数器<br /> CJNE A,#10,TT8 ;开蜂鸣100ms未到,转TT8继续<br /> SETB 05H ;05H←"1",关蜂鸣定时<br /> SETB P1.3 ;关蜂鸣<br />TT9: DEC 38H ;蜂鸣10ms计数器减一<br /> MOV A,38H ;取出蜂鸣10ms计数器<br /> CJNE A,#00,TT8 ;关蜂鸣50ms未到,转TT8继续<br /> CLR 05H ;05H←"0",关蜂鸣定时标志复位<br /> CLR 02H ;02H←"0",开蜂鸣定时标志复位<br /> MOV 38H,#30 ;重置蜂鸣定时150ms常数<br /> DJNZ 46H,TT8 ;蜂鸣次数未到,转TT8继续<br /> CLR 01H ;01H←"0",禁止蜂鸣处理<br />;**********************************<br />;* 调相触发滞后时间调整 *<br />;*--------------------------------*<br />;* 每20ms调整一档,每档0.1ms *<br />;* 半周期共调整10ms÷0.1ms=100档 *<br />;* 20msX100=2s调完半程,4s调完全程 *<br />;**********************************<br />TT8: JNB 20H,DY5 ;20H="0",调相关,转DY5不调整<br /> INC 56H ;5ms计数器加一<br /> MOV A,56H ;取出5ms计数器值<br /> CJNE A,#12,DY5 ;20ms未到,转DY5出口<br /> MOV 56H,#00<br /> JNB 06H,DY5 ;06H="0",禁止调相,转DY5不调整<br /> JNB 21H,DY6 ;21H="0",转DY6电压调低<br /> MOV A,30H ;取出当前调相触发滞后时间值<br /> CJNE A,#08,DY7 ;30H="02",电压最高值<br /> SJMP DY5 ;30H="0",电压已调到最高了,转DY5出口<br />;<br />DY7: DEC 30H ;每20ms调相触发延时减一档(每档0.1ms),电压调高<br /> SJMP DY5<br />;<br />DY6: MOV A,30H ;取出当前调相触发滞后时间值<br /> INC 30H ;每20ms调相触发延时加一档(每档0.1ms),电压调低<br /> CJNE A,#85,DY5 ;100usX100=10ms未到,转DY5出口<br /> MOV 30H,#85 ;30H="97",电压已调到最低了,不再增加<br />;<br />DY5: POP ACC ;ACC出栈<br /> POP PSW ;PSW出栈【恢复进栈前寄存器区】<br /> RETI ;定时中断返回<br />;<br />;****************<br />;* 外部中断处理 *<br />;****************<br />;<br />WT0: PUSH PSW ;PSW进栈<br /> PUSH ACC ;ACC进栈<br /> SETB PSW.3 ;RS0←"1"<br /> SETB PSW.4 ;RS1←"1",选工作寄存区3(R18H ̄R1FH)<br />;*************************<br />;* 电压过零,允许调相触发 *<br />;*************************<br /> JNB 20H,TOFF1 ;20H="0",调相关,转TOFF1<br /> SETB 30H ;30H←"1",电压过零,允许调相触发定时<br />;********************<br />;* 调功周期触发处理 *<br />;********************<br />TOFF1: JNB 22H,TOFF2 ;22H="0",调功关,转TOFF2<br /> INC 33H ;21H="0",当前周期触发步进定时计数器加一<br /> MOV A,33H ;读取当前周期触发步进定时计数器<br /> CJNE A,#50,TF13 ;未到250ms设定数<br /> MOV 33H,#01 ;周期触发脉冲计数器清"0"<br />;**************************<br />;* 周期触发脉冲数调整环节 *<br />;**************************<br /> JNB 07H,TF13 ;07H="0",禁止调功,转TF13直接触发<br /> MOV A,31H ;读取开周期计数器<br /> JB 23H,TF12 ;23H="1",递增<br /> DEC 31H ;开周期计数器减一<br /> CJNE A,#02,TF13 ;未到开周期设定数下限(20%)<br /> MOV 31H,#02 ;到设定数下限,不再减少<br /> SJMP TF13<br />TF12: INC 31H ;开周期计数器加一<br /> CJNE A,#20,TF13 ;未到开周期设定数上限(100%)<br /> MOV 31H,#20 ;到设定数上限,不再增加<br />;****************<br />;* 周期脉冲触发 *<br />;****************<br />TF13: MOV A,32H ;读取周期触发脉冲计数器<br /> INC 32H ;21H="0",调功触发计数器加一<br /> JB 29H,TF10<br /> CLR 29H ;29H←"0",当前周期触发开<br /> CJNE A,31H,TF10 ;未到开周期设定数<br /> SETB 29H ;29H←"1",当前周期触发关<br />TF10: CJNE A,#20,TF11 ;未到周期<br /> MOV 32H,#00 ;加载周期触发脉冲计数器<br /> CLR 29H ;29H←"0",当前周期触发开<br />;<br />TF11: JB 29H,TOFF2 ;29H="1",调功间隙,禁止触发<br /> CLR P3.3 ;P3.3←"0",调功触发脉冲前沿<br />;<br />TOFF2: JNB 24H,TOFF3 ;24H="0",开1关,转TOFF3<br /> CLR P3.4 ;P3.4←"0",开1触发脉冲前沿<br />;<br />TOFF3: JNB 26H,TOFF4 ;26H="0",开2关,转TOFF4<br /> CLR P3.5 ;P3.5←"0",开2触发脉冲前沿<br />;<br />TOFF4: MOV R7,#50 ;设置100us触发脉宽软件延时<br />WAIT: DJNZ R7,WAIT ;产生100us触发脉宽<br /> SETB P3.3 ;P3.3←"1",调功触发脉冲后沿<br /> SETB P3.4 ;P3.4←"1",开1触发脉冲后沿<br /> SETB P3.5 ;P3.5←"1",开2触发脉冲后沿<br /> ;<br /> POP ACC ;ACC出栈<br /> POP PSW ;PSW出栈=【恢复进栈前寄存器区】<br /> RETI ;外部中断返回<br />;<br /> END<br /><br /><img src="https://bbs.21ic.com/upfiles/img/200711/200711228226664.gif"> |
|