欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3676|回復: 3
打印 上一主題 下一主題
收起左側

學習型空調遙控的實現

[復制鏈接]
跳轉到指定樓層
樓主
ID:82781 發表于 2015-6-13 01:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  經過整整一年的時間,今天終于實現了夢寐以求的控制空調的程序,回顧這段歷程,大有曲折輪回之意。

去年此時我從xx辭職了,那時候我留下了一個空調的問題而懸而未決,但是其實走的時候我已經說過了,要用單片機捕捉原始碼,不要解碼,因為當時我做的電視遙控學習是用的網上的一段程序做的,是解碼的,始終沒有做這個空調的學習原始碼和控制。后來聽說后來者做出來了,也就印證了我的思想沒有錯。然后這個問題在我這里就被擱置了!掛起了。
  一方面是我的主要工作不在是智能家居,兩一方面是程序上原來的固件庫有問題。不太好做。直到上周吧,近來xx等人做的空調和電視的控制深深的刺激了我,我縱然是不服輸的,和他交流了幾次,總是驕縱的樣子,仿佛他做出來就沒有別人一樣。于是乎,暗下決心,一定要攻破此問題,他能做我們就不能做?總得試試才知道,說干就干,重新找出來去年的代碼,都看不懂了,然后開始分步走。
第一步:確定好TICK時間在基準,
第二步:模擬采樣PWM波形,
第三步:采集紅外數據
第四步:PWM調制紅外波形發送
主要粗分為以上4步。然后分而治之。第一步就遇到很大問題,也是老問題,就是固件庫怎么也不能把時鐘提高到我需要的精度,并且老有遲滯誤差的出現。為了解決這個問題。我專門去官方網站下載了最新的寄存器庫,XX人總是自信的認為他是操作寄存器起家的,殊不知大家都是那樣過來的,忽悠純軟件的人可以,忽悠我你還是省省得好。然后對比兩套庫的差異,很明顯出來了,是由于代碼的回調時的進出棧帶來的遲滯,雖然進出、棧時間很短,CPU速度足夠快,但是由于是精度比較高,所以速度很快,多次的堆積壓棧出棧就會導致時間被占用,于是我在老版本的程序上稍加改動,屏蔽掉系統回調,速度直接呼呼上去。于是這個問題解決了,此問題已解決問題就已經解決一半了,
      今天實現了剩下的3步,上午主要工作是捕捉,很順利,捕捉很成功,這也是磨刀不誤砍柴工的結果。然后自己寫了一點邏輯算法,用來接收和發送之間的協同。下午實現數據碼的重構,利用PWM發生的38K重構整個碼流,下午為了這個特意去辦公室拿了示波器。架起來示波器直到發出來的和接收到遙控的數據碼一個不差的顯示到屏幕上,我知道大概我要去辦公室實際測試一下了。

到了辦公室廢了好一頓周折才進去,沒帶鑰匙,無奈只能爬進去了。一切就緒后,學碼,發碼。空調嘩唥嘩唥的跟著變化,我知道成功了,呵呵!



代碼如下:

代碼簡單的不能再簡單,幾行而已。只是XXX別再裝逼,都能!原理都一樣只是你做的稍微細一點,我的這個粒度足夠我用。

uint8_t StartLeve=0;   //起始電平狀態
uint16_t DataLenth=0;    //碼型長度
uint16_t  Learn_Finsh=0; //學習完畢
uint16_t ir_raw[512];    //數據碼
uint32_t  ir_number;     //計數器

/*
  描述:發送紅外調制嘛
************************/
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;//更新計數器
                                ir_number=0;                         //清計數器
                        if(DataLenth==0)                         //獲取起始電平,以后按照數組依次排列為高低高低.
                        {
                           if(DrvGPIO_GetBit(E_PORT3,E_PIN2)==0)
                           {
                           StartLeve = 0;
                           }
                           else                                             //取得起始電平
                           {
                           StartLeve = 1;
                           }
                        }
                        //100MS        作為數據碼結束的標志,理論上沒有大于100MS的紅外間隔,可改變。
                        //但是要注意再學習的時候學完一次之后得在按一下,觸發之。
                        //此時已經學到了數據并可以返回數據的長度啦。       
                        if((ir_raw[DataLenth]>10000)&&(DataLenth!=0))
                        {                                                               
                        //學碼完成 大于0之后表示數據已經記錄進緩存中了
                        //        Learn_Finsh = DataLenth-1
                        //RAW數據被記錄在raw[1]-raw[Learn_Finsh]之間
                        //                                       
                                Learn_Finsh= DataLenth-1;//       
                                DataLenth=0;                          //準備下一次學習。
                        }       
                                   DataLenth++;                         //下一個數據碼



}

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);
       
       
        }


到最后做出來了,單獨使用確實沒啥意思,如果聯合TCP/IP使用那就有意義的多了。數據碼放在本地FLASH中,服務器只要發送代號即可,小米盒子的遙控功能就是這么做的!

最后結句以自欺:
結廬在人境,而無車馬喧。 問君何能爾?心遠地自偏。 采菊東籬下,悠然見南山。 山氣日夕佳,飛鳥相與還。 此中有真意,欲辨已忘言。


老偉
于日照比特電子






分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:208445 發表于 2017-8-24 11:45 | 只看該作者
問題的是空調的學習,空調不是有好多命令的,都記錄下來這么多的脈寬,也是一件費勁的事啊
回復

使用道具 舉報

板凳
ID:208445 發表于 2017-8-24 11:45 | 只看該作者
小米盒子 用的是藍牙吧
回復

使用道具 舉報

地板
ID:260347 發表于 2018-8-19 10:54 | 只看該作者
老哥,可否把完整程序發到我郵箱,非常感謝!!向您學習一下Martin_1996@163.com
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表