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

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

3天內(nèi)不再提示

用STM32CubeMx配置定時器

嵌入式技術(shù)開發(fā) ? 來源:嵌入式技術(shù)開發(fā) ? 2023-02-16 09:08 ? 次閱讀

1.NEC協(xié)議

紅外遙控是一種比較常用的通訊方式,目前紅外遙控的編碼方式中,應(yīng)用比較廣泛的是NEC協(xié)議。

NEC協(xié)議的特點如下:

1)載波頻率為 38KHz

2)8位地址和 8位指令長度

3)地址和命令2次傳輸(確保可靠性)

4)PWM 脈沖位置調(diào)制,以發(fā)射紅外載波的占空比代表“0”和“1” 其邏輯1與邏輯0的表示如圖所示:

c6375f78-ad47-11ed-bfe3-dac502259ad0.png

可以看到,邏輯1的位時間為2.25ms,脈沖時間560us;邏輯0的位時間為1.12ms,脈沖時間560us。

一個完整的NEC數(shù)據(jù)包如下:

c65f5bd6-ad47-11ed-bfe3-dac502259ad0.png

首次發(fā)送的是9ms高電平+4.5ms低電平,為引導(dǎo)碼。

接下來是8bit的地址碼+8bit地址碼的反碼+8bit命令碼+8bit命令碼的反碼。

以上是一個正常的數(shù)據(jù)包,但可能存在一種情況:當長按某個鍵時,發(fā)送的是以110ms為周期的重復(fù)碼,如下圖:

c67cf09c-ad47-11ed-bfe3-dac502259ad0.png

重復(fù)碼由9ms高電平和2.25ms的低電平以及560us的高電平組成。

2.解碼程序

在上面的圖中可以看到,邏輯1和邏輯0的位時間是不同的,占空比也不同。

所以我們可以根據(jù)位時間的長短來解碼,也可以根據(jù)占空比的不同(1/2或1/4)來解碼,或者二者同時作為解碼條件。這

里我們介紹根據(jù)位時間來解碼。 需要注意的是,很多紅外一體接收頭為了提高接受靈敏度。

輸入高電平,其輸出的是相反的低電平。

下圖為示波器實際捕獲的一組數(shù)據(jù):

c69fcd6a-ad47-11ed-bfe3-dac502259ad0.png

可以看到,空閑時為高電平,引導(dǎo)碼為9ms低電平+4.5ms高電平。根據(jù)位時間解碼的話,我們就不必關(guān)系高低電平各自的時間,只需關(guān)系總時間就行,即:引導(dǎo)碼為13.5ms,邏輯1為2.25ms,邏輯0為1.12ms。 首先用STM32CubeMx配置定時器。

系統(tǒng)時鐘等的配置這里不在贅述,參考其它教程。

這里使用TIM3的Channel1作為捕獲通道配置如下:

c6c2bce4-ad47-11ed-bfe3-dac502259ad0.png

1)定時器時鐘為內(nèi)部時鐘

2)Channel1配置為輸入捕獲模式

3)分頻系數(shù)為63,因為系統(tǒng)時鐘為64M,這樣定時器實際時鐘為64/(63+1)=1M,主要是為了程序中方便計算。

4)捕獲方式為下降沿捕獲

5)最后別忘了打開定時器的中斷

c7009f00-ad47-11ed-bfe3-dac502259ad0.png

最后生成代碼。

在生成的TIM3中斷函數(shù)中,屏蔽生成的中斷處理還是,添加自己的解碼程序如下:

uint32_t TIM3_Over_Cnt = 0;//tim3溢出次數(shù)
uint32_t TIM3_Sum_Cnt = 0;//兩次下降沿之間的時間間隔
uint32_t cnt0 = 0;
uint8_t IR_Data[60];


void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */


  /* USER CODE END TIM3_IRQn 0 */
//  HAL_TIM_IRQHandler(&htim3);
  /* USER CODE BEGIN TIM3_IRQn 1 */
    if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE))      //定時器溢出中斷
    {
        __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);    //清除中斷標記
        TIM3_Over_Cnt++;
    }
    cnt0 = __HAL_TIM_GET_COUNTER(&htim3);
    TIM3_Sum_Cnt = (TIM3_Over_Cnt << 16) + cnt0;//獲取計數(shù)器的值
    __HAL_TIM_SetCounter(&htim3,0);//清零重新計數(shù)
    TIM3_Over_Cnt = 0;//清零重新計數(shù)


    if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC1) != RESET)//TIM3CH1捕獲中斷
    {
       if(StartRevFlag == 1)//接收到引導(dǎo)碼,開始解碼
       {
         if(TIM3_Sum_Cnt > 36000)//大于36ms認為是結(jié)束
         {
           RevComplete = 1;//解碼完成
           IR_Tick = 0;
         }
         else if(RevComplete == 0)
         {
           if(TIM3_Sum_Cnt > 1000 && TIM3_Sum_Cnt < 1300)//1ms~1.3ms認為是低電平
            IR_Data[IR_Idx] = 0;
           else  if(TIM3_Sum_Cnt > 2100 && TIM3_Sum_Cnt < 2400)//2.1ms~2.4ms認為是高電平
            IR_Data[IR_Idx] = 1;
           else //接收錯誤,重新開始
             StartRevFlag = 0;
           IR_Idx++;
           if(IR_Idx > 59)
             IR_Idx = 59;
        }


       }
       else
       {
         if(TIM3_Sum_Cnt > 13000 && TIM3_Sum_Cnt < 14000)//13~14ms引導(dǎo)碼
         {
           StartRevFlag = 1;
         }
         IR_Tick = 0;
         RevComplete = 0;//解碼完成標志置零
         IR_Idx = 0;//有效解碼位
         TIM3_Over_Cnt = 0;
         TIM3_Sum_Cnt = 0;//定時器計數(shù)清零
       }
        __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_CC1);
    }


  /* USER CODE END TIM3_IRQn 1 */
}
解碼程序根據(jù)每次捕獲下降沿之間的間隔判斷是引導(dǎo)碼還是邏輯1或邏輯0。

接收到引導(dǎo)碼之后,再開始將解碼的數(shù)據(jù)保存下來。

最后通過也是時長來判斷解碼結(jié)束。

這里沒有判斷重復(fù)碼,有興趣的小伙伴可以自己加上。

中斷函數(shù)中,只是將每一位解碼并保存,最后還需要在主程序中組合成字節(jié)并判斷處理。
void IR_Rev()
{
  uint8_t num = IR_Idx / 8;
  uint8_t IRValue[8];


  if(RevComplete == 1 && StartRevFlag == 1 && IR_Tick > 20)
  {
    if(num > 7)
      num = 7;


    for(uint8_t j=0;j>1;
        if(IR_Data[j*8+i])
          IRValue[j] |= 0x80;
      }
    }
    if(IRValue[0] == 0x00 && IRValue[1] == 0xFF)//地址碼正確
    {
switch(IRValue[2])//判斷數(shù)據(jù)碼
      {
        case 0x46:
          KeyValue = S_key_Menu;
          break;
        case 0x43:
          KeyValue = S_key_Set;
          break;
        case 0x40:
          KeyValue = S_key_Rst;
          break;
        case 0x15:
          KeyValue = S_key_Down;
          break;
        case 0x09:
          KeyValue = S_key_Up;
break;
      }
    }
    StartRevFlag = 0;
    RevComplete = 0;
    IR_Tick = 0;
  }
}





審核編輯:劉清

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

    關(guān)注

    0

    文章

    238

    瀏覽量

    99053
  • STM32
    +關(guān)注

    關(guān)注

    2262

    文章

    10846

    瀏覽量

    353676
  • 定時器
    +關(guān)注

    關(guān)注

    23

    文章

    3226

    瀏覽量

    114142
  • 紅外遙控
    +關(guān)注

    關(guān)注

    22

    文章

    347

    瀏覽量

    45478

原文標題:STM32定時器實現(xiàn)紅外接收與解碼

文章出處:【微信號:嵌入式技術(shù)開發(fā),微信公眾號:嵌入式技術(shù)開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    STM32CubeMx入門教程(3):定時器的使用

    導(dǎo)語“ 使用STM32CubeMx 生成初始化定時器代碼,實現(xiàn)定時器特定定時
    發(fā)表于 07-11 15:22 ?3558次閱讀
    <b class='flag-5'>STM32CubeMx</b>入門教程(3):<b class='flag-5'>定時器</b>的使用

    STM32CubeMx入門教程(4):PWM應(yīng)用

    導(dǎo)語“使用STM32CubeMx配置定時器輸出PWM波,生成初始化代碼?!?/div>
    發(fā)表于 07-11 15:23 ?2066次閱讀
    <b class='flag-5'>STM32CubeMx</b>入門教程(4):PWM應(yīng)用

    stm32cubemx配置定時器

    stm32cubemx配置定時器,文章目錄前言keil主函數(shù)時鐘配置中斷響應(yīng)CUBE主函數(shù)配置函數(shù)中斷響應(yīng)前言本文主要介紹使用keil和
    發(fā)表于 08-10 07:55

    STM32CUBEMX配置教程

    STM32CUBEMX配置教程(四)定時器中斷配置基于STM32H743VI使用STM32CUBEMX
    發(fā)表于 08-17 09:02

    Stm32CubeMx基本定時器的概念

    Stm32CubeMx基本定時器基本定時器概念Stm32CubeMx 配置基本配置
    發(fā)表于 08-18 08:18

    怎樣使用STM32cubemx配置通用定時器

    STM32定時器的功能特點有哪些呢?STM32的通用定時器有哪些應(yīng)用?怎樣使用STM32cubemx
    發(fā)表于 10-22 07:46

    求助STM32CubeMX是如何配置定時器中斷的呢

    STM32CubeMX是如何配置定時器中斷的呢?有哪些基本配置步驟?
    發(fā)表于 11-23 06:12

    【MCU】基于STM32CubeMX定時器中斷實現(xiàn)LED閃爍

    基于STM32CubeMX定時器中斷實現(xiàn) LED 閃爍本實驗基于STM32CubeMX實現(xiàn)對STM32開發(fā)板的配置,通過
    發(fā)表于 10-29 11:06 ?20次下載
    【MCU】基于<b class='flag-5'>STM32CubeMX</b><b class='flag-5'>定時器</b>中斷實現(xiàn)LED閃爍

    STM32CUBEMX配置教程(十二)STM32定時器觸發(fā)的固定頻率ADC采樣(使用DMA)

    STM32CUBEMX配置教程(十二)STM32定時器觸發(fā)的固定頻率ADC采樣(使用DMA)
    發(fā)表于 11-24 13:51 ?85次下載
    <b class='flag-5'>STM32CUBEMX</b><b class='flag-5'>配置</b>教程(十二)<b class='flag-5'>STM32</b>的<b class='flag-5'>定時器</b>觸發(fā)的固定頻率ADC采樣(使用DMA)

    STM32CUBEMX配置教程(十三)STM32定時器觸發(fā)的固定頻率DAC輸出(使用DMA)

    STM32CUBEMX配置教程(十三)STM32定時器觸發(fā)的固定頻率DAC輸出(使用DMA)
    發(fā)表于 11-24 14:06 ?46次下載
    <b class='flag-5'>STM32CUBEMX</b><b class='flag-5'>配置</b>教程(十三)<b class='flag-5'>STM32</b>的<b class='flag-5'>定時器</b>觸發(fā)的固定頻率DAC輸出(使用DMA)

    STM32 CubeMX學(xué)習(xí):3. 定時器閃爍LED

    STM32 CubeMX學(xué)習(xí):3. 定時器閃爍LED 系列文章目錄前期的準備點亮 LED閃爍 LED定時器閃爍LED未完待續(xù)…文章目錄STM32
    發(fā)表于 11-25 10:21 ?13次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>CubeMX</b>學(xué)習(xí):3. <b class='flag-5'>定時器</b>閃爍LED

    STM32定時器單脈沖模式及其應(yīng)用

    STM32定時器可以配置為單脈沖模式,所謂的單脈沖就是通過配置定時器使其在一個可控延時后,產(chǎn)生一個脈寬可控的脈沖。使用
    發(fā)表于 11-25 11:06 ?64次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>定時器</b>單脈沖模式及其應(yīng)用

    STM32CubeMX實戰(zhàn)教程(五)——通用定時器(PWM輸出)

    前言在上一章《STM32CubeMX實戰(zhàn)教程(四)——基本定時器(還是點燈)》中,已經(jīng)介紹過基本定時器的功能及用法,在這一章中,我講主要介紹一下通用定時器的相關(guān)功能以及
    發(fā)表于 11-26 15:36 ?13次下載
    <b class='flag-5'>STM32CubeMX</b>實戰(zhàn)教程(五)——通用<b class='flag-5'>定時器</b>(PWM輸出)

    STM32CubeMX_定時器中斷_PWM

    文章目錄前言STM32CubeMX新建工程基本定時器配置生成代碼定時器中斷PWM配置工程代碼前言STM3
    發(fā)表于 12-05 13:51 ?13次下載
    <b class='flag-5'>STM32CubeMX</b>_<b class='flag-5'>定時器</b>中斷_PWM

    STM32CUBEMX配置教程(一)基礎(chǔ)配置

    STM32CUBEMX配置教程合集(一)
    發(fā)表于 12-14 18:41 ?17次下載
    <b class='flag-5'>STM32CUBEMX</b><b class='flag-5'>配置</b>教程(一)基礎(chǔ)<b class='flag-5'>配置</b>