chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

單片機(jī)軟件定時(shí)器的實(shí)現(xiàn)方法

CHANBAEK ? 來(lái)源:固件工人 ? 作者:固件工人 ? 2023-01-17 15:14 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1.1 背景

目前市面上的單片機(jī)基本都帶有硬件定時(shí)器功能,單片機(jī)應(yīng)用程序開發(fā)中也經(jīng)常會(huì)用到定時(shí)器進(jìn)行一些和時(shí)間相關(guān)的開發(fā),比如延時(shí)或者周期性地執(zhí)行一些操作。單片機(jī)的硬件定時(shí)器個(gè)數(shù)一般都是固定的,而且一些低端單片機(jī)的定時(shí)器個(gè)數(shù)一般都比較少,在一些有多個(gè)周期性操作的應(yīng)用場(chǎng)合就無(wú)法滿足要求。這時(shí),就可以基于硬件定時(shí)器派生出軟件定時(shí)器,來(lái)滿足這種多種周期性或多個(gè)單次延時(shí)操作的需求。軟件定時(shí)器的優(yōu)點(diǎn)就是個(gè)數(shù)可以根據(jù)實(shí)際需求進(jìn)行靈活配置,而且可以實(shí)現(xiàn)多種不同的定時(shí)周期。

1.2 測(cè)試平臺(tái)

這里使用的開發(fā)環(huán)境和相關(guān)硬件如下。

  • 操作系統(tǒng):Ubuntu 20.04.2 LTS x86_64(使用uname -a命令查看)
  • 集成開發(fā)環(huán)境(IDE):Eclipse IDE for Embedded C/C++ Developers,Version: 2021-06 (4.20.0)
  • 硬件開發(fā)板:STM32F429I-DISCO
  • 本文對(duì)應(yīng)的例程代碼鏈接如下。

https://download.csdn.net/download/goodrenze/85106391

1.3 軟件定時(shí)器實(shí)現(xiàn)方法

這里就結(jié)合開發(fā)板STM32F429I-DISCO上的STM32F429ZI的單片機(jī)來(lái)演示軟件定時(shí)器的實(shí)現(xiàn)方法。

一般定時(shí)器的計(jì)數(shù)方式有2種:一種是單次定時(shí),即定時(shí)時(shí)間到了之后,自動(dòng)停止定時(shí);另一種是周期定時(shí),定時(shí)時(shí)間到了之后,自動(dòng)按照之前的定時(shí)周期重新定時(shí)。對(duì)于周期定時(shí),可以手動(dòng)進(jìn)行定時(shí)器的啟動(dòng)、關(guān)閉和刪除。

下面講解軟件定時(shí)器的實(shí)現(xiàn)步驟。

1)由于軟件定時(shí)器是基于硬件定時(shí)器的,所以需要先初始化一個(gè)硬件定時(shí)器,并啟動(dòng)硬件定時(shí)器。這里使用STM32F429ZI的硬件定時(shí)器7,定時(shí)器的定時(shí)周期為10ms,即每10ms產(chǎn)生一次定時(shí)器中斷。初始化代碼如下。

TIM_HandleTypeDef    Tim7Handle;
uint8_t InitTim7(uint32_t period_ms)
{
  uint16_t uwPrescalerValue;


  if(0 == period_ms)
  {
    return 1;
  }


  __HAL_RCC_TIM7_CLK_ENABLE();


  HAL_NVIC_SetPriority(TIM7_IRQn, 2, 0);


  HAL_NVIC_EnableIRQ(TIM7_IRQn);


  /* Compute the prescaler value to have TIM7 counter clock equal to 10 KHz */
  uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;


  /* Set TIM7 instance */
  Tim7Handle.Instance = TIM7;
  Tim7Handle.Init.Period = period_ms * 10 - 1;
  Tim7Handle.Init.Prescaler = uwPrescalerValue;
  Tim7Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  Tim7Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_Base_Init(&Tim7Handle) != HAL_OK)
  {
    return 1;
  }


  /* Start the TIM Base generation in interrupt mode */
  if(HAL_TIM_Base_Start_IT(&Tim7Handle) != HAL_OK)
  {
    return 1;
  }


  return 0;
}

2)硬件定時(shí)器定時(shí)時(shí)間到了之后,會(huì)產(chǎn)生中斷,所以需要實(shí)現(xiàn)定時(shí)器中斷處理函數(shù)。這里基于STM32的HAL進(jìn)行開發(fā),所以在定時(shí)器的中斷入口函數(shù)中直接調(diào)用HAL_TIM_IRQHandler()函數(shù),然后實(shí)現(xiàn)實(shí)際的中斷處理回調(diào)函數(shù)HAL_TIM_PeriodElapsedCallback()。對(duì)應(yīng)的代碼如下。其中調(diào)用的軟件定時(shí)器更新函數(shù)會(huì)在后面介紹。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim == &Tim7Handle)
  {
    SwTimerUpdateCount();
  }
}

3)設(shè)計(jì)軟件定時(shí)器對(duì)應(yīng)的結(jié)構(gòu)體。按照軟件定時(shí)器的實(shí)際使用特點(diǎn),必須要包含定時(shí)器計(jì)數(shù)值和周期定時(shí)器的重裝載值,另外還要有定時(shí)器時(shí)間到之后需要執(zhí)行的回調(diào)函數(shù)。對(duì)應(yīng)的軟件定時(shí)器結(jié)構(gòu)體如下所示。當(dāng)結(jié)構(gòu)體中的TimerCount和TimerReload都為0時(shí),說(shuō)明軟件定時(shí)器處于空閑狀態(tài),可以分配使用;如果TimerCount非0,而TimerReload為0,說(shuō)明軟件定時(shí)器是單次定時(shí)器;如果TimerCount和TimerReload都非0,說(shuō)明軟件定時(shí)器是周期定時(shí)器。

typedef void (*TimerCallbackFunc)(void);


typedef struct _SwTimer_t
{
  uint32_t TimerCount;
  uint32_t TimerReload;
  TimerCallbackFunc TimerCallback;
}SwTimer_t;

4)這里將軟件定時(shí)器設(shè)置成10個(gè),可以通過(guò)宏定義來(lái)設(shè)置軟件定時(shí)器個(gè)數(shù)。使用軟件定時(shí)器結(jié)構(gòu)體定義一個(gè)具有10個(gè)定時(shí)器的數(shù)組。如下代碼所示。

#define SW_TIMER_NUM    10
SwTimer_t SwTimer[SW_TIMER_NUM];

5)軟件定時(shí)器復(fù)位函數(shù),用于實(shí)現(xiàn)所有軟件定時(shí)器的重置操作,重置后,所有軟件定時(shí)器都處于空閑狀態(tài),可供分配使用。函數(shù)代碼如下。

void SwTimerReset(void)
{
  uint8_t i;


  for(i = 0; i < SW_TIMER_NUM; i++)
  {
    SwTimer[i].TimerCount = 0;
    SwTimer[i].TimerReload = 0;
    SwTimer[i].TimerCallback = 0;
  }
}

6)啟動(dòng)單次定時(shí)器函數(shù),用于實(shí)現(xiàn)單次定時(shí),定時(shí)時(shí)間到了之后,執(zhí)行對(duì)應(yīng)回調(diào)函數(shù),并停止定時(shí)和釋放定時(shí)器資源。函數(shù)代碼如下。如果啟動(dòng)成功,函數(shù)返回定時(shí)器的索引號(hào)(該值小于定時(shí)器個(gè)數(shù)值);啟動(dòng)失敗,返回的定時(shí)器索引號(hào)等于定時(shí)器的個(gè)數(shù)。

uint8_t SwTimerStartSingleTimer(uint32_t single_ms, TimerCallbackFunc TimerCallback)
{
  uint8_t i;


  single_ms /= MINI_PERIOD_MS;
  if(0 == single_ms)
  {
    single_ms = 1;
  }
  for(i = 0; i < SW_TIMER_NUM; i++)
  {
    if((SwTimer[i].TimerCount == 0) && (SwTimer[i].TimerReload == 0))
    {
      SwTimer[i].TimerCount = single_ms;
      SwTimer[i].TimerCallback = TimerCallback;
      break;
    }
  }


  return i;
}

7)添加周期定時(shí)器函數(shù),用于添加一個(gè)新的周期定時(shí)器但不啟動(dòng)定時(shí),需要手動(dòng)啟動(dòng)定時(shí)器。函數(shù)代碼如下。如果添加成功,函數(shù)返回定時(shí)器的索引號(hào)(該值小于定時(shí)器個(gè)數(shù)值);添加失敗,返回的定時(shí)器索引號(hào)等于定時(shí)器的個(gè)數(shù)。

uint8_t SwTimerAddPeriodTimer(uint32_t period_ms, TimerCallbackFunc TimerCallback)
{
  uint8_t i;


  period_ms /= MINI_PERIOD_MS;
  if(0 == period_ms)
  {
    period_ms = 1;
  }
  for(i = 0; i < SW_TIMER_NUM; i++)
  {
    if((SwTimer[i].TimerCount == 0) && (SwTimer[i].TimerReload == 0))
    {
      SwTimer[i].TimerReload = period_ms;
      SwTimer[i].TimerCallback = TimerCallback;
      break;
    }
  }


  return i;
}

8)啟動(dòng)周期定時(shí)器函數(shù),用于啟動(dòng)指定定時(shí)器索引號(hào)的周期定時(shí)器開始定時(shí)。函數(shù)代碼如下。如果啟動(dòng)成功,函數(shù)返回定時(shí)器的索引號(hào)(該值小于定時(shí)器個(gè)數(shù)值);啟動(dòng)失敗,返回的定時(shí)器索引號(hào)等于定時(shí)器的個(gè)數(shù)。

uint8_t SwTimerStartPeroidTimer(uint8_t timer_no)
{
  if(SW_TIMER_NUM <= timer_no)
  {
    return SW_TIMER_NUM;
  }
  else if((SwTimer[timer_no].TimerCount == 0) && (SwTimer[timer_no].TimerReload == 0))
  {
    return SW_TIMER_NUM;
  }
  else
  {
    SwTimer[timer_no].TimerCount = SwTimer[timer_no].TimerReload;
    return timer_no;
  }
}

9)停止定時(shí)器函數(shù),用于結(jié)束指定定時(shí)器索引號(hào)的定時(shí)器的定時(shí),可用于停止單次或周期定時(shí)器。函數(shù)代碼如下。如果停止成功,函數(shù)返回定時(shí)器的索引號(hào)(該值小于定時(shí)器個(gè)數(shù)值);停止失敗,返回的定時(shí)器索引號(hào)等于定時(shí)器的個(gè)數(shù)。

uint8_t SwTimerStopTimer(uint8_t timer_no)
{
  if(SW_TIMER_NUM <= timer_no)
  {
    return SW_TIMER_NUM;
  }
  else
  {
    SwTimer[timer_no].TimerCount = 0;
    return timer_no;
  }
}

10)刪除周期定時(shí)器函數(shù),用于結(jié)束指定定時(shí)器索引號(hào)的周期定時(shí)器的定時(shí),并釋放定時(shí)器資源。函數(shù)代碼如下。如果刪除成功,函數(shù)返回定時(shí)器的索引號(hào)(該值小于定時(shí)器個(gè)數(shù)值);刪除失敗,返回的定時(shí)器索引號(hào)等于定時(shí)器的個(gè)數(shù)。

uint8_t SwTimerDeletePeroidTimer(uint8_t timer_no)
{
  if(SW_TIMER_NUM <= timer_no)
  {
    return SW_TIMER_NUM;
  }
  else
  {
    SwTimer[timer_no].TimerCount = 0;
    SwTimer[timer_no].TimerReload = 0;
    return timer_no;
  }
}

11)軟件定時(shí)器計(jì)數(shù)值更新函數(shù),用于更新每個(gè)已經(jīng)啟動(dòng)定時(shí)的軟件定時(shí)器的計(jì)數(shù)值,該函數(shù)必須在硬件定時(shí)器的中斷處理函數(shù)中調(diào)用。函數(shù)的實(shí)現(xiàn)思路是:遍歷所有的軟件定時(shí)器,如果遍歷到的定時(shí)器的計(jì)數(shù)值非0,則進(jìn)行減1操作。如果減1后計(jì)數(shù)值為0,如果定時(shí)器的重裝載值非0,說(shuō)明是周期定時(shí)器,需要將計(jì)數(shù)值更新成對(duì)應(yīng)的重裝載值以便重新定時(shí),同時(shí)執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù);如果定時(shí)器的重裝載值是0,說(shuō)明是單次定時(shí)器,執(zhí)行完回調(diào)函數(shù)后自動(dòng)停止定時(shí)并釋放定時(shí)器資源。如果減1后計(jì)數(shù)值不為0,繼續(xù)遍歷更新后續(xù)的定時(shí)器,直到所有定時(shí)器都遍歷完畢。函數(shù)流程圖和對(duì)應(yīng)代碼如下。

圖1 軟件定時(shí)器計(jì)數(shù)值更新函數(shù)

void SwTimerUpdateCount(void)
{
  uint8_t i;


  for(i = 0; i < SW_TIMER_NUM; i++)
  {
    if(SwTimer[i].TimerCount != 0)
    {
      SwTimer[i].TimerCount -= 1;
      if(SwTimer[i].TimerCount == 0)
      {
        if(SwTimer[i].TimerReload != 0)
        {
          SwTimer[i].TimerCount = SwTimer[i].TimerReload;
        }
        if(SwTimer[i].TimerCallback != 0)
        {
          SwTimer[i].TimerCallback();
        }
      }
    }
  }
}

12)軟件定時(shí)器的實(shí)際使用示例。代碼如下。

int main(void)
{
  uint8_t no;


  HAL_Init();


  /* Configure the system clock to 168 MHz */
  SystemClock_Config();


  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  InitTim7(MINI_PERIOD_MS);
  SwTimerReset();
  no = SwTimerAddPeriodTimer(500, ToggleLed3);
  if(no < SW_TIMER_NUM)
  {
    SwTimerStartPeroidTimer(no);
  }
#if 1
  no = SwTimerAddPeriodTimer(1000, ToggleLed4);
  if(no < SW_TIMER_NUM)
  {
    SwTimerStartPeroidTimer(no);
  }
#else
  no = SwTimerStartSingleTimer(5000, ToggleLed4);
#endif


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

    關(guān)注

    6074

    文章

    45453

    瀏覽量

    667050
  • STM32
    +關(guān)注

    關(guān)注

    2307

    文章

    11150

    瀏覽量

    372402
  • 軟件定時(shí)器
    +關(guān)注

    關(guān)注

    0

    文章

    18

    瀏覽量

    7041
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3365

    瀏覽量

    122363
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4413

    瀏覽量

    67197
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    單片機(jī)定時(shí)器的用法

    本章以CW32通用定時(shí)器為例介紹單片機(jī)定時(shí)器的用法。
    的頭像 發(fā)表于 01-04 10:37 ?2682次閱讀
    <b class='flag-5'>單片機(jī)</b><b class='flag-5'>定時(shí)器</b>的用法

    Winbond 51單片機(jī)定時(shí)器初值計(jì)算(工具軟件)

    Winbond 51單片機(jī)定時(shí)器初值計(jì)算(工具軟件)
    發(fā)表于 06-14 07:53 ?237次下載

    單片機(jī)視頻教程06:使用定時(shí)器方法

    《手把手教你學(xué)單片機(jī)單片機(jī)視頻教程06:使用定時(shí)器方法 單片機(jī)視頻教程06:使用定時(shí)器
    發(fā)表于 08-21 09:33 ?1.7w次閱讀
    <b class='flag-5'>單片機(jī)</b>視頻教程06:使用<b class='flag-5'>定時(shí)器</b>的<b class='flag-5'>方法</b>

    51單片機(jī)定時(shí)器計(jì)算軟件

    電子發(fā)燒友網(wǎng)站提供《51單片機(jī)定時(shí)器計(jì)算軟件.zip》資料免費(fèi)下載
    發(fā)表于 08-10 12:48 ?1次下載

    基于51單片機(jī)定時(shí)器2的操作與實(shí)現(xiàn)

    基于51單片機(jī)定時(shí)器2的操作與實(shí)現(xiàn),51單片機(jī)定時(shí)器2的使用!
    發(fā)表于 02-22 17:53 ?14次下載

    52單片機(jī)有幾個(gè)定時(shí)器?52單片機(jī)定時(shí)器1和52單片機(jī)定時(shí)器2程序?qū)Ρ?/a>

    52單片機(jī)有幾個(gè)定時(shí)器?STC89C52RC其實(shí)是有三個(gè)定時(shí)器單片機(jī),STC89C52RC共有3個(gè)定時(shí)器,分別是T0、T1、T2。而51
    發(fā)表于 11-10 14:30 ?3.7w次閱讀

    如何基于51單片機(jī)利用定時(shí)器實(shí)現(xiàn)PWM的方法詳細(xì)概述

    51單片機(jī)是可以輸出PWM的,比較的麻煩。此時(shí)需要用到內(nèi)部定時(shí)器來(lái)實(shí)現(xiàn),可用兩個(gè)定時(shí)器實(shí)現(xiàn),也可以用一個(gè)
    的頭像 發(fā)表于 06-12 20:01 ?3.4w次閱讀

    ESP8266的管腳的控制和軟件定時(shí)器的使用

    先說(shuō)定時(shí)器,ESP8266內(nèi)部的定時(shí)器分為軟件定時(shí)器和硬件定時(shí)器。手冊(cè)中指出硬件定時(shí)器其實(shí)就跟
    的頭像 發(fā)表于 07-29 14:57 ?1w次閱讀
    ESP8266的管腳的控制和<b class='flag-5'>軟件</b><b class='flag-5'>定時(shí)器</b>的使用

    使用單片機(jī)實(shí)現(xiàn)定時(shí)器的程序免費(fèi)下載

      本文檔的主要內(nèi)容詳細(xì)介紹的是使用單片機(jī)實(shí)現(xiàn)定時(shí)器的程序免費(fèi)下載。
    發(fā)表于 06-05 17:35 ?6次下載
    使用<b class='flag-5'>單片機(jī)</b><b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>定時(shí)器</b>的程序免費(fèi)下載

    基于單片機(jī)定時(shí)器的設(shè)計(jì)方法

    單片機(jī)實(shí)現(xiàn)一個(gè)定時(shí)器只要對(duì)單片機(jī)里的特殊寄存進(jìn)行設(shè)置就可以實(shí)現(xiàn)了,下面我與朋友們說(shuō)說(shuō)這個(gè)0到
    的頭像 發(fā)表于 11-02 16:58 ?1.1w次閱讀
    基于<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>定時(shí)器</b>的設(shè)計(jì)<b class='flag-5'>方法</b>

    基于51單片機(jī)定時(shí)器

    設(shè)計(jì)思路。這樣自己拿到任何型號(hào)的51單片機(jī),只要有原理圖,都可以自主設(shè)計(jì)。博主剛接觸單片機(jī),才疏學(xué)淺,可能會(huì)出現(xiàn)設(shè)計(jì)不足和錯(cuò)誤,歡迎大家評(píng)論區(qū)交流。^ _ ^/********************************************************
    發(fā)表于 11-04 21:06 ?35次下載
    基于51<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>定時(shí)器</b>

    51單片機(jī)——定時(shí)器

    51單片機(jī)——定時(shí)器為什么使用定時(shí)器定時(shí)器原理?定時(shí)器設(shè)置中斷配置源代碼為什么使用定時(shí)器?之前
    發(fā)表于 11-11 16:36 ?40次下載
    51<b class='flag-5'>單片機(jī)</b>——<b class='flag-5'>定時(shí)器</b>

    51單片機(jī)定時(shí)器中斷

    定時(shí)器介紹:51單片機(jī)定時(shí)器屬于單片機(jī)的內(nèi)部資源,其電路連接和運(yùn)轉(zhuǎn)均在單片機(jī)的內(nèi)部完成定時(shí)器
    發(fā)表于 11-11 19:36 ?7次下載
    51<b class='flag-5'>單片機(jī)</b><b class='flag-5'>定時(shí)器</b>中斷

    單片機(jī)如何只用定時(shí)器實(shí)現(xiàn)秒表_MSP430單片機(jī)定時(shí)器A結(jié)構(gòu)及其應(yīng)用范例

    )單片機(jī)定時(shí)器可以用來(lái)實(shí)現(xiàn)計(jì)時(shí),延時(shí),信號(hào)頻率測(cè)量,信號(hào)觸發(fā)檢測(cè),脈沖脈寬信號(hào)測(cè)量,PWM信號(hào)發(fā)生。另外通過(guò)軟件編寫可以用作串口的波特率發(fā)生
    發(fā)表于 11-19 15:51 ?8次下載
    <b class='flag-5'>單片機(jī)</b>如何只用<b class='flag-5'>定時(shí)器</b><b class='flag-5'>實(shí)現(xiàn)</b>秒表_MSP430<b class='flag-5'>單片機(jī)</b><b class='flag-5'>定時(shí)器</b>A結(jié)構(gòu)及其應(yīng)用范例

    51單片機(jī)定時(shí)器中斷

    定時(shí)器介紹:51單片機(jī)定時(shí)器屬于單片機(jī)的內(nèi)部資源,其電路連接和運(yùn)轉(zhuǎn)均在單片機(jī)的內(nèi)部完成定時(shí)器
    發(fā)表于 11-20 20:36 ?15次下載
    51<b class='flag-5'>單片機(jī)</b><b class='flag-5'>定時(shí)器</b>中斷