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