微控制器紅外遙控格力空調

PpgpOs發表於2018-12-03

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\n",run,mode,wd+16,wind,wod,wlr);//串列埠傳送需傳送的紅外碼
	for(i=0;i<35;i++)
	{
		if(i%8==0)printf("\n");			
		printf("%d ",(fsdat[i/8]>>i%8)&0x01);						
	}

	for(i=0;i<32;i++)
	{
		if(i%8==0)printf("\n");
		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);
}

就是這樣

相關文章