简单软件定时器程序

2019-07-21 05:34发布


typedef unsigned char  BYTE;    // unsigned 8bit
typedef unsigned short  WORD;    // unsigned 16bit
typedef unsigned long  DWORD;    // unsigned 32bit
typedef struct
{
DWORD usrTmrStatus :2;
DWORD usrTmrBuffer :30;
} USER_TIMER;
typedef enum
{
   TIMER_OK   = 0,  // Timer running
   TIMER_TMO  = 1,  // Timer timeout
   TIMER_STOP = 2,  // Timer stop
} gmt_TimerStatus;
enum
{
// ---------------------------------------------------------------
START_10ms,                                 // ***** 10ms timer start ,此值必须为零,否则需修改UserTimer_Start函数
UART2_RX_10ms_TMR,
END_10ms,                                   // ***** 10ms timer end
// ---------------------------------------------------------------
START_100ms=END_10ms,                       // ***** 100ms timer start
END_100ms,                                  // ***** 100ms timer end
// ---------------------------------------------------------------
START_1s=END_100ms,                         // ***** 1s timer start
Commom_1s_TMR,
AM2320_1s_TMR,
CLOCK_1s_TMR,
END_1s,                                     // ***** 1s timer end
// ---------------------------------------------------------------
MAX_TMR=END_1s                              // Total Max number of timer (5)
};

#define SYSTEM_TICK 1000U         //单位:Hz
#define SYSTEMTICK_PERIOD_MS  1
static DWORD U32_TimerSaveNow = 0;
static ST_USER_TIMER gWa_TmrBuf[MAX_TMR] = {{TIMER_STOP, 0},};
volatile DWORD LocalTime = 0; /* this variable is used to create a time reference incremented by 10ms */
volatile DWORD LocalTimeSecond = 0;
volatile DWORD LocalTimeSecondCnt = 0;
DWORD timingdelay;
DWORD KeyEventTimeSecond = 0;
void SystemTick_Init(void)
{
    /* setup systick timer for 1000Hz interrupts */
    if (SysTick_Config(SystemCoreClock/SYSTEM_TICK)){
        /* capture error */
        while (1){
            //printf("Systick config error !");
        }
    }
    /* configure the systick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
DWORD UserSystemTime_Get(void)
{
return LocalTime;
}
WORD UserTimeout_Calcu(WORD Start, WORD End)
{
WORD W_Timeout;
if(End >= Start)
{
  W_Timeout = End - Start;
}
else
{
  W_Timeout = 0xFFFF - Start + End;
}
return W_Timeout;
}
void Delay_1ms(WORD nCount)
{
  /* Capture the current local time */
  timingdelay = LocalTime + nCount;
  /* wait until the desired delay finish */
  while(timingdelay > LocalTime)
  {
  }
}
void UserTime_Update(void)
{   
LocalTime += SYSTEMTICK_PERIOD_MS;
LocalTimeSecondCnt ++;
if(LocalTimeSecondCnt == SYSTEM_TICK)
{
  LocalTimeSecond ++;
  LocalTimeSecondCnt = 0;
}   
}
void UserTimer_Init(void)
{
BYTE B_temp;
for(B_temp = 0; B_temp < MAX_TMR; B_temp++)
{
  gWa_TmrBuf[B_temp].usrTmrStatus = TIMER_STOP;
  gWa_TmrBuf[B_temp].usrTmrBuffer = 0;
}
}
/*!
    功能:       开始定时
    Timer:   定时器名称
      value:  0 < xxx_TMR < MAX_TMR
    imes:    定时时基倍数  
      value:  0 < value <= 65535
    eturn:   无
      value:  无
*/
void UserTimer_Start(BYTE nTimer, WORD times)
{
DWORD dw_Value;
/* Convert time value to micro second */
    if(nTimer < END_10ms)
    {
  dw_Value = times * 10UL;
    }
    else if((nTimer >= START_100ms) && (nTimer < END_100ms))
    {
  dw_Value = times * 100UL;
    }
else if((nTimer >= START_1s) && (nTimer < END_1s))
{
  dw_Value = times * 1000UL;
}
else
{
  dw_Value = times;
}
gWa_TmrBuf[nTimer].usrTmrStatus = TIMER_OK;
gWa_TmrBuf[nTimer].usrTmrBuffer = dw_Value;
}
gmt_TimerStatus UserTimer_Check(BYTE nTimer)
{
return((gmt_TimerStatus)(gWa_TmrBuf[nTimer].usrTmrStatus));
}

void UserTimer_Stop(BYTE nTimer)
{
gWa_TmrBuf[nTimer].usrTmrStatus = TIMER_STOP;
gWa_TmrBuf[nTimer].usrTmrBuffer = 0;
}
DWORD UserTimer_Read(BYTE nTimer)
{
return(gWa_TmrBuf[nTimer].usrTmrBuffer);
}

void UserTimer_Handler(void)
{
BYTE nTimer;
  DWORD timeEscaped;
DWORD currentTime = UserSystemTime_Get();
    if(currentTime == U32_TimerSaveNow)
    {
  return;  
    }
else if(currentTime > U32_TimerSaveNow)
{
  timeEscaped = currentTime - U32_TimerSaveNow;
}
else // system timer overflow
{
  timeEscaped = currentTime + (~U32_TimerSaveNow);
}
   
U32_TimerSaveNow = currentTime;
for(nTimer = 0; nTimer < MAX_TMR; nTimer++)
{
  if(gWa_TmrBuf[nTimer].usrTmrStatus == TIMER_OK)
  {
   if(gWa_TmrBuf[nTimer].usrTmrBuffer > timeEscaped)
            {         
    gWa_TmrBuf[nTimer].usrTmrBuffer -= timeEscaped;
            }
   else
            {         
    gWa_TmrBuf[nTimer].usrTmrBuffer = 0;
                gWa_TmrBuf[nTimer].usrTmrStatus = TIMER_TMO;
            }
  }
}
}
void SysTick_Handler(void)
{
    UserTime_Update();
}
说明:UserTime_Update()可以放在滴答中断服务函数中,也可以放在普通定时器中断服务函数中。
UserTimer_Handler()函数放在主函数的while循环中。
使用范例:
void UserClock_Display(void)
{
    if(TIMER_OK != UserTimer_Check(CLOCK_1s_TMR))
{
  UserTimer_Start(CLOCK_1s_TMR, 1);
        clockSec++;
        if(clockSec == 60)
        {
            clockSec = 0;
            clockMin++;
            UserClock_SpecialSave();
            if(clockMin == 60)
            {
                clockMin = 0;
                clockHour++;
                //UserClock_Save();
                if(clockHour == 24)
                {
                    clockHour = 0;
                    clockDay++;
                    LCD_ShowNumbers(16, 112, clockDay, 4, WHITE);
                }
                LCD_ShowNumbers(64, 112, clockHour,2, WHITE);
            }
            LCD_ShowNumbers(96, 112, clockMin,2, WHITE);
        }
        LCD_ShowNumbers(128, 112, clockSec,2, WHITE);
    }
}
int main(void)
{  
    SCB->VTOR = FLASH_BASE | 0x2000; /* Vector Table Relocation in Internal FLASH. */
__enable_irq();
   
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  //向量组设置
    SystemTick_Init();
   
    UserTimer_Init();
   
    while(1)
    {
        UserTimer_Handler();
        UserClock_Display();
    }
}



0条回答

一周热门 更多>