在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

Free RTOS的軟件定時器

汽車電子技術 ? 來源:玩轉單片機 ? 作者: Julian ? 2023-02-10 15:53 ? 次閱讀

軟件定時器FreeRTOS中的一個重要模塊,使用軟件定時器可以方便的實現一些與超時或周期性相關的功能。


硬件定時器


芯片本身提供的定時功能。一般是由外部晶振提供給芯片輸入時鐘,芯片向軟件模塊提供一組配置寄存器,接受控制輸入,到達設定時間值后芯片中斷控制器產生時鐘中斷。硬件定時器的精度一般很高,可以達到納秒級別,并且是中斷觸發方式。


軟件定時器


軟件定時器是由操作系統提供的一類系統接口,它構建在硬件定時器基礎之上,使系統能夠提供不受硬件定時器資源限制的定時器服務,它實現的功能與硬件定時器也是類似的。


FreeRTOS 軟件定時器功能

裁剪:能通過宏關閉軟件定時器功能。

軟件定時器創建。

軟件定時器啟動。

軟件定時器停止。

軟件定時器復位。

軟件定時器刪除。


軟件定時器模式


單次模式:當用戶創建了定時器并啟動了定時器后,定時時間到了,只執行一次回調函數之后就將該定時器刪除,不再重新執行。

周期模式:這個定時器會按照設置的定時時間循環執行回調函數,直到用戶將定時器刪除

poYBAGPl9zqAEXkAAAE78KsCOCE553.png


FreeRTOS 通過一個 prvTimerTask 任務(也叫守護任務 Daemon)管理軟定時器,它是在啟動調度器時自動創建的,為了滿足用戶定時需求。prvTimerTask 任務會在其執行期間檢查用戶啟動的時間周期溢出的定時器,并調用其回調函數。只有設置 FreeRTOSConfig.h中的宏定義 configUSE_TIMERS 設置為 1 ,將相關代碼編譯進來,才能正常使用軟件定時器相關功能。

配置定時器

//啟用軟件定時器
#define configUSE_TIMERS                    1                              
//軟件定時器優先級
#define configTIMER_TASK_PRIORITY            (configMAX_PRIORITIES-1)        
//軟件定時器隊列長度
#define configTIMER_QUEUE_LENGTH            10                               
//軟件定時器任務堆棧大小
#define configTIMER_TASK_STACK_DEPTH        (configMINIMAL_STACK_SIZE*2) 


創建定時器

TimerHandle_t xTimerCreate( const char *pcTimerName, 
                            const TickType_t xTimerPeriod, 
                            const UBaseType_t uxAutoReload, 
                            void * const pvTimerID, 
                           TimerCallbackFunction_t pxCallbackFunction );

參數

pcTimerName:定時器名稱

xTimerPeriod :定時周期

uxAutoReload : 如果將uxAutoReload設置為pdTRUE,則計時器將以xTimerPeriod參數設置的頻率重復終止。如果將uxAutoReload設置為pdFALSE,則計時器將是一次觸發,并在其到期后進入休眠狀態。

pvTimerID分配給正在創建的計時器的標識符。

pxCallbackFunction計時器到期時要調用的函數

返回值

如果成功創建了計時器,則返回新創建的計時器的句柄。如果由于剩余的FreeRTOS堆不足而無法分配計時器結構而無法創建計時器,則返回NULL

啟動定時器

BaseType_t xTimerStart( TimerHandle_t xTimer, 
                        TickType_t xTicksToWait );

參數

xTimer:計時器的句柄

xTicksToWait:指定在計時器命令隊列已經滿的情況下,任務應保持阻塞狀態以等待空間可用的最大時間。

返回值

如果即使經過xBlockTime刻度后仍無法將啟動命令發送到計時器命令隊列,則將返回pdFAIL。如果命令已成功發送到計時器命令隊列,則將返回pdPASS。

停止定時器

BaseType_t xTimerStop( TimerHandle_t xTimer, 
                       TickType_t xTicksToWait );

參數:同上

返回值:同上


復位定時器

BaseType_t xTimerReset( TimerHandle_t xTimer, 
                        TickType_t xTicksToWait );

參數:同上

返回值:同上


刪除定時器

BaseType_t xTimerDelete( TimerHandle_t xTimer, 
                         TickType_t xTicksToWait );

參數:同上類似

返回值:同上類似


改變定時器周期

BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, 
                               TickType_txNewPeriod,
                               TickType_t xTicksToWait );

參數

xTimer:定時器的句柄

xNewPeriod:新的周期參數

xTicksToWait:指定在計時器命令隊列已經滿的情況下,任務應保持阻塞狀態以等待空間可用的最大時間。

返回值

如果即使經過xBlockTime滴答聲后仍無法將更改周期命令發送到計時器命令隊列,則將返回pdFAIL。如果命令已成功發送到計時器命令隊列,則將返回pdPASS。


還有中斷啟動定時器、停止、復位、改變周期的API函數,請查閱官方文檔!


附上小例程

#include "stm32f10x.h"
#include 
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "timers.h"

//毫秒級的延時
void Delay_Ms(u16 time)
{    
   u16 i=0;  
   while(time--)
   {
      i=12000;  //自己定義
      while(i--) ;    
   }
}

void LED_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;        //定義結構體變量
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);  //開啟時鐘
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;            //選擇你要設置的IO口
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;      //設置推挽輸出模式
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     //設置傳輸速率
  GPIO_Init(GPIOC,&GPIO_InitStructure);                //初始化GPIO
  
  GPIO_SetBits(GPIOC,GPIO_Pin_0);             //將LED端口拉高,熄滅LED
}

void KEY_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure; //定義結構體變量  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;     //選擇你要設置的IO口
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉輸入  
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;     //設置傳輸速率
  GPIO_Init(GPIOA,&GPIO_InitStructure);      /* 初始化GPIO */
  
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  //上拉輸入
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOE,&GPIO_InitStructure);
}


void USART_init(uint32_t bound)
{
  GPIO_InitTypeDef GPIO_InitStruct;   //定義GPIO結構體變量
  USART_InitTypeDef USART_InitStruct;   //定義串口結構體變量
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);   //使能GPIOC的時鐘
  
  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;   //配置TX引腳
  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;   //配置PA9為復用推挽輸出
  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;   //配置PA9速率
  GPIO_Init(GPIOA,&GPIO_InitStruct);   //GPIO初始化函數
  
  GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;   //配置RX引腳
  GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;   //配置PA10為浮空輸入
  GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;   //配置PA10速率
  GPIO_Init(GPIOA,&GPIO_InitStruct);   //GPIO初始化函數
  
  
  USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;   //發送接收模式
  USART_InitStruct.USART_Parity=USART_Parity_No;   //無奇偶校驗
  USART_InitStruct.USART_BaudRate=bound;   //波特率
  USART_InitStruct.USART_StopBits=USART_StopBits_1;   //停止位1位
  USART_InitStruct.USART_WordLength=USART_WordLength_8b;   //字長8位
  USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;   //無硬件數據流控制
  USART_Init(USART1,&USART_InitStruct);   //串口初始化函數
  
  USART_Cmd(USART1,ENABLE);   //使能USART1
}

int fputc(int ch,FILE *f)   //printf重定向函數
{
  USART_SendData(USART1,(uint8_t)ch);   //發送一字節數據
  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);   //等待發送完成
  return ch;
}


#define START_TASK_PRIO 5      //任務優先級
#define START_STK_SIZE 128      //任務堆棧大小
TaskHandle_t StartTask_Handler;   //任務句柄
void Start_Task(void *pvParameters);//任務函數

#define Low_TASK_PRIO 2       //任務優先級
#define Low_STK_SIZE 50       //任務堆棧大小
TaskHandle_t LowTask_Handler;     //任務句柄
void Low_Task(void *p_arg);     //任務函數

#define Med_TASK_PRIO 3       //任務優先級
#define Med_STK_SIZE 50       //任務堆棧大小
TaskHandle_t MedTask_Handler;     //任務句柄
void Med_Task(void *p_arg);     //任務函數

TimerHandle_t Time0Handler = NULL;  //軟件定時器句柄
void Time0Callback( TimerHandle_t pxTimer );//回調函數

int main( void ) 
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組 4
  
  LED_Init(); //初始化 LED
  KEY_Init();
  USART_init(9600);
  
  //創建開始任務
  xTaskCreate(
    (TaskFunction_t )Start_Task,     //任務函數
    (const char* )"Start_Task",     //任務名稱
    (uint16_t )START_STK_SIZE,       //任務堆棧大小
    (void* )NULL,             //傳遞給任務函數的參數
    (UBaseType_t )START_TASK_PRIO,     //任務優先級
    (TaskHandle_t* )&StartTask_Handler  //任務句柄 
  );
  vTaskStartScheduler();  //開啟調度
}

//開始任務函數
void Start_Task(void *pvParameters)
{
  taskENTER_CRITICAL();   //進入臨界區
  //創建軟件定時器
  Time0Handler = xTimerCreate( ( char *                ) "Time0",     //定時器的名稱
                 ( TickType_t              ) 1000,       //定時周期
                 ( UBaseType_t             ) pdTRUE,       //是否重裝載 (pdTRUE or pdFAIL)
                 ( void *                  ) 0,         //ID號
                 ( TimerCallbackFunction_t ) Time0Callback ); //回調函數
  //開啟定時器
  xTimerStart( Time0Handler, portMAX_DELAY );
  //創建 Low 任務
  xTaskCreate(
    (TaskFunction_t )Low_Task, 
    (const char* )"Low_Task", 
    (uint16_t )Low_STK_SIZE, 
    (void* )NULL,
    (UBaseType_t )Low_TASK_PRIO,
    (TaskHandle_t* )&LowTask_Handler
  );
  //創建 Med 任務
  xTaskCreate(
    (TaskFunction_t )Med_Task, 
    (const char* )"Med_Task", 
    (uint16_t )Med_STK_SIZE, 
    (void* )NULL,
    (UBaseType_t )Med_TASK_PRIO,
    (TaskHandle_t* )&MedTask_Handler
  );
  vTaskDelete(StartTask_Handler); //刪除開始任務
  taskEXIT_CRITICAL();   //退出臨界區
}


void Low_Task(void *pvParameters)
{
  while(1)
  {
    
    vTaskDelay(1000);
  }
}

void Med_Task(void *pvParameters)
{
  //BaseType_t xReturn = NULL;
  while(1)
  {
    printf("正在運行n");
    vTaskDelay(1000);
  }
}

void Time0Callback( TimerHandle_t pxTimer )
{
  static int count = 0;
  printf("%dn",++count);
}


實驗現象

pYYBAGPl99KAejgvAABWsxgh4dQ062.png


--END--

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 軟件定時器
    +關注

    關注

    0

    文章

    18

    瀏覽量

    6749
  • FreeRTOS
    +關注

    關注

    12

    文章

    484

    瀏覽量

    62178
收藏 人收藏

    評論

    相關推薦

    使用cola_os軟件定時器實現時間片輪詢框架

    如果使用RTOS顯得太浪費,這時候可以嘗試使用使用cola_os這類基于軟件定時器實現的時間片輪詢框架。
    的頭像 發表于 09-22 09:03 ?1425次閱讀
    使用cola_os<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>實現時間片輪詢框架

    基于STM32的軟件定時器設計

    軟件定時器是用程序模擬出來的定時器,可以由一個硬件定時器模擬出成千上萬個軟件定時器,這樣程序在需
    發表于 07-03 17:06 ?1063次閱讀
    基于STM32的<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>設計

    Linux和RTOS的時鐘和定時器怎么使用

    Linux發燒友1.RTOS篇1.1RT-Thread簡介1.2時鐘管理1.2.1時鐘節拍1.3獲取系統節拍1.4定時器分類1.5定時器源碼分析1.6定時器相關函數1.61動態創建一個
    發表于 01-17 08:13

    定時器初值計算軟件工具

    定時器初值計算軟件工具
    發表于 03-20 10:23 ?239次下載

    555定時器電路設計軟件

    555定時器電路設計軟件
    發表于 03-02 11:29 ?287次下載

    555定時器應用設計軟件免費下載

    本文檔的主要內容詳細介紹的是555定時器應用設計軟件免費下載,本軟件是一款555定時器設計軟件,使用非常方便。
    發表于 12-17 08:00 ?51次下載
    555<b class='flag-5'>定時器</b>應用設計<b class='flag-5'>軟件</b>免費下載

    ESP8266的管腳的控制和軟件定時器的使用

    先說定時器,ESP8266內部的定時器分為軟件定時器和硬件定時器。手冊中指出硬件定時器其實就跟單
    的頭像 發表于 07-29 14:57 ?9513次閱讀
    ESP8266的管腳的控制和<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>的使用

    設計軟件定時器

    軟件定時器搬來使用2、自己設計軟件定時器這里我只介紹第二種方法,我們知道,硬件定時器是通過對系統時鐘周期進行計數實現的,那么
    發表于 11-05 18:35 ?2次下載
    設計<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>

    基于硬件定時器軟件定時器

    概括硬件定時器很精確,軟件定時器無論如何都有延遲,主要用在不需要精確定時的地方,而且軟件定時比較
    發表于 11-25 09:51 ?8次下載
    基于硬件<b class='flag-5'>定時器</b>的<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>

    詳細剖析Linux和RTOS(RT-Thread)的時鐘和定時器的使用

    Linux發燒友1.RTOS篇1.1RT-Thread簡介1.2時鐘管理1.2.1時鐘節拍1.3獲取系統節拍1.4定時器分類1.5定時器源碼分析1.6定時器相關函數1.61動態創建一個
    發表于 01-17 09:31 ?4次下載
    詳細剖析Linux和<b class='flag-5'>RTOS</b>(RT-Thread)的時鐘和<b class='flag-5'>定時器</b>的使用

    軟件定時器簡介及程序配置

      軟件定時器就是允許函數設置一定的等待時間,然后執行。定時器執行的函數被稱為定時器的回調函數。定時器從啟動到執行回調函數之間的時間稱為
    的頭像 發表于 12-06 16:10 ?3912次閱讀
    <b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>簡介及程序配置

    freeRTOS軟件定時器的使用

    freeRTOS中加入了軟件定時器這個功能組件,是一個可選的、不屬于freeRTOS內核的功能,由定時器服務(其實就是一個定時器任務)來提供。
    的頭像 發表于 02-10 13:55 ?2169次閱讀

    什么是軟件定時器軟件定時器的實現原理

    軟件定時器是用程序模擬出來的定時器,可以由一個硬件定時器模擬出成千上萬個軟件定時器,這樣程序在需
    的頭像 發表于 05-23 17:05 ?2791次閱讀

    關于軟件定時器的一些討論

    這就是簡單的軟件定時器,是的,這就是特別簡潔版本的軟件定時器。當然它是有缺點的,比如systick_ms每1ms加1,所以軟件
    的頭像 發表于 10-13 16:14 ?569次閱讀
    關于<b class='flag-5'>軟件</b><b class='flag-5'>定時器</b>的一些討論

    如何實現一個軟件定時器

    在Linux,uC/OS,FreeRTOS等操作系統中,都帶有軟件定時器,原理大同小異。典型的實現方法是:通過一個硬件定時器產生固定的時鐘節拍,每次硬件定時器中斷到,就對一個全局的時間
    的頭像 發表于 04-29 11:00 ?653次閱讀
    主站蜘蛛池模板: 国产精品资源网站在线观看| 成人午夜大片免费看爽爽爽| 欧美色国| 女人爽到喷水的视频大全在线观看| 国产免费卡1卡2卡| 中文字幕在线观看你懂的| 伊人操| 午夜视频啪啪| 五月六月伊人狠狠丁香网| 亚洲成电影| 日本a级片在线观看| 巨乳色最新网址| 成人一二| 1024你懂的国产在线播放| 一级做a爰片久久毛片美女图片 | 骚淫| 亚洲天天综合| 一女多夫嗯啊高h| 日本精品三级| 天天干天天操天天舔| japanese色系tube日本护士| 一区二区三区四区电影| 国内自拍露脸普通话对白在线| 国产午夜免费一区二区三区| 69中国xxxxxxxx18| 亚洲成人黄色| 美国一级做a一级爱视频| 中文在线天堂网www| 在线成人免费观看国产精品| 最新sss华人| 色倩网站| 国产激烈床戏无遮挡在线观看 | 久久99精品福利久久久| 在线观看一二三区| 女人张腿让男桶免费视频网站| 日本wwwxx| 日本一区二区不卡视频| 久久亚洲精品玖玖玖玖| 天天爽夜夜爽人人爽免费| 激情丁香网| 午夜爱爱免费视频|