標(biāo)題:
學(xué)習(xí)型空調(diào)遙控的實(shí)現(xiàn)
[打印本頁(yè)]
作者:
xuwei
時(shí)間:
2015-6-13 01:11
標(biāo)題:
學(xué)習(xí)型空調(diào)遙控的實(shí)現(xiàn)
經(jīng)過(guò)整整一年的時(shí)間,今天終于實(shí)現(xiàn)了夢(mèng)寐以求的控制空調(diào)的程序,回顧這段歷程,大有曲折輪回之意。
去年此時(shí)我從xx辭職了,那時(shí)候我留下了一個(gè)空調(diào)的問(wèn)題而懸而未決,但是其實(shí)走的時(shí)候我已經(jīng)說(shuō)過(guò)了,要用單片機(jī)捕捉原始碼,不要解碼,因?yàn)楫?dāng)時(shí)我做的電視遙控學(xué)習(xí)是用的網(wǎng)上的一段程序做的,是解碼的,始終沒(méi)有做這個(gè)空調(diào)的學(xué)習(xí)原始碼和控制。后來(lái)聽說(shuō)后來(lái)者做出來(lái)了,也就印證了我的思想沒(méi)有錯(cuò)。然后這個(gè)問(wèn)題在我這里就被擱置了!掛起了。
一方面是我的主要工作不在是智能家居,兩一方面是程序上原來(lái)的固件庫(kù)有問(wèn)題。不太好做。直到上周吧,近來(lái)xx等人做的空調(diào)和電視的控制深深的刺激了我,我縱然是不服輸?shù)模退涣髁藥状,總是驕縱的樣子,仿佛他做出來(lái)就沒(méi)有別人一樣。于是乎,暗下決心,一定要攻破此問(wèn)題,他能做我們就不能做?總得試試才知道,說(shuō)干就干,重新找出來(lái)去年的代碼,都看不懂了,然后開始分步走。
第一步:確定好TICK時(shí)間在基準(zhǔn),
第二步:模擬采樣PWM波形,
第三步:采集紅外數(shù)據(jù)
第四步:PWM調(diào)制紅外波形發(fā)送
主要粗分為以上4步。然后分而治之。第一步就遇到很大問(wèn)題,也是老問(wèn)題,就是固件庫(kù)怎么也不能把時(shí)鐘提高到我需要的精度,并且老有遲滯誤差的出現(xiàn)。為了解決這個(gè)問(wèn)題。我專門去官方網(wǎng)站下載了最新的寄存器庫(kù),XX人總是自信的認(rèn)為他是操作寄存器起家的,殊不知大家都是那樣過(guò)來(lái)的,忽悠純軟件的人可以,忽悠我你還是省省得好。然后對(duì)比兩套庫(kù)的差異,很明顯出來(lái)了,是由于代碼的回調(diào)時(shí)的進(jìn)出棧帶來(lái)的遲滯,雖然進(jìn)出、棧時(shí)間很短,CPU速度足夠快,但是由于是精度比較高,所以速度很快,多次的堆積壓棧出棧就會(huì)導(dǎo)致時(shí)間被占用,于是我在老版本的程序上稍加改動(dòng),屏蔽掉系統(tǒng)回調(diào),速度直接呼呼上去。于是這個(gè)問(wèn)題解決了,此問(wèn)題已解決問(wèn)題就已經(jīng)解決一半了,
今天實(shí)現(xiàn)了剩下的3步,上午主要工作是捕捉,很順利,捕捉很成功,這也是磨刀不誤砍柴工的結(jié)果。然后自己寫了一點(diǎn)邏輯算法,用來(lái)接收和發(fā)送之間的協(xié)同。下午實(shí)現(xiàn)數(shù)據(jù)碼的重構(gòu),利用PWM發(fā)生的38K重構(gòu)整個(gè)碼流,下午為了這個(gè)特意去辦公室拿了示波器。架起來(lái)示波器直到發(fā)出來(lái)的和接收到遙控的數(shù)據(jù)碼一個(gè)不差的顯示到屏幕上,我知道大概我要去辦公室實(shí)際測(cè)試一下了。
到了辦公室廢了好一頓周折才進(jìn)去,沒(méi)帶鑰匙,無(wú)奈只能爬進(jìn)去了。一切就緒后,學(xué)碼,發(fā)碼。空調(diào)嘩唥嘩唥的跟著變化,我知道成功了,呵呵!
代碼如下:
代碼簡(jiǎn)單的不能再簡(jiǎn)單,幾行而已。只是XXX別再裝逼,都能!原理都一樣只是你做的稍微細(xì)一點(diǎn),我的這個(gè)粒度足夠我用。
uint8_t StartLeve=0; //起始電平狀態(tài)
uint16_t DataLenth=0; //碼型長(zhǎng)度
uint16_t Learn_Finsh=0; //學(xué)習(xí)完畢
uint16_t ir_raw[512]; //數(shù)據(jù)碼
uint32_t ir_number; //計(jì)數(shù)器
/*
描述:發(fā)送紅外調(diào)制嘛
************************/
extern void DrvTIMER_Delay(E_TIMER_CHANNEL ch, uint32_t uIntTicks)
;
void Send_Ir_Code(uint8_t *pt ,uint16_t Lenth )
{
uint16_t i;
uint8_t k=0;
uint32_t da,da1;
for(i=1;i<Lenth+1;i+=2)
{
DrvPWM_Enable(DRVPWM_TIMER0, 1);
da = ir_raw
;
DrvTIMER_Delay( E_TMR0, da) ;
DrvPWM_Enable(DRVPWM_TIMER0, 0);
da1 = ir_raw[i+1];
DrvTIMER_Delay( E_TMR0, da1) ;
}
DrvPWM_Enable(DRVPWM_TIMER0, 0);
}
void EINT0callback()
{
ir_raw[DataLenth]=ir_number;//更新計(jì)數(shù)器
ir_number=0;
//清計(jì)數(shù)器
if(DataLenth==0)
//獲取起始電平,以后按照數(shù)組依次排列為高低高低.
{
if(DrvGPIO_GetBit(E_PORT3,E_PIN2)==0)
{
StartLeve = 0;
}
else
//取得起始電平
{
StartLeve = 1;
}
}
//100MS
作為數(shù)據(jù)碼結(jié)束的標(biāo)志,理論上沒(méi)有大于100MS的紅外間隔,可改變。
//但是要注意再學(xué)習(xí)的時(shí)候?qū)W完一次之后得在按一下,觸發(fā)之。
//此時(shí)已經(jīng)學(xué)到了數(shù)據(jù)并可以返回?cái)?shù)據(jù)的長(zhǎng)度啦。
if((ir_raw[DataLenth]>10000)&&(DataLenth!=0))
{
//學(xué)碼完成 大于0之后表示數(shù)據(jù)已經(jīng)記錄進(jìn)緩存中了
//
Learn_Finsh = DataLenth-1
//RAW數(shù)據(jù)被記錄在raw[1]-raw[Learn_Finsh]之間
//
Learn_Finsh= DataLenth-1;//
DataLenth=0;
//準(zhǔn)備下一次學(xué)習(xí)。
}
DataLenth++;
//下一個(gè)數(shù)據(jù)碼
}
void pfP2P3P4Callback(uint32_t u32P2Status, uint32_t u32P3Status, uint32_t u32P4Status)
{
}
void pfP0P1Callback
(uint32_t u32P0Status, uint32_t u32P1Status)
{
if(u32P0Status&(1<<0)) //p0.0
{
}
}
void init_IR_INTTRUPUT(void)
{
//DrvGPIO_SetIntCallback(pfP0P1Callback, pfP2P3P4Callback);//install
//DrvGPIO_EnableInt(E_PORT0, E_PIN0, E_IO_BOTH_EDGE, E_MODE_EDGE);//雙邊沿
DrvGPIO_EnableEINT(E_EINT0_PIN,E_IO_BOTH_EDGE, E_MODE_EDGE, EINT0callback);
}
void init_PWM(void)
{
S_DRVPWM_TIME_DATA_T sP_PWM;
/*Initialize PWM*/
DrvPWM_Open();
/* Select PWM engine clock */
DrvPWM_SelectClockSource(DRVPWM_TIMER0, DRVPWM_INTERNAL_22M);
/* PWM Timer property */
sP_PWM.u8Mode = DRVPWM_AUTO_RELOAD_MODE;
sP_PWM.u8HighPulseRatio = 50; /* High Pulse peroid : Total Pulse peroid = 1 : 100 */
sP_PWM.i32Inverter = 1;
sP_PWM.u32Frequency =38000;
DrvPWM_SetTimerClk(DRVPWM_TIMER0, &sP_PWM);
/* Enable Output for PWM Timer */
DrvPWM_SetTimerIO(DRVPWM_TIMER0, 1);
/* Enable the PWM Timer */
// DrvPWM_Enable(DRVPWM_TIMER0, 0);
DrvGPIO_InitFunction(E_FUNC_PWM01_P4);
DrvPWM_Enable(DRVPWM_TIMER0, 0);
}
到最后做出來(lái)了,單獨(dú)使用確實(shí)沒(méi)啥意思,如果聯(lián)合TCP/IP使用那就有意義的多了。數(shù)據(jù)碼放在本地FLASH中,服務(wù)器只要發(fā)送代號(hào)即可,小米盒子的遙控功能就是這么做的!
最后結(jié)句以自欺:
結(jié)廬在人境,而無(wú)車馬喧。 問(wèn)君何能爾?心遠(yuǎn)地自偏。 采菊東籬下
,悠然見南山。 山氣日夕佳,飛鳥相與還。 此中有真意,欲辨已忘言。
老偉
于日照比特電子
作者:
sirius2015
時(shí)間:
2017-8-24 11:45
問(wèn)題的是空調(diào)的學(xué)習(xí),空調(diào)不是有好多命令的,都記錄下來(lái)這么多的脈寬,也是一件費(fèi)勁的事啊
作者:
sirius2015
時(shí)間:
2017-8-24 11:45
小米盒子 用的是藍(lán)牙吧
作者:
Martin777
時(shí)間:
2018-8-19 10:54
老哥,可否把完整程序發(fā)到我郵箱,非常感謝!!向您學(xué)習(xí)一下
Martin_1996@163.com
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1