Type:
Compiler/Assembler:
soft_timers.h:
//======================================================================== #ifndef SOFT_TIMERS_H #define SOFT_TIMERS_H #include "soft_timers.h" #include "main_def_func.h" //======================================================================== //======================================================================== // Выбор: с прерыванием или с опросом флага OCFx. #define __ST_NO_INTERRUPT__ // __ST_NO_INTERRUPT__ // __ST_INTERRUPT__ // Состав структуры: bool status, u08 sys_tick_prev, u16 cnt, u16 period. // Итого 6 байтов на один программный таймер. Если убрать элемент period, // то теперь будет 4 байта на таймер. #define __ST_NO_PERIOD__ // __ST_PERIOD__ // __ST_NO_PERIOD__ //======================================================================== //======================================================================== #define ST_TCNT TCNT0 #define ST_TIMSK TIMSK0 #define ST_OCIE OCIE0A #define ST_OCR OCR0A #define ST_TCCR TCCR0B #define ST_CS0 CS00 #define ST_CS1 CS01 #define ST_CS2 CS02 #define ST_TIFR TIFR0 #define ST_OCF OCF0A //======================================================================== //======================================================================== #define SYS_TICK (F_CPU/64/1000) //======================================================================== //======================================================================== typedef struct soft_timer { bool status; u08 sys_tick_prev; u16 cnt; // Counter. #ifdef __ST_PERIOD__ u16 period; // Period. #endif } soft_timer; //======================================================================== //======================================================================== void init_soft_timers (void); #define handle_soft_timer(a) _handle_soft_timer(&a) bool _handle_soft_timer(soft_timer *ptr_timer); #ifdef __ST_PERIOD__ #define set_soft_timer(a,b,c) _set_soft_timer (&a, b, c) void _set_soft_timer (soft_timer *ptr_timer, u16 time, u16 period); #endif #ifdef __ST_NO_PERIOD__ #define set_soft_timer(a,b) _set_soft_timer (&a, b) void _set_soft_timer (soft_timer *ptr_timer, u16 time); #endif #define reset_soft_timer(a) _reset_soft_timer (&a) void _reset_soft_timer (soft_timer *ptr_timer); void proc_sys_tick (void); //======================================================================== #endif
soft_timer.c:
//======================================================================== // Реализация программных таймеров. // Примечание. Важно!!!!!!!!!!!!!!! // При смене состояния конечного автомата нужно сбросить // все таймеры, которые используются в этом состоянии. Иначе может быть // следующая ситуация: если таймер уже использовался в // текущем состоянии и флаг EN установлен, то по окончании времени // выполнится соответствующий код. //--------------------- Пример использования ----------------------------- // set_soft_timer (ST_LED_2_BLINK, 50, 50); // Установка таймера. // if (handle_soft_timer (ST_LED_2_BLINK)) // Проверка таймера. //======================================================================== //======================================================================== #include "soft_timers.h" //======================================================================== //======================================================================== static u08 sys_tick; //======================================================================== //======================================================================== #ifdef __ST_INTERRUPT__ #pragma vector = TIMER2_COMP_vect __interrupt void SysTimerComp (void) { ST_OCR += SYS_TICK; sys_tick++; } #endif //======================================================================== //======================================================================== void init_soft_timers (void) { sys_tick = 0; ST_TCNT = 0; ST_OCR = SYS_TICK; ST_TCCR = ((1<<ST_CS1) | (1<<ST_CS0)); #ifdef __ST_INTERRUPT__ set_bit (ST_TIMSK, ST_OCIE); #endif } //------------------------------------------------------------------------ #ifdef __ST_PERIOD__ void _set_soft_timer (soft_timer *ptr_timer, u16 time, u16 period) #else void _set_soft_timer (soft_timer *ptr_timer, u16 time) #endif { ptr_timer -> status = true; if (time == 0) ptr_timer -> sys_tick_prev = ~sys_tick; else ptr_timer -> sys_tick_prev = sys_tick; ptr_timer -> cnt = time; #ifdef __ST_PERIOD__ ptr_timer -> period = period; #endif } //------------------------------------------------------------------------ bool _handle_soft_timer (soft_timer *ptr_timer) { if (ptr_timer -> status) { if (ptr_timer -> sys_tick_prev != sys_tick) { ptr_timer -> sys_tick_prev = sys_tick; if (ptr_timer -> cnt == 0) { #ifdef __ST_PERIOD__ if (ptr_timer -> period != 0) ptr_timer -> cnt = ptr_timer -> period; #endif return true; } else { ptr_timer -> cnt--; if (ptr_timer -> cnt == 0) { #ifdef __ST_PERIOD__ if (ptr_timer -> period == 0) ptr_timer -> status = false; else ptr_timer -> cnt = ptr_timer -> period; #else ptr_timer -> status = false; #endif return true; } } } } return false; } //------------------------------------------------------------------------ void _reset_soft_timer (soft_timer *ptr_timer) { ptr_timer -> status = false; ptr_timer -> sys_tick_prev = 0; ptr_timer -> cnt = 0; #ifdef __ST_PERIOD__ ptr_timer -> period = 0; #endif } //------------------------------------------------------------------------ #ifdef __ST_NO_INTERRUPT__ void proc_sys_tick (void) { static u08 _proc_sys_tick; switch (_proc_sys_tick) { case 0: init_soft_timers (); _proc_sys_tick = 1; break; case 1: if (ST_TIFR & (1<<ST_OCF)) { ST_TIFR = (1<<ST_OCF); ST_OCR += SYS_TICK; sys_tick++; } break; } } #endif //========================================================================
//************************************************************************ // Example of the using //************************************************************************ static u08 _proc_led_2; soft_timer ST_LED_2_BLINK; // Immediate execution case 0: set_soft_timer (ST_LED_2_BLINK, 0, 50); _proc_led_2 = 1; break; case 1: if (handle_soft_timer (ST_LED_2_BLINK)) { } break; // Execution after the specified time case 0: set_soft_timer (ST_LED_2_BLINK, 50, 50); _proc_led_2 = 1; break; case 1: if (handle_soft_timer (ST_LED_2_BLINK)) { } break; // Other case 0: set_soft_timer (ST_LED_2_BLINK, 1000, 50); _proc_led_2 = 1; break; case 1: if (handle_soft_timer (ST_LED_2_BLINK)) { } break;
//======================================================================== #include "proc_device.h" //======================================================================== //======================================================================== void proc_device (void) { static u08 _proc_device; switch (_proc_device) { case 0: // Блок инициализации. #ifdef __ST_PERIOD__ set_proc_led_1_run (); set_proc_led_2_run (); set_proc_led_3_run (); set_proc_led_4_run (); set_proc_led_5_run (); set_proc_led_6_run (); set_proc_led_7_run (); set_proc_led_8_run (); #endif _proc_device = 1; break; case 1: #ifdef __ST_PERIOD__ proc_led_1 (); proc_led_2 (); proc_led_3 (); proc_led_4 (); proc_led_5 (); proc_led_6 (); proc_led_7 (); proc_led_8 (); #else led_1_blink (); led_2_blink (); led_3_blink (); led_4_blink (); led_5_blink (); led_6_blink (); led_7_blink (); led_8_blink (); #endif break; } } //======================================================================== //======================================================================== static u08 _proc_led_1; static soft_timer ST_PROC_LED_1; static soft_timer ST_PROC_LED_2; static soft_timer ST_PROC_LED_3; static soft_timer ST_PROC_LED_4; static soft_timer ST_PROC_LED_5; static soft_timer ST_PROC_LED_6; static soft_timer ST_PROC_LED_7; static soft_timer ST_PROC_LED_8; void set_proc_led_1_run (void) { led_1_off (); _proc_led_1 = 1; } void set_proc_led_1_off (void) { led_1_off (); _proc_led_1 = 0; } void proc_led_1 (void) { switch (_proc_led_1) { case 0: break; // Idle. case 1: #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_1, 0, 10); #else set_soft_timer (ST_PROC_LED_1, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! #endif _proc_led_1 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_1)) { if (!(LED_1_DDR & (1<<LED_1))) led_1_on (); else led_1_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_2; void set_proc_led_2_run (void) { led_2_off (); _proc_led_2 = 1; } void set_proc_led_2_off (void) { led_2_off (); _proc_led_2 = 0; } void proc_led_2 (void) { switch (_proc_led_2) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_2, 0, 10); set_soft_timer (ST_PROC_LED_2, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_2 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_2)) { if (!(LED_2_DDR & (1<<LED_2))) led_2_on (); else led_2_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_3; void set_proc_led_3_run (void) { led_3_off (); _proc_led_3 = 1; } void set_proc_led_3_off (void) { led_3_off (); _proc_led_3 = 0; } void proc_led_3 (void) { switch (_proc_led_3) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_3, 0, 10); set_soft_timer (ST_PROC_LED_3, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_3 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_3)) { if (!(LED_3_DDR & (1<<LED_3))) led_3_on (); else led_3_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_4; void set_proc_led_4_run (void) { led_4_off (); _proc_led_4 = 1; } void set_proc_led_4_off (void) { led_4_off (); _proc_led_4 = 0; } void proc_led_4 (void) { switch (_proc_led_4) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_4, 0, 10); set_soft_timer (ST_PROC_LED_4, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_4 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_4)) { if (!(LED_4_DDR & (1<<LED_4))) led_4_on (); else led_4_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_5; void set_proc_led_5_run (void) { led_5_off (); _proc_led_5 = 1; } void set_proc_led_5_off (void) { led_5_off (); _proc_led_5 = 0; } void proc_led_5 (void) { switch (_proc_led_5) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_5, 0, 10); set_soft_timer (ST_PROC_LED_5, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_5 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_5)) { if (!(LED_5_DDR & (1<<LED_5))) led_5_on (); else led_5_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_6; void set_proc_led_6_run (void) { led_6_off (); _proc_led_6 = 1; } void set_proc_led_6_off (void) { led_6_off (); _proc_led_6 = 0; } void proc_led_6 (void) { switch (_proc_led_6) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_6, 0, 10); set_soft_timer (ST_PROC_LED_6, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_6 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_6)) { if (!(LED_6_DDR & (1<<LED_6))) led_6_on (); else led_6_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_7; void set_proc_led_7_run (void) { led_7_off (); _proc_led_7 = 1; } void set_proc_led_7_off (void) { led_7_off (); _proc_led_7 = 0; } void proc_led_7 (void) { switch (_proc_led_7) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_7, 0, 10); set_soft_timer (ST_PROC_LED_7, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_7 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_7)) { if (!(LED_7_DDR & (1<<LED_7))) led_7_on (); else led_7_off (); } break; } } //======================================================================== //======================================================================== static u08 _proc_led_8; void set_proc_led_8_run (void) { led_8_off (); _proc_led_8 = 1; } void set_proc_led_8_off (void) { led_8_off (); _proc_led_8 = 0; } void proc_led_8 (void) { switch (_proc_led_8) { case 0: break; // Idle. case 1: // set_soft_timer (ST_PROC_LED_8, 0, 10); set_soft_timer (ST_PROC_LED_8, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!! _proc_led_8 = 2; break; case 2: if (handle_soft_timer (ST_PROC_LED_8)) { if (!(LED_8_DDR & (1<<LED_8))) led_8_on (); else led_8_off (); } break; } } //======================================================================== //======================================================================== void led_1_blink (void) { if (!(LED_1_DDR & (1<<LED_1))) { set_bit (LED_1_DDR, LED_1); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_1, 0, 10); #else set_soft_timer (ST_PROC_LED_1, 0); #endif } if (handle_soft_timer (ST_PROC_LED_1)) { if (!(LED_1_PORT & (1<<LED_1))) led_1_on (); else led_1_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_1, 10); #endif } } //------------------------------------------------------------------------ void led_2_blink (void) { if (!(LED_2_DDR & (1<<LED_2))) { set_bit (LED_2_DDR, LED_2); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_2, 0, 10); #else set_soft_timer (ST_PROC_LED_2, 0); #endif } if (handle_soft_timer (ST_PROC_LED_2)) { if (!(LED_2_PORT & (1<<LED_2))) led_2_on (); else led_2_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_2, 10); #endif } } //------------------------------------------------------------------------ void led_3_blink (void) { if (!(LED_3_DDR & (1<<LED_3))) { set_bit (LED_3_DDR, LED_3); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_3, 0, 10); #else set_soft_timer (ST_PROC_LED_3, 0); #endif } if (handle_soft_timer (ST_PROC_LED_3)) { if (!(LED_3_PORT & (1<<LED_3))) led_3_on (); else led_3_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_3, 10); #endif } } //------------------------------------------------------------------------ void led_4_blink (void) { if (!(LED_4_DDR & (1<<LED_4))) { set_bit (LED_4_DDR, LED_4); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_4, 0, 10); #else set_soft_timer (ST_PROC_LED_4, 0); #endif } if (handle_soft_timer (ST_PROC_LED_4)) { if (!(LED_4_PORT & (1<<LED_4))) led_4_on (); else led_4_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_4, 10); #endif } } //------------------------------------------------------------------------ void led_5_blink (void) { if (!(LED_5_DDR & (1<<LED_5))) { set_bit (LED_5_DDR, LED_5); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_5, 0, 10); #else set_soft_timer (ST_PROC_LED_5, 0); #endif } if (handle_soft_timer (ST_PROC_LED_5)) { if (!(LED_5_PORT & (1<<LED_5))) led_5_on (); else led_5_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_5, 10); #endif } } //------------------------------------------------------------------------ void led_6_blink (void) { if (!(LED_6_DDR & (1<<LED_6))) { set_bit (LED_6_DDR, LED_6); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_6, 0, 10); #else set_soft_timer (ST_PROC_LED_6, 0); #endif } if (handle_soft_timer (ST_PROC_LED_6)) { if (!(LED_6_PORT & (1<<LED_6))) led_6_on (); else led_6_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_6, 10); #endif } } //------------------------------------------------------------------------ void led_7_blink (void) { if (!(LED_7_DDR & (1<<LED_7))) { set_bit (LED_7_DDR, LED_7); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_7, 0, 10); #else set_soft_timer (ST_PROC_LED_7, 0); #endif } if (handle_soft_timer (ST_PROC_LED_7)) { if (!(LED_7_PORT & (1<<LED_7))) led_7_on (); else led_7_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_7, 10); #endif } } //------------------------------------------------------------------------ void led_8_blink (void) { if (!(LED_8_DDR & (1<<LED_8))) { set_bit (LED_8_DDR, LED_8); #ifdef __ST_PERIOD__ set_soft_timer (ST_PROC_LED_8, 0, 10); #else set_soft_timer (ST_PROC_LED_8, 0); #endif } if (handle_soft_timer (ST_PROC_LED_8)) { if (!(LED_8_PORT & (1<<LED_8))) led_8_on (); else led_8_off (); #ifdef __ST_NO_PERIOD__ set_soft_timer (ST_PROC_LED_8, 10); #endif } } //========================================================================