| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 | /******************************* (C) LiteMesh ********************************** * @module  systick * @file    systick.c * @version 1.0.0 * @date    29.05.2015 * $brief   Functions to work with System Timer.  *          Module is based on code teplofizik, 2013 ******************************************************************************* * @history     Version  Author         Comment * 29.05.2015   1.0.0    Telenkov D.A.  First release. ******************************************************************************* */   #include "stm32f4xx.h"#include "systick.h"#include <stdbool.h>#include <string.h>extern void Time_Update(void);typedef struct{  TTimerHandler Handler;  uint16_t      Countdown;  uint16_t      Reload;  bool          Run;    // Запущено  bool          Fired;  // Сработало    } THandlers;volatile uint32_t  TimingDelay;volatile uint8_t   StopDelayFlag = 0;static THandlers Handlers[TIMER_HANDLERS];static uint32_t  TimerFrequency;static int       TimerCount;/**  * @brief  Обработчик прерывания системного таймера  * @retval нет  */void SysTick_Handler(void){  int i;   Time_Update();    TimingDelay_Decrement();      for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Run)    {      if(--Handlers[i].Countdown == 0)      {        Handlers[i].Countdown = Handlers[i].Reload;	/* Запишем, что сработало */	Handlers[i].Fired = true;      }    }  }}/**  * @brief  Запуск таймера с заданной частотой  * @retval нет  */void timer_Init(uint32_t Frequency){  if(!Frequency) return;  /* Сбросим параметры */  TimerCount = 0;  TimerFrequency = Frequency;  memset(&Handlers[0], 0, sizeof(Handlers));  /* Настройка частоты */  SysTick_Config(clock_GetSYS() / Frequency);}/**  * @brief  Добавить функцию в список вызова.   *         Handler будет вызываться с заданной частотой  * @retval нет  */void timer_AddFunction(uint16_t Frequency, TTimerHandler Handler){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    /* Найдем пустой слот */    if(!Handlers[i].Handler)    {      /* Обработчик, частота опроса */      Handlers[i].Run       =  true;      Handlers[i].Fired     =  false;      Handlers[i].Handler   =  Handler;      Handlers[i].Reload    =  Frequency;      Handlers[i].Countdown =  Handlers[i].Reload;      TimerCount++;      return;    }  }}/**  * @brief  Изменить частоту таймера  * @retval нет  */void timer_ChangeFrequency(TTimerHandler Handler, uint16_t Frequency){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Handler == Handler)    {      Handlers[i].Reload = Frequency;      Handlers[i].Countdown = Handlers[i].Reload;      break;    }  }}/**  * @brief  Возобночить работу задачи  * @retval нет  */void timer_Resume(TTimerHandler Handler){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Handler == Handler)    {      Handlers[i].Run = true;      break;    }  }}/**  * @brief  Перезапуск задачи  * @retval нет  */void timer_Restart(TTimerHandler Handler){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Handler == Handler)    {      Handlers[i].Run = true;      Handlers[i].Countdown = Handlers[i].Reload;      break;    }  }}/**  * @brief  Перезапуск задачи. Задача будет вызвана сразу.  * @retval нет  */void timer_RestartAtOnce(TTimerHandler Handler){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Handler == Handler)    {      Handlers[i].Run = true;      Handlers[i].Countdown = 1;      break;    }  }}/**  * @brief  Остановить задачу  * @retval нет  */void timer_Stop(TTimerHandler Handler){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    if(Handlers[i].Handler == Handler)    {      Handlers[i].Run = false;      Handlers[i].Fired =  false;      break;    }  }}/**  * @brief  Функция перебора и вызова актуальных задач.   *         Должна вызываться в главном цикле  * @retval нет  */void timer_Main(void){  int i;  for(i = 0; i < TIMER_HANDLERS; i++)  {    /* Если сработало - вызовем */    if(Handlers[i].Fired)    {      Handlers[i].Fired = false;      Handlers[i].Handler();    }  }}/**  * @brief    * @retval Частота тактирования ядра  */uint32_t clock_GetSYS(void){  return SystemCoreClock;}/**  * @brief  Задержка в миллисекундах  * @retval нет  */void Delay_ms(uint32_t nTime){  TimingDelay = nTime;  while(TimingDelay);}/**  * @brief  Вспомогательная функция для реализации Delay_ms  * @retval нет  */void TimingDelay_Decrement(void) {  if (TimingDelay)    TimingDelay--;}//******************************** (C) POTEK ***********************************
 |