https://blog.csdn.net/u013247982/article/details/37914581
https://blog.csdn.net/yannanxiu/article/details/48174649
参考以上两章文章了解格力空调码
红外接收头输出的电平:
0的电平宽度为:600us低电平+600us高电平
1的电平宽度为:600us低电平+1700us高电平(1600更改为1700)
起始码S电平宽度为:9000us低电平+4500us高电平
连接码C电平宽度为:600us低电平+20000us高电平
37.9KHz的载波周期是指红外发射二极管的发光频率为37.9KHz。
由于任何物体都会发射红外线,所以红外通信需要抗干扰,红外接收头被调整为只接收发光频率为37.9KHz左右的红外光。
实际上就是37.9KHz的PWM驱动红外管发射,并且其有效电平占比为25%~33%。如果红外发射管是高电平发光,那么高电平就是有效电平。
红外二极管被37.9KHz,有效电平占比为30%的PWM驱动发光,这时候被红外接收头接收到,红外接收头就会发出低电平。没收到信号就会发高电平信号。
信号组成:起始信号+35位数据+连接信号+32位数据+结束信号。结束信号和连接信号一样
每一个字节都是倒序发送的,例如制热,开,自动风速。那么第一字节数据被红外接收头接收到的信号依次是00110000,但是制热模式是4,是100,实际在字节里的排列为00001100,所以倒序发送可解决该问题。
我用的是stm32,使用定时器3产生37.9KHz的PWM。
高电平为有效电平
TIM_SetCompare2(TIM3,570);//发送低电平信号。高电平占比:1900x30%=570
TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<900); //等待9000us
TIM_SetCompare2(TIM3,0);//发送高电平信号。红外二极管不发光
TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<450);//等待4500us
//PWM部分代码
TIM_TimeBaseInitStructure.TIM_Period = 1900-1; //37.9khz
TIM_TimeBaseInitStructure.TIM_Prescaler = 1-1; //不分频
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStructure);
空调码的计算与发送
u8 fsc=0;
u8 fsdat[5];//前35位
u8 fsdat2[4];//后32位
//mode 0~4,run 0~1,wind 0~3,wod wlr 0~1,wd 0~14
void Airc(u8 mode,u8 run,u8 wind,u8 wod,u8 wlr,u8 wd)
{
u8 i;
fsdat[0]=wind<<4|run<<3|mode+0x40;//风速,开关和模式
fsdat[1]=wd; //温度
fsdat[2]=0xa0;
fsdat[3]=0x50;
fsdat[4]=0x02;
fsdat2[0]=wod|wlr<<4;//上下左右扫风
fsdat2[1]=0x20;
fsdat2[2]=0;
fsdat2[3]=((mode-1)+wd+5+wod-8+run*8)<<4;//校验码
printf("Start run:%d mode:%d wd:%d wind:%d wod:%d wlr:%d
",run,mode,wd+16,wind,wod,wlr);//串口发送需发送的红外码
for(i=0;i<35;i++)
{
if(i%8==0)printf("
");
printf("%d ",(fsdat[i/8]>>i%8)&0x01);
}
for(i=0;i<32;i++)
{
if(i%8==0)printf("
");
printf("%d ",(fsdat2[i/8]>>i%8)&0x01);
}
//起始码
TIM_SetCompare2(TIM3,570);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<900);
TIM_SetCompare2(TIM3,0);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<450);
for(i=0;i<35;i++)
{
TIM_SetCompare2(TIM3,570);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<60);
TIM_SetCompare2(TIM3,0);TIM_SetCounter(TIM2, 0);
if(((fsdat[i/8]>>i%8)&0x01)==0){while(TIM_GetCounter(TIM2)<60);}
else {while(TIM_GetCounter(TIM2)<170);}
}
//连接码
TIM_SetCompare2(TIM3,570);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<60);
TIM_SetCompare2(TIM3,0);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<2000);
for(i=0;i<32;i++)
{
TIM_SetCompare2(TIM3,570);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<60);
TIM_SetCompare2(TIM3,0);TIM_SetCounter(TIM2, 0);
if(((fsdat2[i/8]>>i%8)&0x01)==0){while(TIM_GetCounter(TIM2)<60);}
else {while(TIM_GetCounter(TIM2)<170);}
}
TIM_SetCompare2(TIM3,570);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<60);
TIM_SetCompare2(TIM3,0);TIM_SetCounter(TIM2, 0);while(TIM_GetCounter(TIM2)<2000);
}
就是这样