天气太热,睡觉的话用红云风扇兜风,有时候觉得最慢的风还是太大了。我试过在风扇上连接风扇的电感调节器,用过晶闸管调节器,但即使电源电压低,风扇也低到勉强可以工作,但是风扇转速太大,吹得睡不着觉。
这也可能是我这个风扇低压启动性能不好。最后,我用单片机控制,用PWM方波控制这个红云风扇。通过调整不同的占空比来控制转速,效果比电感或晶闸管调节速度好,风扇速度可以调节得非常慢,通过缝隙给风扇供电,可以模拟自然风效果。最后增加了红外线遥控功能,使用起来比较满意。
相应的51单片机红外接收遥控风扇控制电路和软件代码将在下面说明,供感兴趣的朋友参考。
图3,装在饮料瓶上的红外接收电路输出插座。
图4,红外接收控制电路结构图
硬件和软件说明:
在图4中,用标称输出5V的USB电源模块为系统供电。由于实测输出电压为6V,所以在5V输出端连接了二极管降压。由于控制PWM输出的电源开关经常断开,且常规电磁继电器的触点寿命有限,因此使用固态继电器控制220伏交流输出插座。图4还绘制了原本打算用于控制风扇的快速线圈切换的双开关继电器。在使用过程中,我们发现只要通过调整PWM的不同占空比来控制风扇速度基本上符合要求,这个设备就没有必要了。(4)以前,4键控制:
0x 16=“0”=“0”=控制固态继电器的总电源开关-“开或关,每个键翻转一次”。
0x0c="1"="1"=控制快速慢档,控制圈继电器-"双刀双掷开关快速慢档转换,每键翻转一次。
0x44="vol-"=减速,控制主继电器断电时间,=速度-(如果将主继电器断电时间增加到10,则为1)。
0x 40=“VOL”=加速,控制主继电器开通时间,=speed-(如果将主继电器开通时间增加到8,则为1)。
(5)以后更改为8键控制:
0x 43=“pause/play”=控制固态继电器的总电源开关-“开或关,每个键翻转一次”。
0x09="EQ"="EQ"=速度控制快,控制旋转继电器-"双刀双掷开关转换,每键翻转一次。
0x44="prev"=减速,将主继电器断电时间增加到10时停止。
0x40="next"=加速,主继电器断电时间减少到1时停止。)
0x15="vol-"=减速,将主继电器开通时间减少到1时停止。
0x 07=“VOL”=加速,将主继电器开通时间增加到10时停止。
(6)用于单片机软件下载的CH340下载线(仅使用下图5、TXD RXD GND等3条线)。
(7) p02=hyd Zr beeper(针脚38)=p02 10k上载1K线程9014-B极、9014-C极LED BEEPER。
(8) P03=J1(WANJIA双刀双掷继电器,5A250V)=P03 10k全1K连接9014-B极,9014-C极WJ113H继电器(RJ=55欧,IJ=;
(9) P04=Jmain(主开关固态继电器)=P03 10k全1K线程9014-B极、9014-C极固态继电器(IJmain=12MA)。负荷连接50瓦灯,传导时输出触点压降=8伏交流电。
(10)38k红外线遥控器(1838红外线接收器=包括HS0038B):
(11)遥控器键值
//uchar code test1 [4]={0x16,0x0c、0x08,0x42、};//遥控器键0-1-
4-7//uchar code Test2[4]={0x18,0x5e,0x1c,0x5a,};//遥控键2-3-5-6
//uchar code Test3[4]={0x42,0x52,0x4a,0x15,};//遥控键7-8-9-+
按键名称 数据码, 按键名称 数据码, 按键名称 数据码, 按键名称 数据码
0 0x16 1 0x0c 2 0x18 3 0x5e
4 0x08 5 0x1c 6 0xaa 7 0x42
8 0x52 9 0xab - 0x07 + 0x15
eq 0x09 next 0x40 prev 0x44 play 0x87
PAUSE/PLAY 0x43
--------------------------===================================------------------------------
(12)源码:
unsigned char IRtime; //红外信号位周期时长计时器,由T0中断计数。
bit irpro_ok,IRrec_Ok;
unsigned char IRcode[4]; //将接收的红外32位数据按四个字节数据保存
unsigned char IR_time[33]; //分别寄存33个bit的时间
sbit Beep = P0^2; //红外接收提示LED灯+beeper
sbit Speed = P0^3; //9014驱动的动圈继电器J1-快慢档输出端口
sbit Power = P0^4; //固态继电器Jmain-总电源控制输出端口
#define ON 1; //定义led=1=on
#define OFF 0; //定义led=0=off
#define TRUE 1;
#define FALSE 0;
uchar Ton, Toff; //Ton是主继电器开通延时时间,Toff是主继电器关断延时时间。
uchar Ton_count, Toff_count; //Ton_count是主继电器开通计数器,Toff_count是主继电器关断计数器。
uchar F_Speed; //调速模式标志,=TRUE=1是调速状态,=0是正常速度状态。
/*--------------------函数声明----------*/
void Ir_work(void);
void Ircode_pro(void);
void Delay_1ms(unsigned int Tx)
{ unsigned int t1,t2;
for(t1=0;t1<Tx;t1++) for(t2=0;t2<120;t2++);
}
void Beeper(unsigned int Tx)
{ Beep = ON; Delay_1ms(Tx); Beep = OFF; Delay_1ms(10);
}
#define PreloadT0H (65536-250)>>8;
#define PreloadT0L (65536-250)%256;
#define PreloadT1H (65536-50000)>>8;
#define PreloadT1L (65536-50000)%256;
unsigned int PreT0h, PreT0l;
unsigned int PreT1h, PreT1l;
//===================================================================
//T0=0001,设为16位定时工作方式0
void TIME0_init(void)
{ TMOD &= 0Xf0; // 低位T0计数方式清0
TMOD |= 0X01; // T0=计数方式1= 16位,
//T0方式选择位C/T=0=定时工作方式1,= 16位,不自动重装参数
PreT0h= PreloadT0H; PreT0l= PreloadT0L;
TH0= PreT0h; TL0= PreT0l;
TR0 = 1;
ET0=1; //允许计数器0中断
PT0= 1; //T0为最高优先级
}
/*-----------------------*/
void time0_isr (void) interrupt 1 using 1
{ IRtime++; //用于计数2个下降沿之间的时间
TH0= PreT0h; TL0= PreT0l;
}
//==================================================================
//T1设为16位定时工作方式0
void TIME1_init(void)
{
TMOD &= 0X0f; // 高位T1计数方式清0
TMOD |= 0X10; // T1=计数方式1= 16位,
//T1方式选择位C/T=0=定时工作方式1= 16位,不自动重装参数
PreT1h= PreloadT1H; PreT1l= PreloadT1L;
TH1= PreT1h; TL1= PreT1l;
TR1 = 1;
ET1=1; //允许计数器1中断
}
/*----------------------------------*/
uchar Txms_count=0;
void time1_isr(void) interrupt 3
{ TH1= PreT1h; TL1= PreT1l;
if(Txms_count++ >=20)
{ Txms_count = 0;
if(F_Speed==1) //=1是调速状态
{
if(Ton_count++ <Ton)
{ Power=ON; }
else if((Ton_count>=Ton)&&(Toff_count++ <Toff) )
{ Power=OFF; }
if((Ton_count>=Ton)&&(Toff_count>=Toff) )
{ Beeper(2); //=心跳信号,在慢速工作状态时,每个"通电+断电结束"周期响一短声。
Ton_count=0; Toff_count=0; } //定时时间到,计数器清零
}
}
}
/*----------------------------*/
void EX0init(void)
{ IT0 = 1; //指定外部中断0下降沿触发,INT0 )
EX0 = 1; //使能外部中断
}
/*-----------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{ //接收红外信号处理,将接收到各位数占时存储下来
static unsigned char IRcount; //接收位数计数器
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(IRtime>32) //IRtime>32即认为是引导码,丢弃
//引导码=TC9012的头码=53*IRtime=9ms+4.5ms,33*IRtime=8.448ms
//when IRtime=250us,33*IRtime=8250us, 32*IRtime=8000us
{ IRcount=0; } // IR_time[0]=引导码的时间长度=9ms+4.5ms,
IR_time[IRcount]=IRtime;//存储每个位电平的持续时间,用于以后判断是0还是1
IRtime=0; //清零
IRcount++; //接收位数计数器
if(IRcount==33) //收够32位数据了
{ IRrec_Ok=1; IRcount=0; }
}
else
{ IRtime=0; startflag=1; }
}
void Ir_work(void) //根据接收到的红外键值跳转处理程序--
{
switch(IRcode[2])//只判断第三个数码值
{
case 0x43: //key=PAUSE/play=暂停=Jmain主继电器开通或关断,每按键一次翻转一次
F_Speed = FALSE; //FALSE=0==正常速度状态
Power= !Power; Beeper(200); //跟踪Power= ~Power;是同样效果-20220731
break;
case 0x09: //key=EQ =快慢控制继电器)快速或慢速控制(接通1为慢速,接通2为快速)
F_Speed = FALSE; //FALSE=0=正常速度状态
Speed= !Speed; Beeper(200); //每按键一次翻转一次
break;
case 0x44: //=PREV =Toff-- (Jmain主继电器开通时间减少)
F_Speed = TRUE; //TRUE=1=调速状态
if(Toff-- <2)
{ Toff=1; Beeper(1000); } //从2开始,10档速度,每按键一次,断电时间-1s
Beeper(200); break;
case 0x40: //=NEXT =Toff++ (Jmain主继电器开通时间++)
F_Speed = TRUE; //TRUE=1
if(Toff++ >10)
{ Toff=10; Beeper(1000); } //从2开始,10档速度,每按键一次,断电时间+1s
Beeper(200); break;
case 0x15: //=VOL- =Ton-- (Jmain主继电器开通时间--
F_Speed = TRUE; //TRUE=1
if(Ton-- <2)
{ Ton=1; Beeper(1000); } //从2开始,8档速度,每按键一次,通电时间-1s
Beeper(200); break;
case 0x07: //=VOL+ =Ton++ (Jmain主继电器开通时间--
F_Speed = TRUE; //TRUE=1
if(Ton++ >8)
{ Ton= 8; Beeper(1000); } //从2开始,8档速度,每按键一次,通电时间+1s
Beeper(200); break;
default: F_Speed = FALSE; break;
}
irpro_ok=0;//处理完成标志
}
void Ircode_pro(void)
//将接收的32字节存储在IR_time[32],根据时长判断个位是0或1,转为四个字节保存
{ unsigned char i, j, k; unsigned char Code32b,value;
k=1; //将引导码=IR_time[0]去掉,所以令k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理每1个字节的8位数
{
Code32b=IR_time[k]; //1th,取出32位数的的第一位IR_time[1],根据时长来判断是0或1。
if(Code32b>6) //大于某值为1,这个和晶振有关系
// 如果收到1,对应的高电平时间=1.168ms,IR_time[]=1.168ms/IRtime,必定大于等于4。
// 如果收到0,对应的高电平时间=0.56ms,IR_time[]=0.56ms/IRtime,必定>=2。
//7*IRtime=1750us, 6*IRtime=1500us,560/250=2.24, 1168/250=4.67个IR_time
// 另有资料说,1对应的高电平时间=1.69ms,IR_time[]=1690us/250=6.76个IR_time。
//结论:用4或8会得乱码。用5-7解码结果都对,取6较合理。
value|=0x80; //令最高位=1
if(j<8) { value>>=1; } //处理下一位
k++;
}
IRcode[i]=value; //将接收的8位数据按1个字节保存
value=0;
}
irpro_ok=1; //将接收的32位数据按四个字节保存,处理完毕标志位置1
}
/*----------- 主函数-------*/
void main(void)
{//MCU通电瞬间的端口高电平,会令各输出端口的9014导通+继电器吸合通电,改用PNP的9012可避免此问题
Power = OFF; Speed = OFF; Beep = OFF; //开机先令几个输出端口=0,防止继电器通电!
Delay_1ms(500); Beeper(200);
EX0init(); //初始化外部中断
TIME0_init(); //初始化定时器0-红外接收定时
TIME1_init(); //初始化定时器1-继电器开关定时
Ton= 3; Toff= 2; //Ton是主继电器开通和关断的延时时间,一秒为单位,调速才用到
Ton_count=0; Toff_count=0; //主继电器开通和关断计数器,调速时,在T1中断1S后计数
EA = 1; //开总中断
while(1)//主循环
{
if(IRrec_Ok) //如果在INT0接收到正确的红外信号,就跳转这里进行红外数据处理
{ Beeper(30); //接收到红外按键信号,发出提示音
Ircode_pro(); //将接收的32位时长数据按四个字节提取并保存到IRcode[i]
IRrec_Ok=0;
}
if(irpro_ok) //数据处理好后,做对应工作
{ Ir_work(); } //根据红外键值跳转处理程序
}
}
写于20220813
1.《【遥控风扇电路怎么接线】电子生产1-红外遥控风扇生产》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《【遥控风扇电路怎么接线】电子生产1-红外遥控风扇生产》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/why/3088723.html