0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區
會(huì )員中心
創(chuàng )作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內不再提示

STM32之紅外遙控信號自學(xué)習實(shí)現

jf_pJlTbmA9 ? 來(lái)源:jf_pJlTbmA9 ? 作者:jf_pJlTbmA9 ? 2023-09-18 15:52 ? 次閱讀

1、序言

很早前就想實(shí)現這個(gè)紅外遙控自學(xué)習的這個(gè)實(shí)驗,用于來(lái)自己控制房子里如空調等紅外遙控設備的自動(dòng)化,NEC的標準到具體的產(chǎn)品上可能就被廠(chǎng)家定義為不一樣了,所以自學(xué)習就應該是接收到什么就發(fā)送什么,不用管內容是什么!

2、硬件實(shí)現原理

poYBAGIB1zqAfv0iAACYj1AoSVo485.png

由上述原理圖可知,當IE為高電平時(shí)發(fā)送紅外光,為低電平時(shí)不發(fā)送紅外光。

在NEC協(xié)議中,信息傳輸是基于38K載波,也就是說(shuō)紅外線(xiàn)是以載波的方式傳遞。

發(fā)送波形如下圖所示:

poYBAGD5kxmARvikAADzeSrpLMw630.png

NEC協(xié)議規定:

發(fā)送協(xié)議數據“0” = 發(fā)送載波560us + 不發(fā)送載波560us

發(fā)送協(xié)議數據“1” = 發(fā)送載波560us+ 不發(fā)送載波1680us

發(fā)送引導碼 = 發(fā)送載波9000us + 不發(fā)送載波4500us

在紅外接收端,如果接收到紅外38K載波,則IR輸出為低電平,如果不是載波包括固定低電平和固定高電平則輸出高電平。在IR端接收的信號如下所示:

pYYBAGIB1z2AWqY8AADmgOQPgTA783.png
pYYBAGIB1z6ATOcoAAFVJMK3aHE541.png

3、軟件實(shí)現自學(xué)習

設計原理:

pYYBAGIB1z-AN7J1AADYosTOXiY565.png

1、 根據接收波形記錄電平和電平持續時(shí)間,以便于發(fā)送。

2、電平記錄采用定時(shí)器捕獲功能,從下降沿接收引導信號開(kāi)始,每觸發(fā)一次改變觸發(fā)方式,從而使每個(gè)電平變化都能捕獲到。

源碼實(shí)現如下:

定時(shí)器捕獲初始化設置(CubeMax軟件自動(dòng)配置生成):

void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};


htim4.Instance = TIM4;
htim4.Init.Prescaler = 71;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 10000;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init( htim4) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource( htim4,  sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init( htim4) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization( htim4,  sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel( htim4,  sConfigIC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}


}

定時(shí)器捕獲中斷回調處理:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
    {
if(TIM4->CCER   (TIM_CCER_CC4P))   //下降沿觸發(fā)
        {
            TIM4->CCER  = ~(TIM_CCER_CC4P); //切換
            gu8BitVal = 1;
        }
else                               //上升沿觸發(fā)
        {
            TIM4->CCER |= TIM_CCER_CC4P;    //切換
            gu8BitVal = 0;
        }




if(gsInfrared.State == NONE_STATE)
        {
            gsInfrared.State = RECV_STATE;
        }
else if(gsInfrared.State == RECV_STATE)
        {
            NowTimCnt = HAL_TIM_ReadCapturedValue( htim4, TIM_CHANNEL_4);
            gsInfrared.KeepTime[gsInfrared.SampleCount] = Round(NowTimCnt);
            gsInfrared.BitValue[gsInfrared.SampleCount ++] = gu8BitVal;
        }


        TIM4->CNT = 0;
    }
}

3、設置的定時(shí)器溢出時(shí)間為10ms,如果10毫秒內不再接收電平變化則默認接收結束,設置結束標志。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim ==  htim4)
    {
if(gsInfrared.State == RECV_STATE)
        {
            gsInfrared.State = END_STATE;
        }
    }
}

至此,實(shí)現了紅外遙控的學(xué)習功能,獲得的記錄數據為記錄長(cháng)度和電平信號數組與電平信號維持的時(shí)間數組。

poYBAGIB10GAeLEAAACXkIF7MwY745.png
poYBAGIB10KAKYYpAACb-d5PGr4135.png

4、發(fā)送實(shí)現

設置定時(shí)器輸出38KPWM信號,在記錄電平為0是輸出記錄時(shí)間的38K載波信號,如果為1則不輸出載波,實(shí)現如下:

PWM生成設置(CubeMax自動(dòng)配置生成):

void MX_TIM5_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};


  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 0;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 1896;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init( htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization( htim5,  sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel( htim5,  sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit( htim5);


}

發(fā)送實(shí)現,注意點(diǎn)就是記錄為0時(shí)發(fā)載波,記錄為1時(shí)不發(fā)載波:

void InfraredSend(void)
{
uint16_t Count = 0;

while(Count < gsInfrared.SampleCount     gsInfrared.State == END_STATE)
    {
if(gsInfrared.BitValue[Count] == 0)
        {
            TIM5->CCR2 = 948;
            delay_us(gsInfrared.KeepTime[Count]);
            TIM5->CCR2 = 0;
        }
else
        {
            TIM5->CCR2 = 0;
            delay_us(gsInfrared.KeepTime[Count]);
            TIM5->CCR2 = 0;
        }


        Count ++;
    }


    delay_us(20000);
}

往PWM比較寄存器設置948即為設置38KPWM波,也可在初始化時(shí)固定948,在此函數內啟停定時(shí)器即可;

至此,自學(xué)習功能的全部思路已實(shí)現,通過(guò)對各個(gè)不同類(lèi)型的紅外遙控進(jìn)行功能測試,均成功。

PS:查看很多資料發(fā)現很多紅外解碼未判斷低電平時(shí)間,個(gè)人感覺(jué)不是很好,應該是不僅高電平時(shí)間得符合,低電平時(shí)間也應該符合。

自己寫(xiě)了一個(gè)小函數驗證了一下,這個(gè)函數只是驗證,未經(jīng)仔細推敲,還可優(yōu)化,僅供參考這一思想。

誤差設計:±200us(拍腦袋值)

void InFraredDataDeal(void)
{
uint32_t DataBuff = 0;
uint16_t Count = 0;


if(gsInfrared.State == END_STATE)
    {
        gsInfraredData.State = 0;


do
        {
switch(gsInfraredData.State)
            {
case 0:   //引導碼識別
            {


if(gsInfrared.KeepTime[0] >= 8800    gsInfrared.KeepTime[0] <= 9200    gsInfrared.BitValue[0] == 0)
                {
if(gsInfrared.KeepTime[1] >= 4300    gsInfrared.KeepTime[1] <= 4700    gsInfrared.BitValue[1] == 1)
                    {
if(gsInfrared.KeepTime[2] >= 360    gsInfrared.KeepTime[2] <= 760    gsInfrared.BitValue[2] == 0)
                        {
                            Count = 3;
                            gsInfraredData.State = 1;
                        }
                    }
else if(gsInfrared.KeepTime[1] >= 2300    gsInfrared.KeepTime[1] <= 2700    gsInfrared.BitValue[1] == 1)
                    {
if(gsInfrared.KeepTime[2] >= 360    gsInfrared.KeepTime[2] <= 760    gsInfrared.BitValue[2] == 0)
                        {
                            gsInfraredData.ReDataCount ++;
                            gsInfraredData.State = 3;
                        }
                    }
else
                    {
                        gsInfraredData.State = 3;
                    }


                }
else
                {
                    gsInfraredData.State = 3;
                }




            }
break;




case 1:   //數據解析
            {


if(gsInfrared.KeepTime[Count + 1] >= 360    gsInfrared.KeepTime[Count + 1] <= 760    gsInfrared.BitValue[Count + 1] == 0)
                {


if(gsInfrared.BitValue[Count] == 1)
                    {
if(gsInfrared.KeepTime[Count] >= 1480    gsInfrared.KeepTime[Count] <= 1880)
                        {
                            DataBuff <<= 1;
                            DataBuff |= 1;
                        }
else if(gsInfrared.KeepTime[Count] >= 360    gsInfrared.KeepTime[Count] <= 760    gsInfrared.BitValue[Count] == 1)
                        {
                            DataBuff <<= 1;
                            DataBuff |= 0;
                        }
else
                        {
                            gsInfraredData.State = 3;
                        }
                    }
                }


if(Count < gsInfrared.SampleCount)
                {
                    Count += 2;
                }
else
                {
                    gsInfraredData.State = 2;
                }


            }
break;


case 2:   //成功解析
            {
                gsInfraredData.Data = DataBuff;
                gsInfraredData.State = 3;


            }
break;


default:
            {
                gsInfraredData.State = 3;   //解析結束


            }
break;
            }


        }
while(gsInfraredData.State != 3);


        gsInfrared.State = NONE_STATE;
        gsInfrared.SampleCount = 0;
    }


}

解析的話(huà)一般高位在前,所以左移,經(jīng)測試幀格式為:引導碼+用戶(hù)碼+用戶(hù)碼反碼+命令碼+命令碼反碼,能成功解析數據!解析的話(huà)根據具體協(xié)議,具體分析。

審核編輯:彭菁

聲明:本文內容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權轉載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習之用,如有內容侵權或者其他違規問(wèn)題,請聯(lián)系本站處理。 舉報投訴
  • 遙控
    +關(guān)注

    關(guān)注

    11

    文章

    276

    瀏覽量

    56961
  • STM32
    +關(guān)注

    關(guān)注

    2247

    文章

    10693

    瀏覽量

    349920
  • 硬件
    +關(guān)注

    關(guān)注

    11

    文章

    2966

    瀏覽量

    65303
  • 自動(dòng)化
    +關(guān)注

    關(guān)注

    28

    文章

    5205

    瀏覽量

    78067
  • 低電平
    +關(guān)注

    關(guān)注

    1

    文章

    87

    瀏覽量

    13106
收藏 人收藏

    評論

    相關(guān)推薦

    STM32紅外遙控信號自學(xué)習實(shí)現

    很早前就想實(shí)現這個(gè)紅外遙控自學(xué)習的這個(gè)實(shí)驗,用于來(lái)自己控制房子里如空調等紅外遙控設備的自動(dòng)化,N
    的頭像 發(fā)表于 12-29 09:49 ?2005次閱讀
    <b class='flag-5'>STM32</b>之<b class='flag-5'>紅外</b><b class='flag-5'>遙控</b><b class='flag-5'>信號</b><b class='flag-5'>自學(xué)習</b><b class='flag-5'>實(shí)現</b>

    單片機紅外解碼的問(wèn)題

    本人在校學(xué)生,最近在想做基于51單片機的空調遙控器,空調型號(aux),但是不知道它的紅外協(xié)議是什么。在做了nec協(xié)議的解碼程序后,發(fā)現沒(méi)法識別。{:11:}求問(wèn):1.不知道空調的紅外協(xié)議能做出
    發(fā)表于 09-17 14:58

    自學(xué)習空調控制器

    最近的項目是做一個(gè)485控制的具有自學(xué)習功能的空調控制器,本來(lái)以為是個(gè)挺簡(jiǎn)單的紅外收發(fā),然后發(fā)現紅外編碼真的是個(gè)很復雜的事情,有沒(méi)有相關(guān)項目經(jīng)驗的提供點(diǎn)思路和經(jīng)驗,謝謝大神
    發(fā)表于 08-31 12:55

    哪位有基于M3的紅外自學(xué)習模塊的程序嗎 求打賞

    我現在有一個(gè)紅外自學(xué)習的程序但是功能貌似沒(méi)有實(shí)現so哪位大神打賞一個(gè)參考參考
    發(fā)表于 12-12 21:53

    紅外遙控器怎么相互兼容?

    自學(xué)習紅外遙控器的設計與實(shí)現
    發(fā)表于 11-08 09:00

    紅外自學(xué)習芯片和紅外編解碼芯片之間的區別?

    紅外自學(xué)習芯片和紅外編解碼芯片之間的區別在哪里?
    發(fā)表于 04-07 11:37

    如何讓電機自學(xué)習?

    變頻器換應用場(chǎng)合,恢復出廠(chǎng)設置了,如何讓電機自學(xué)習? 經(jīng)常有人電話(huà)給我們,變頻器更換了應用場(chǎng)合(為了省錢(qián)把變頻器最大化利用,你懂得)。比之前要求的環(huán)境呢精度要高,有沒(méi)有什么辦法。我們建議他讓電機
    發(fā)表于 12-24 16:04

    自學(xué)習紅外遙控器的設計與實(shí)現

     給出了自學(xué)習紅外遙控器的一種設計,采用測量脈沖寬度的原理,適用于大多數電子產(chǎn)品的遙控器。介紹了轉發(fā)紅外
    發(fā)表于 05-09 12:08 ?2270次閱讀
    <b class='flag-5'>自學(xué)習</b><b class='flag-5'>紅外</b><b class='flag-5'>遙控</b>器的設計與<b class='flag-5'>實(shí)現</b>

    STM32外部中斷實(shí)現紅外遙控功能

    STM32外部中斷實(shí)現紅外遙控功能。
    發(fā)表于 12-14 15:49 ?67次下載

    STM32_紅外遙控實(shí)驗

    STM32 紅外遙控實(shí)驗,很好的學(xué)習資料,快來(lái)下載吧
    發(fā)表于 02-15 17:08 ?32次下載

    基于交流異步電機驅動(dòng)磨床進(jìn)給位移的自學(xué)習控制

    基于交流異步電機驅動(dòng)磨床進(jìn)給位移的自學(xué)習控制
    發(fā)表于 04-25 10:00 ?8次下載

    自學(xué)習差異進(jìn)化算法

    為解決動(dòng)態(tài)環(huán)境下的多中心優(yōu)化問(wèn)題,提出自學(xué)習差異進(jìn)化算法。通過(guò)評估特定個(gè)體檢測到環(huán)境變化,自學(xué)習算子將群體引至新的環(huán)境,并保持群體的拓撲結構不變,以繼續當前的進(jìn)化趨勢。采用鄰域搜索機制加快算法的收斂
    發(fā)表于 03-13 16:46 ?0次下載

    基于ESP8266智能家居自學(xué)習紅外遙控設計 單片機源代碼+PCB電路圖

    基于ESP8266智能家居自學(xué)習紅外遙控設計 單片機源代碼+PCB電路圖(51單片機)-基于ESP8266智能家居自學(xué)習紅外
    發(fā)表于 07-22 15:11 ?88次下載
    基于ESP8266智能家居<b class='flag-5'>自學(xué)習</b><b class='flag-5'>紅外</b><b class='flag-5'>遙控</b>設計 單片機源代碼+PCB電路圖

    STM32紅外遙控信號自學(xué)習實(shí)現

    紅外接收端,如果接收到紅外38K載波,則IR輸出為低電平,如果不是載波包括固定低電平和固定高電平則輸出高電平。
    發(fā)表于 02-08 15:08 ?6次下載
    <b class='flag-5'>STM32</b>之<b class='flag-5'>紅外</b><b class='flag-5'>遙控</b><b class='flag-5'>信號</b><b class='flag-5'>自學(xué)習</b><b class='flag-5'>實(shí)現</b>

    紅外遙控自學(xué)習實(shí)現原理詳解

    很早前就想實(shí)現這個(gè)紅外遙控自學(xué)習的這個(gè)實(shí)驗,用于來(lái)自己控制房子里如空調等紅外遙控設備的自動(dòng)化,N
    的頭像 發(fā)表于 04-24 16:16 ?6089次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看