智能语音风扇灯是基于普中51实验板做的一个小项目。主要功能是语音控制风扇档位变化和rgb灯变换颜色。
系统硬件以围绕STC89C52为核心的外围功能元件展开,文章重点从语音大脑模块、5V DC直流风扇、5050封装RGB灯珠模块、数码管四个方面开展硬件介绍与功能设计。
RGB呼吸灯电路
系统可以通过单片机产生PWM脉冲进行控制。通过语音模块发出的指令,单片机通过串口接收处理后,由从控制器P1.0、P1.1、P1.2、P1.3口输出PWM方波脉冲控制RGB灯珠的发光。在LED模块中,RGE5050为全彩RGB高亮LED灯珠,且R、G、B三个引脚均串联了限流电阻以防止烧毁灯珠,其余的三个引脚均接地。另外,模块的工作电压为3.3V-5V,接电后即可发出单色或复色光。硬件电路图如图3所示。
PWM即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,而我们想要实现控速以及后面的RGB灯呼吸灯效果,刚好可以利用PWM来实现。
rgb的PWM代码可以参考下面的思路
//定时器中断设置
void Timer0_Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
//PWM控制定时器中断函数
void Timer0_Routine() interrupt 1
{
TL0 = 0x9C; //重装初值设置定时初值
TH0 = 0xFF; //
if(LEDCounter<R_Patten) //计数值小于比较值
{
R=1; //输出1
}
else //计数值大于比较值
{
R=0; //输出0
}
if(LEDCounter<G_Patten) //计数值小于比较值
{
G=1; //输出1
}
else //计数值大于比较值
{
G=0; //输出0
}
if(LEDCounter<B_Patten) //计数值小于比较值
{
Blue=1; //输出1
}
else //计数值大于比较值
{
Blue=0; //输出0
}
}
//LED灯颜色控制
void LEDMODE( unsigned char Patten)
{
Patten%=5;
if(Key1==1)
{
GND=0;
//设置比较值,改变PWM占空比
if(Patten==0){P2=0X00;R_Patten=225;G_Patten=0;B_Patten=0;} //红
if(Patten==1){P2=0X00;R_Patten=0;G_Patten=225;B_Patten=0;} //绿
if(Patten==2){P2=0X00;R_Patten=0;G_Patten=0;B_Patten=225;} //蓝
if(Patten==3){P2=0X00;R_Patten=160;G_Patten=32;B_Patten=240;} //紫
if(Patten==4){P2=0X00;R_Patten=0;G_Patten=255;B_Patten=255;} //青
if(Patten==5){P2=0X00;R_Patten=255;G_Patten=255;B_Patten=0;} //黄
}
风扇的pwm控制同理
//定时器中断函数
void Timer0_Routine() interrupt 1
{
TL0 = 0x9C; //重装初值设置定时初值
TH0 = 0xFF; //
Counter++;
Counter%=100; //计数值变化范围限制在0~99
if(Counter<Compare) //计数值小于比较值
{
Motor=1; //输出1
}
else //计数值大于比较值
{
Motor=0; //输出0
}
//风扇档位控制
void Fan(unsigned char Speed)
{
if(Key==1)
{
if(Speed==0){Compare=0;}
if(Speed==1){Compare=25;} //设置比较值,改变PWM占空比
if(Speed==2){Compare=50;}
if(Speed==3){Compare=75;}
if(Speed==4){Compare=100;}
}
}
语音模块使用的是语音大脑模块VB6824,这里的语音模块已经写好程序,我们把它当做串口透传模块来使用,语音模块会发生两个数组只取后一个为控制命令。
串口参考代码如下
//串口初始化
void Uart_Init()
{
SCON=0x50; //串口工作方式1,8位UART,波特率可变
TH2=0xFF;
TL2=0xFD; //波特率:115200 晶振=11.0592MHz
RCAP2H=0xFF;
RCAP2L=0xFD; //16位自动再装入值
EA=1;
ES=1;
/*****************/
TCLK=1;
RCLK=1;
C_T2=0;
EXEN2=0; //波特率发生器工作方式
/*****************/
TR2=1 ; //定时器2开始
}
//串口中断服务函数
void Uart() interrupt 4
{
if(RI == 1)
{
RI = 0;
Buffer[Count] = SBUF; //用数组接收串口数据,一个BYTE。
if(Count == 2){Count = 0;} //只接收两个,下次再接收覆盖。 }
if(TI) //如果是发送标志位,清除
TI=0;
}
switch(Buffer[1])
{
case 0x02: /*命令“打开灯光”*/
Key1=1;
P2=0X00;
LEDMODE(Patten);
break;
case 0x03: /*命令“关闭灯光”*/
Key1=0;
P2=0X00;
R_Patten=0;
G_Patten=0;
B_Patten=0;
break;
case 0x04: /*命令“改变颜色”*/
P2=0X00;
Patten++;
LEDMODE(Patten);
break;
case 0x05: /*命令“打开风扇”*/
P2=0X31;
Key=1;
Fan(Speed);
display(Speed);
break;
case 0x06: /*命令“关闭风扇”*/
Compare=0;
Key=0;
P2=0X31;
break;
case 0x07: /*命令“增大风速”*/
Speed++;
if(Speed>=5){Speed=4;}
Fan(Speed);
P2=0X31;
display(Speed);
break;
case 0x08: /*命令“减小风速”*/
Speed--;
Fan(Speed);
P2=0X31;
display(Speed);
break;
}
Buffer[0]=0;
Buffer[1]=0; //清除上一个命令
Count++;
if(TI) //如果是发送标志位,清除
TI=0;
}
为了匹配115200的波特率要求,这里使用了定时器2的16位重装模式。