From 2a260911f5abc4e03cb41474a49e01a571395155 Mon Sep 17 00:00:00 2001 From: Oxore Date: Fri, 3 Mar 2023 00:02:25 +0300 Subject: Remove precious comments, change encoding to utf-8 --- Libraries/Button/button_handler.c | 153 +++---- Libraries/Button/button_handler.h | 5 +- Libraries/Button/button_task.c | 87 +--- Libraries/Head_Task/head_task.c | 288 +++++--------- Libraries/LED_Driver/led_driver_config.c | 61 ++- Libraries/LED_Driver/led_driver_config.h | 16 +- Libraries/LED_Driver/led_driver_process.h | 2 +- Libraries/LED_Driver/led_driver_task.c | 6 +- Libraries/LTimers/ltimers.c | 135 +++---- Libraries/LTimers/ltimers.h | 12 +- Libraries/LTimers/ltimers_config.c | 50 +-- Libraries/LTimers/ltimers_config.h | 4 +- Libraries/LightSensor/light_sensor_task.c | 159 ++++---- Libraries/LightSensor/light_sensor_task.h | 8 +- Libraries/NixieDriver/nixie_driver_config.c | 140 +++---- Libraries/NixieDriver/nixie_driver_config.h | 67 +--- Libraries/NixieDriver/nixie_driver_process.c | 441 +++++---------------- Libraries/NixieDriver/nixie_driver_process.h | 79 ++-- Libraries/NixieDriver/nixie_driver_task.c | 56 +-- Libraries/NixieDriver/nixie_driver_task.h | 2 +- Libraries/Time/time.c | 16 - Libraries/Time/time.h | 2 +- Project/src/main.c | 100 +++-- .../platform/stm32f0-gcc/freertos/FreeRTOSConfig.h | 92 ++--- Project/src/stm32f0xx_it.c | 58 ++- 25 files changed, 683 insertions(+), 1356 deletions(-) diff --git a/Libraries/Button/button_handler.c b/Libraries/Button/button_handler.c index 8df1e6b..7c3ea91 100644 --- a/Libraries/Button/button_handler.c +++ b/Libraries/Button/button_handler.c @@ -3,48 +3,39 @@ #include "nixie_driver_process.h" -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" -// -// , -// +// Обработчик нажатий представляет собой конечный автомат для обработки +// результата работы сенсорной библиотеки, обработки комбинаций и времени +// нажатий и выдачи результата во внешнюю программу -#define TIME_BUTTON_LONG_PRESS 1000 // 3 +#define TIME_BUTTON_LONG_PRESS 1000 // 3 секунды для долгого жмака -// +// Состояние конечного автомата обработчика нажатий typedef enum { - BUTTON_STATE_START = 0, BUTTON_STATE_ONE_BUT_IS_PRESSING_NOW, BUTTON_STATE_TWO_BUTS_AND_TIMER, BUTTON_STATE_TWO_BUTS_AFTER_TIMER - } Button_FSMStates_t; -// ( , .) +// Комбнации нажатостей кнопушек (нажата одна, зажаты две и тд.) enum { - BUT_COMB_NONE = 0, BUT_COMB_BUT1 = 1, BUT_COMB_BUT2 = 2, BUT_COMB_BOTH = 3 - } ; - -//extern const uint8_t tube_digits [MAX_DIGITS]; -//static uint8_t test_button_bufer[MAX_TUBES] = {TUBE_DIGIT_0}; -//static uint8_t cnt [6] = {0}; - QueueHandle_t queue_but_comb; -// - , -// , +// - сделать в обработчике вывода индикации ламп на нижнем уровне, +// чтобы ты отправлял цифру на индикатор, а он сам уже преобразовывал // ---------------------------------------------------------------------------- @@ -58,155 +49,132 @@ void ButtonInit ( void ) // ---------------------------------------------------------------------------- -// - +// Конечный автомат-обработчик нажатий кнопушек // Note: -// , .. -// ( , , -// ) +// Антидребезг в данном автомате не нужен, т.к. обработчик сенсорной библиотеки +// уже все сделал (а вот не сделал, возможно от микродребезга есть защита, +// а вот от крупного дребезга нет защиты) // ---------------------------------------------------------------------------- void Button_ProcessFSM ( void ) { static Button_FSMStates_t state_fsm_button = BUTTON_STATE_START; static uint8_t still_pushed = 0; - + static uint8_t prev_button_comb; static uint8_t curr_button_comb; static ButtonCombName_t msg_but_comb_name; - + switch ( state_fsm_button ) { // ------------------------------------------------------------------------- case BUTTON_STATE_START: - + curr_button_comb = Button_GetCurrButtons(); - + if ( curr_button_comb != BUT_COMB_NONE ) { prev_button_comb = curr_button_comb; state_fsm_button = BUTTON_STATE_ONE_BUT_IS_PRESSING_NOW; still_pushed = 0; } - + break; // ------------------------------------------------------------------------- case BUTTON_STATE_ONE_BUT_IS_PRESSING_NOW: - // - 1 - // - 2 - // - 3 , () - + // - 1 отпустили + // - 2 нажали вторую + // - 3 вторая кнопка, но такого не должно быть(ошибка) + curr_button_comb = Button_GetCurrButtons(); - - // , + + // Сначала проверим, вдруг кнопушку отпустили if ( (curr_button_comb == BUT_COMB_NONE) && (still_pushed == 0) ) { - // - .: " " - + // - сообщ.: "Одиночный обратный жмак" + switch ( prev_button_comb ) { case BUT_COMB_BUT1: - -// test_button_bufer[0] == TUBE_DIGIT_9 ? cnt[0] = 0 : cnt[0]++; -// test_button_bufer[0] = tube_digits [cnt[0]]; -// NixieDriver_SendValue ( &test_button_bufer[0] ); xQueueReceive ( queue_but_comb, &msg_but_comb_name, 0 ); msg_but_comb_name = BUTTON_SINGLE_FORWARD; xQueueSend ( queue_but_comb, &msg_but_comb_name, 0 ); - break; case BUT_COMB_BUT2: -// test_button_bufer[1] == TUBE_DIGIT_9 ? cnt[1] = 0 : cnt[1]++; -// test_button_bufer[1] = tube_digits [cnt[1]]; -// NixieDriver_SendValue ( &test_button_bufer[0] ); xQueueReceive ( queue_but_comb, &msg_but_comb_name, 0 ); msg_but_comb_name = BUTTON_SINGLE_BACKWARD; xQueueSend ( queue_but_comb, &msg_but_comb_name, 0 ); - break; - default: break; } - + state_fsm_button = BUTTON_STATE_START; - + return; } - + if ( (curr_button_comb == BUT_COMB_NONE) && (still_pushed == 1) ) { state_fsm_button = BUTTON_STATE_START; return; } - + switch ( prev_button_comb ) { case BUT_COMB_BUT1: - + if ( curr_button_comb == BUT_COMB_BOTH ) { - // - .: " " -// test_button_bufer[2] == TUBE_DIGIT_9 ? cnt[2] = 0 : cnt[2]++; -// test_button_bufer[2] = tube_digits [cnt[2]]; -// -// NixieDriver_SendValue ( &test_button_bufer[0] ); + // - тогда сообщ.: "Зажатый прямой жмак вперед" xQueueReceive ( queue_but_comb, &msg_but_comb_name, 0 ); //msg_but_comb_name = BUTTON_HOLD_FORWARD; msg_but_comb_name = BUTTON_HOLD_BACKWARD; xQueueSend ( queue_but_comb, &msg_but_comb_name, 0 ); - StartLTimer ( LTIMER_BUTTON_LONG_PRESS ); state_fsm_button = BUTTON_STATE_TWO_BUTS_AND_TIMER; still_pushed = 1; } - + break; - + case BUT_COMB_BUT2: - + if ( curr_button_comb == BUT_COMB_BOTH ) { - // - .: " " -// test_button_bufer[3] == TUBE_DIGIT_9 ? cnt[3] = 0 : cnt[3]++; -// test_button_bufer[3] = tube_digits [cnt[3]]; -// -// NixieDriver_SendValue ( &test_button_bufer[0] ); + // - тогда сообщ.: "Зажатый прямой жмак назад" xQueueReceive ( queue_but_comb, &msg_but_comb_name, 0 ); //msg_but_comb_name = BUTTON_HOLD_BACKWARD; msg_but_comb_name = BUTTON_HOLD_FORWARD; xQueueSend ( queue_but_comb, &msg_but_comb_name, 0 ); - + StartLTimer ( LTIMER_BUTTON_LONG_PRESS ); state_fsm_button = BUTTON_STATE_TWO_BUTS_AND_TIMER; still_pushed = 1; } - + break; - + default: state_fsm_button = BUTTON_STATE_START; break; } - + break; - + // ------------------------------------------------------------------------- case BUTTON_STATE_TWO_BUTS_AND_TIMER: - + curr_button_comb = Button_GetCurrButtons(); - + if ( curr_button_comb == BUT_COMB_BOTH ) { - if ( GetLTimer (LTIMER_BUTTON_LONG_PRESS) == TIME_BUTTON_LONG_PRESS ) + if ( GetLTimer (LTIMER_BUTTON_LONG_PRESS) == TIME_BUTTON_LONG_PRESS ) { - // - .: " " -// test_button_bufer[4] == TUBE_DIGIT_9 ? cnt[4] = 0 : cnt[4]++; -// test_button_bufer[4] = tube_digits [cnt[4]]; -// -// NixieDriver_SendValue ( &test_button_bufer[0] ); + // - сообщ.: "Две долго" xQueueReceive ( queue_but_comb, &msg_but_comb_name, 0 ); msg_but_comb_name = BUTTON_LONG; xQueueSend ( queue_but_comb, &msg_but_comb_name, 0 ); - + state_fsm_button = BUTTON_STATE_TWO_BUTS_AFTER_TIMER; } } @@ -215,14 +183,14 @@ void Button_ProcessFSM ( void ) prev_button_comb = curr_button_comb; state_fsm_button = BUTTON_STATE_ONE_BUT_IS_PRESSING_NOW; } - + break; - - // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- case BUTTON_STATE_TWO_BUTS_AFTER_TIMER: - + curr_button_comb = Button_GetCurrButtons(); - + if ( curr_button_comb == BUT_COMB_NONE ) { state_fsm_button = BUTTON_STATE_START; @@ -232,23 +200,10 @@ void Button_ProcessFSM ( void ) prev_button_comb = curr_button_comb; state_fsm_button = BUTTON_STATE_ONE_BUT_IS_PRESSING_NOW; } - + break; - + default: - break; + break; } } - - - - - - - - - - - - - diff --git a/Libraries/Button/button_handler.h b/Libraries/Button/button_handler.h index 76b21d1..86118fa 100644 --- a/Libraries/Button/button_handler.h +++ b/Libraries/Button/button_handler.h @@ -3,19 +3,16 @@ #include - typedef enum { - BUTTON_SINGLE_FORWARD, BUTTON_SINGLE_BACKWARD, BUTTON_HOLD_FORWARD, BUTTON_HOLD_BACKWARD, BUTTON_LONG - } ButtonCombName_t; void ButtonInit ( void ); uint8_t Button_GetCurrButtons ( void ); void Button_ProcessFSM ( void ); -#endif //BUTTON_HANDLER_INCLUDED \ No newline at end of file +#endif //BUTTON_HANDLER_INCLUDED diff --git a/Libraries/Button/button_task.c b/Libraries/Button/button_task.c index 4a06a3b..3446fb4 100644 --- a/Libraries/Button/button_task.c +++ b/Libraries/Button/button_task.c @@ -5,19 +5,11 @@ #include "button_handler.h" #include "ltimers.h" -// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" - -// -//enum { -// TKEY_NUM_1 = 0, -// TKEY_NUM_2 -//}; - #define TKEY_NUM_1 0 #define TKEY_NUM_2 1 @@ -35,9 +27,7 @@ uint8_t DS[TSLPRM_TOTAL_TKEYS + TSLPRM_TOTAL_LNRTS]; // To store the States (one per object) int16_t DD[TSLPRM_TOTAL_TKEYS + (TSLPRM_TOTAL_LNRTS * 3)]; // To store the Deltas (one per channel) -//static uint8_t touch_tube_bufer [MAX_TUBES] = {0}; - -// , +// , // static volatile uint8_t tkey_buttons_bits = 0; @@ -63,9 +53,9 @@ void ProcessFSM_ButtonTask ( void ) { /* Execute STMTouch Driver state machine */ if (TSL_user_Action () == TSL_STATUS_OK) - { + { ProcessSensors (); // Execute sensors related tasks - + // () //Button_ProcessFSM (); } @@ -82,25 +72,19 @@ void ProcessFSM_ButtonTask ( void ) static void ProcessSensors ( void ) { uint32_t idx; - //uint32_t idxch; uint32_t idx_ds = 0; uint32_t idx_dd = 0; - //uint32_t touched = 0; -#if USE_LCD > 0 +#if USE_LCD > 0 static uint32_t started = 0; #endif -#if TSLPRM_TOTAL_TKEYS > 0 +#if TSLPRM_TOTAL_TKEYS > 0 // Read all TKeys for (idx = 0; idx < TSLPRM_TOTAL_TKEYS; idx++) { // STMStudio debug - DS[idx_ds++] = MyTKeys[idx].p_Data->StateId; + DS[idx_ds++] = MyTKeys[idx].p_Data->StateId; DD[idx_dd++] = MyTKeys[idx].p_ChD->Delta; -// if (TEST_TKEY(idx)) -// { -// touched = 1; -// } } #endif @@ -115,39 +99,15 @@ static void ProcessSensors ( void ) { DD[idx_dd++] = MyLinRots[idx].p_ChD[idxch].Delta; } -// if (TEST_LINROT(idx)) -// { -// touched = 1; -// } } #endif - + // ( , // GROUP5 - ) TkeyDebounce(); // - - // if (TEST_TKEY(TKEY_NUM_2)) - // { - // tkey_buttons_bits |= 1 << TKEY_NUM_1; - // } - // else - // { - // tkey_buttons_bits &= ~(1 << TKEY_NUM_1); - // } - - // if (TEST_TKEY(TKEY_NUM_1)) - // { - // tkey_buttons_bits |= 1 << TKEY_NUM_2; - - // } - // else - // { - // tkey_buttons_bits &= ~(1 << TKEY_NUM_2); - // } - } /** @@ -182,7 +142,6 @@ void TSL_CallBack_TimerTick(void) void MyTKeys_ErrorStateProcess(void) { /* Add here your own processing when a sensor is in Error state */ - //TSL_linrot_SetStateOff(); TSL_tkey_SetStateOff (); while(1) { @@ -193,7 +152,6 @@ void MyLinRots_ErrorStateProcess(void) { /* Add here your own processing when a sensor is in Error state */ TSL_linrot_SetStateOff(); - //TSL_tkey_SetStateOff (); while(1) { } @@ -203,7 +161,7 @@ void MyLinRots_ErrorStateProcess(void) // ---------------------------------------------------------------------------- // - // ---------------------------------------------------------------------------- -void TkeyDebounce ( void ) +void TkeyDebounce ( void ) { static uint8_t tkey_db_state = 1; static uint8_t tkey_code = 0; @@ -211,16 +169,16 @@ void TkeyDebounce ( void ) if (TEST_TKEY(TKEY_NUM_2)) { - tkey_code |= 1 << TKEY_NUM_1; + tkey_code |= 1 << TKEY_NUM_1; } else { tkey_code &= ~(1 << TKEY_NUM_1); } - + if (TEST_TKEY(TKEY_NUM_1)) { - tkey_code |= 1 << TKEY_NUM_2; + tkey_code |= 1 << TKEY_NUM_2; } else { @@ -240,20 +198,20 @@ void TkeyDebounce ( void ) case 2: if( GetLTimer( LTIMER_SENSOR_BUT_DEBOUNCE ) >= TIME_SENSOR_BUT_DEBOUNCE ) - { + { tkey_db_state = 3; - } - break; + } + break; case 3: - if( _tkey_code == tkey_code ) - { - tkey_db_state = 1; + if( _tkey_code == tkey_code ) + { + tkey_db_state = 1; tkey_buttons_bits = _tkey_code; - - } - else { tkey_db_state = 1; } - break; + + } + else { tkey_db_state = 1; } + break; default: break; @@ -268,5 +226,4 @@ void TkeyDebounce ( void ) void Button_Task ( void *pvParameters ) { while(1)ProcessFSM_ButtonTask (); - //vTaskDelete(NULL); -} \ No newline at end of file +} diff --git a/Libraries/Head_Task/head_task.c b/Libraries/Head_Task/head_task.c index 7df305d..3a1729a 100644 --- a/Libraries/Head_Task/head_task.c +++ b/Libraries/Head_Task/head_task.c @@ -1,6 +1,6 @@ #include "head_task.h" -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" @@ -14,38 +14,33 @@ #include "stm32f0xx_rtc.h" -// +// Номера функций меню typedef enum { - MENU_FUNC_SIMPLE_TIME_VIEW = 0, MENU_ADJ_TIME, - MAX_MENU_FUNCTIONS - } MenuFunctionsNums_t; -// AdjTime +// Состояния режима меню AdjTime typedef enum { - STATE_MENU_ADJ_TIME_START, STATE_MENU_ADJ_TIME_TIMER_OUT - } MenuAdjTimeStates_t; static MenuFunctionsNums_t curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW; -// +// Прототипы функций меню static void MenuFunc_SimpleTimeView ( void ); static void MenuFunc_AdjTime ( void ); -// - +// Массив указателей на функции-меню typedef void ( *MenuFunctions_t ) ( void ); static const MenuFunctions_t MenuFunctions[MAX_MENU_FUNCTIONS] = { - + MenuFunc_SimpleTimeView, MenuFunc_AdjTime - + }; void GetCurrTime ( DataToIndicate_t* indic_data ); @@ -58,158 +53,137 @@ void ChangeValue ( uint8_t increase, uint8_t *data, uint8_t limit ); DataToIndicate_t indic_data; extern QueueHandle_t queue_data_to_indic; // indicate_modes_task.c extern QueueHandle_t queue_but_comb; // button_handler.c -extern QueueHandle_t queue_data_to_blink_mode; +extern QueueHandle_t queue_data_to_blink_mode; QueueHandle_t queue_switch_indic_mode; static MenuAdjTimeStates_t state_adj_time = STATE_MENU_ADJ_TIME_START; // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void HeadTaskInit ( void ) { queue_switch_indic_mode = xQueueCreate ( 1, sizeof (IndicModesNums_t) ); configASSERT( queue_switch_indic_mode ); - + curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW; } // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void MenuFunc_SimpleTimeView ( void ) { - //static uint8_t prev_time = 0; - //static uint8_t curr_time = 1; - RTC_TimeTypeDef RTC_TimeStructure; - + /* Get the current Time */ RTC_GetTime(RTC_Format_BCD, &RTC_TimeStructure); - -// curr_time = RTC_TimeStructure.RTC_Seconds; -// -// if ( prev_time != curr_time ) -// { -// prev_time = curr_time; -// - GetCurrTime ( &indic_data ); - xQueueSend ( queue_data_to_indic, &indic_data, 0 ); -// } + GetCurrTime ( &indic_data ); + xQueueSend ( queue_data_to_indic, &indic_data, 0 ); } // ---------------------------------------------------------------------------- -// -- +// Ф-я-меню настройки времени // ---------------------------------------------------------------------------- void MenuFunc_AdjTime ( void ) { static const uint32_t TIME_ADJ_OUT = 5000; //ms - + static IndicModesMsgBlink_t blink_data_struct; static ButtonCombName_t but_comb_name; IndicModesNums_t indic_mode_num; static uint8_t position_mask; - - //uint8_t prev_time = 1; - //uint8_t curr_time = 0; - - // - , - // , - // - + + // - при этом нужно постоянно слать текущее время на вывод, то есть + // при настройке времени оно тикает как в обычном режиме, только + // пользователь может его изменять при этом + switch ( state_adj_time ) { case STATE_MENU_ADJ_TIME_START: - + indic_mode_num = INDIC_MODE_BLINK; - // + // Отправляем сообщение на переключение режима индикации xQueueSend ( queue_switch_indic_mode, &indic_mode_num, 0 ); - - // - // , , + + // Отправляем сообщение с данными для индикации + // Но сначала, сотрем, вдруг прошлое собщение не было прочитано xQueueReceive ( queue_data_to_blink_mode, &blink_data_struct, 0 ); - + GetCurrTime ( &blink_data_struct.data ); blink_data_struct.mask_byte = 32; position_mask = blink_data_struct.mask_byte; - + xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 ); - + state_adj_time = STATE_MENU_ADJ_TIME_TIMER_OUT; StartLTimer ( LTIMER_MENU_ADJ_TIME_OUT ); - + break; - + case STATE_MENU_ADJ_TIME_TIMER_OUT: - + if ( GetLTimer (LTIMER_MENU_ADJ_TIME_OUT) >= TIME_ADJ_OUT ) { state_adj_time = STATE_MENU_ADJ_TIME_START; - // + // Выходим из этого меню режима curr_menu_func = MENU_FUNC_SIMPLE_TIME_VIEW; indic_mode_num = INDIC_MODE_STANDART; xQueueSend ( queue_switch_indic_mode, &indic_mode_num, 0 ); - // . - // , .. - // , , - // 1 . - // - + // При выходе из настройки времени нужно послать сообщ. на обновление + // данных в простой режим, т.к. фаза в моргающем режиме могла быть + // отрицательной, а данные обновляются только раз в секунду, и поэтому + // лампа может быть потухшей 1 секунду. + // - тут лучше сделать завершение фазы моргания GetCurrTime ( &indic_data ); - xQueueSend ( queue_data_to_indic, &indic_data, 0 ); + xQueueSend ( queue_data_to_indic, &indic_data, 0 ); } else { - // , , - // + // Если жмакнули кнопушку, то сбрасываем таймер, затем смотрим + // какую кнопушку жмакнули if ( pdPASS == xQueueReceive ( queue_but_comb, &but_comb_name, 0 ) ) { StartLTimer ( LTIMER_MENU_ADJ_TIME_OUT ); - - // , + + // Тут в зависимости от того, какую кнопушку жмакнули switch ( but_comb_name ) { case BUTTON_SINGLE_FORWARD: - case BUTTON_SINGLE_BACKWARD: - // - AdjTimeChangeTube (but_comb_name, &position_mask); + case BUTTON_SINGLE_BACKWARD: + // Меняем позицию времени + AdjTimeChangeTube (but_comb_name, &position_mask); GetCurrTime ( &blink_data_struct.data ); blink_data_struct.mask_byte = position_mask; xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 ); break; - + case BUTTON_HOLD_FORWARD: - case BUTTON_HOLD_BACKWARD: - // + case BUTTON_HOLD_BACKWARD: + // Меняем значение времени GetCurrTime ( &blink_data_struct.data ); AdjTimeChangeValue ( but_comb_name, &blink_data_struct, position_mask ); SetTime ( &blink_data_struct.data ); xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 ); break; - + default: break; } } else { - // - , , + // - тут, если время изменилось, то отправляем его на вывод GetCurrTime ( &blink_data_struct.data ); - - //curr_time = blink_data_struct.data.indic_6; - - //if ( curr_time != prev_time ) - //{ - // prev_time = curr_time; - xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 ); - //} + xQueueSend ( queue_data_to_blink_mode, &blink_data_struct, 0 ); } } - + break; - + default: break; } @@ -220,31 +194,30 @@ void MenuFunc_AdjTime ( void ) // // ---------------------------------------------------------------------------- void ProcessFSM_Head ( void ) -{ - - // - : - // - - // ( gps , wifi .) - - // 1. - - // ( 3 ) - - // - - +{ + + // - тут можно совершать внешние переключения функций меню: + // - ловить сообщения от внешних источников для перехода в нужный пункт + // меню (сообщения от gps модуля, wifi и тд.) + + // 1. Ловим сообщение из модуля-обработчика нажатий кнопушек с командой + // на переход в меню настройки (две кнопки зажать на 3 сек) + + // - перед отправкой сообщения в режим индикации сначала стираем сообщение + static ButtonCombName_t but_comb_name; - + if ( pdPASS == xQueuePeek ( queue_but_comb, &but_comb_name, 0 ) ) { if ( but_comb_name == BUTTON_LONG ) { - // - , - // - + // - при изменении состояния меню или режима, нужно также сбрасывать + // внутреннее состояние текущего режима + xQueueReceive ( queue_but_comb, &but_comb_name, 0 ); curr_menu_func = MENU_ADJ_TIME; } } - MenuFunctions [curr_menu_func](); taskYIELD(); } @@ -254,67 +227,48 @@ void ProcessFSM_Head ( void ) // // ---------------------------------------------------------------------------- -//static DataToIndicate_t const_time; - - void GetCurrTime ( DataToIndicate_t *indic_data ) { RTC_TimeTypeDef RTC_TimeStructure; - + /* Get the current Time */ RTC_GetTime ( RTC_Format_BCD, &RTC_TimeStructure ); - - indic_data->indic_1 = RTC_TimeStructure.RTC_Hours>>4; - indic_data->indic_2 = RTC_TimeStructure.RTC_Hours&0x0F; - - indic_data->indic_3 = RTC_TimeStructure.RTC_Minutes>>4; - indic_data->indic_4 = RTC_TimeStructure.RTC_Minutes&0x0F; - - indic_data->indic_5 = RTC_TimeStructure.RTC_Seconds>>4; - indic_data->indic_6 = RTC_TimeStructure.RTC_Seconds&0x0F; - -// indic_data->indic_1 = const_time.indic_1; -// indic_data->indic_2 = const_time.indic_2; -// -// indic_data->indic_3 = const_time.indic_3; -// indic_data->indic_4 = const_time.indic_4; -// -// indic_data->indic_5 = const_time.indic_5; -// indic_data->indic_6 = const_time.indic_6; + + indic_data->indic_1 = RTC_TimeStructure.RTC_Hours>>4; + indic_data->indic_2 = RTC_TimeStructure.RTC_Hours&0x0F; + + indic_data->indic_3 = RTC_TimeStructure.RTC_Minutes>>4; + indic_data->indic_4 = RTC_TimeStructure.RTC_Minutes&0x0F; + + indic_data->indic_5 = RTC_TimeStructure.RTC_Seconds>>4; + indic_data->indic_6 = RTC_TimeStructure.RTC_Seconds&0x0F; } // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void SetTime ( DataToIndicate_t* indic_data ) { -// const_time.indic_1 = indic_data->indic_1; -// const_time.indic_2 = indic_data->indic_2; -// const_time.indic_3 = indic_data->indic_3; -// const_time.indic_4 = indic_data->indic_4; -// const_time.indic_5 = indic_data->indic_5; -// const_time.indic_6 = indic_data->indic_6; - RTC_TimeTypeDef RTC_TimeStructure; - + RTC_TimeStructure.RTC_Hours = indic_data->indic_1 << 4; RTC_TimeStructure.RTC_Hours |= indic_data->indic_2 & 0x0F; - + RTC_TimeStructure.RTC_Minutes = indic_data->indic_3 << 4; RTC_TimeStructure.RTC_Minutes |= indic_data->indic_4 & 0x0F; - + RTC_TimeStructure.RTC_Seconds = indic_data->indic_5 << 4; RTC_TimeStructure.RTC_Seconds |= indic_data->indic_6 & 0x0F; - + RTC_SetTime ( RTC_Format_BCD, &RTC_TimeStructure ); } // ---------------------------------------------------------------------------- -// - -// - MenuFunc_AdjTime -// ( - , ) +// Ф-я изменения текущего положения моргающей лампы при настройке времени +// Ф-я вызывается из MenuFunc_AdjTime +// Номер лампы соотносится с номером лампы ( левый бит - нулевой, и лампа тоже ) // ---------------------------------------------------------------------------- void AdjTimeChangeTube ( ButtonCombName_t but_comb_name, uint8_t *position_mask ) { @@ -332,36 +286,36 @@ void AdjTimeChangeTube ( ButtonCombName_t but_comb_name, uint8_t *position_mask // ---------------------------------------------------------------------------- -// - -// "" +// Ф-я изменения значения цифры в текущем положении +// То есть тут настраиваем время "поцифирно" // ---------------------------------------------------------------------------- void AdjTimeChangeValue ( ButtonCombName_t but_comb_name, IndicModesMsgBlink_t *data_struct, uint8_t position_mask ) { uint8_t increase; - + if ( but_comb_name == BUTTON_HOLD_FORWARD ) { increase = 1; } else { increase = 0; } switch ( position_mask & 0x3F ) { - case 0x01: // + case 0x01: // Секунды единицы ChangeValue ( increase, &data_struct->data.indic_6, 9 ); break; - - case 0x04: // + + case 0x04: // Минуты единицы ChangeValue ( increase, &data_struct->data.indic_4, 9 ); break; - - case 0x02: // + + case 0x02: // Секунды десятки ChangeValue ( increase, &data_struct->data.indic_5, 5 ); break; - - case 0x08: // + + case 0x08: // Минуты десятки ChangeValue ( increase, &data_struct->data.indic_3, 5 ); break; - - case 0x10: // - if ( data_struct->data.indic_1 == 2 ) + + case 0x10: // Часы единицы + if ( data_struct->data.indic_1 == 2 ) { ChangeValue ( increase, &data_struct->data.indic_2, 3 ); } @@ -370,8 +324,8 @@ void AdjTimeChangeValue ( ButtonCombName_t but_comb_name, IndicModesMsgBlink_t * ChangeValue ( increase, &data_struct->data.indic_2, 9 ); } break; - - case 0x20: // + + case 0x20: // Часы десятки if ( data_struct->data.indic_2 <= 3 ) { ChangeValue ( increase, &data_struct->data.indic_1, 2 ); @@ -388,14 +342,11 @@ void AdjTimeChangeValue ( ButtonCombName_t but_comb_name, IndicModesMsgBlink_t * // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- -//static uint8_t temp; void ChangeValue ( uint8_t increase, uint8_t *data, uint8_t limit ) { - //temp = *data; - + if ( increase ) - //if ( temp ) { if ( *data < limit ) { *data += 1; } else { *data = 0; } @@ -409,40 +360,9 @@ void ChangeValue ( uint8_t increase, uint8_t *data, uint8_t limit ) // ---------------------------------------------------------------------------- -// , NixieClockSimply +// Задача ОС, реализующая головную задачу программы NixieClockSimply // ---------------------------------------------------------------------------- void Head_Task ( void *pvParameters ) { while(1)ProcessFSM_Head (); - //vTaskDelete(NULL); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/LED_Driver/led_driver_config.c b/Libraries/LED_Driver/led_driver_config.c index d71792d..3b2b081 100644 --- a/Libraries/LED_Driver/led_driver_config.c +++ b/Libraries/LED_Driver/led_driver_config.c @@ -4,7 +4,7 @@ static void LED_TIMConfig ( void ); static void LED_SPIConfig ( void ); // ---------------------------------------------------------------------------- -// , RGB +// Подготовка железа, прерываний и тд для работы с RGB светодиодиками // ---------------------------------------------------------------------------- void LED_Driver_Config ( void ) { @@ -20,49 +20,48 @@ static void LED_TIMConfig ( void ) { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - + /* LED_TIMx clock enable */ LED_RCC_APBxPeriphClockCmd ( LED_TIM_RCC, ENABLE ); - + /* Enable the LED_TIMx gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = LED_TIM_IRQx; - NVIC_InitStructure.NVIC_IRQChannelPriority = 2; // , NixieDriver + NVIC_InitStructure.NVIC_IRQChannelPriority = 2; // Установим приоритет ниже, чем у модуля NixieDriver NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init ( &NVIC_InitStructure ); /* ----------------------------------------------------------------------- In this example TIM7 counter clock (TIM7CLK) is set to APB1 clock (PCLK1), since APB1 prescaler is set to 1 and TIM7 prescaler is set to 0. - - In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), - since APB1 prescaler is set to 1. + + In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), + since APB1 prescaler is set to 1. TIM7CLK = PCLK1 = HCLK = SystemCoreClock - + With Prescaler set to 479 and Period to 24999, the TIM7 counter is updated each 250 ms (i.e. and interrupt is generated each 250 ms) TIM7 counter clock = TIM7CLK /((Prescaler + 1)*(Period + 1)) = 48 MHz / ((25000)*(480)) - = 4 Hz + = 4 Hz ==> TIM7 counter period = 250 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration - based on this variable will be incorrect. - ----------------------------------------------------------------------- */ - + based on this variable will be incorrect. + ----------------------------------------------------------------------- */ + /* Time base configuration */ - TIM_TimeBaseStructure.TIM_Period = 1000; // //24999 + TIM_TimeBaseStructure.TIM_Period = 1000; // Это миксросекунды //24999 TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; //479; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit ( LED_TIMx, &TIM_TimeBaseStructure ); - + /* LED_TIMx Interrupts enable */ TIM_ITConfig ( LED_TIMx, TIM_IT_Update, ENABLE ); - + /* LED_TIMx enable counter */ TIM_Cmd ( LED_TIMx, ENABLE ); } @@ -76,20 +75,19 @@ static void LED_SPIConfig ( void ) GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; - + /* Enable the SPI periph */ LED_SPIx_RCC_APBxPeriphClockCmd ( LED_SPIx_CLK, ENABLE ); - + /* Enable SCK, MOSI, MISO and NSS GPIO clocks */ - RCC_AHBPeriphClockCmd ( LED_SPIx_SCK_GPIO_CLK | - LED_SPIx_MOSI_GPIO_CLK | + RCC_AHBPeriphClockCmd ( LED_SPIx_SCK_GPIO_CLK | + LED_SPIx_MOSI_GPIO_CLK | LED_SPIx_ST_GPIO_CLK, ENABLE ); - + GPIO_PinAFConfig ( LED_SPIx_SCK_GPIO_PORT, LED_SPIx_SCK_SOURCE, LED_SPIx_SCK_AF ); GPIO_PinAFConfig ( LED_SPIx_MOSI_GPIO_PORT, LED_SPIx_MOSI_SOURCE, LED_SPIx_MOSI_AF ); - //GPIO_PinAFConfig ( LED_SPIx_ST_GPIO_PORT, LED_SPIx_ST_SOURCE, LED_SPIx_ST_AF ); - + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; @@ -102,21 +100,18 @@ static void LED_SPIConfig ( void ) /* SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = LED_SPIx_MOSI_PIN; GPIO_Init ( LED_SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure ); - + /* GPIO ST pin configuration */ GPIO_InitStructure.GPIO_Pin = LED_SPIx_ST_PIN; - //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; GPIO_Init ( LED_SPIx_ST_GPIO_PORT, &GPIO_InitStructure ); - + /* SPI configuration -------------------------------------------------------*/ SPI_I2S_DeInit ( LED_SPIx ); - //SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI_Direction_2Lines_FullDuplex - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; @@ -126,18 +121,18 @@ static void LED_SPIConfig ( void ) SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init ( LED_SPIx, &SPI_InitStructure ); - + /* Enable the SPI peripheral */ SPI_Cmd ( LED_SPIx, ENABLE ); - + /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = LED_SPIx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init ( &NVIC_InitStructure ); - + /* Enable the Rx buffer not empty interrupt */ SPI_I2S_ITConfig ( LED_SPIx, SPI_I2S_IT_RXNE, ENABLE ); - + LED_ST_PIN_RESET; } diff --git a/Libraries/LED_Driver/led_driver_config.h b/Libraries/LED_Driver/led_driver_config.h index 7e377ac..39927ec 100644 --- a/Libraries/LED_Driver/led_driver_config.h +++ b/Libraries/LED_Driver/led_driver_config.h @@ -9,27 +9,27 @@ #define LED_SPIx_IRQn SPI2_IRQn #define LED_SPIx_IRQHandler SPI2_IRQHandler -#define LED_SPIx_SCK_PIN GPIO_Pin_10 -#define LED_SPIx_SCK_GPIO_PORT GPIOB +#define LED_SPIx_SCK_PIN GPIO_Pin_10 +#define LED_SPIx_SCK_GPIO_PORT GPIOB #define LED_SPIx_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB #define LED_SPIx_SCK_SOURCE GPIO_PinSource10 #define LED_SPIx_SCK_AF GPIO_AF_5 -#define LED_SPIx_MOSI_PIN GPIO_Pin_15 -#define LED_SPIx_MOSI_GPIO_PORT GPIOB +#define LED_SPIx_MOSI_PIN GPIO_Pin_15 +#define LED_SPIx_MOSI_GPIO_PORT GPIOB #define LED_SPIx_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB #define LED_SPIx_MOSI_SOURCE GPIO_PinSource15 #define LED_SPIx_MOSI_AF GPIO_AF_0 -#define LED_SPIx_ST_PIN GPIO_Pin_9 -#define LED_SPIx_ST_GPIO_PORT GPIOB +#define LED_SPIx_ST_PIN GPIO_Pin_9 +#define LED_SPIx_ST_GPIO_PORT GPIOB #define LED_SPIx_ST_GPIO_CLK RCC_AHBPeriph_GPIOA #define LED_SPIx_ST_SOURCE GPIO_PinSource9 #define LED_SPIx_ST_AF GPIO_AF_5 #define LED_SPIx_RCC_APBxPeriphClockCmd RCC_APB1PeriphClockCmd -// LedRgbDriver ------------------------------------- // +// Определения для таймера LedRgbDriver ------------------------------------- // #define LED_TIMx TIM3 #define LED_TIM_IRQHandler TIM3_IRQHandler #define LED_TIM_RCC RCC_APB1Periph_TIM3 @@ -41,4 +41,4 @@ void LED_Driver_Config ( void ); -#endif //LED_DRIVER_CONFIG_INCLUDED \ No newline at end of file +#endif //LED_DRIVER_CONFIG_INCLUDED diff --git a/Libraries/LED_Driver/led_driver_process.h b/Libraries/LED_Driver/led_driver_process.h index 346a0c4..fa02241 100644 --- a/Libraries/LED_Driver/led_driver_process.h +++ b/Libraries/LED_Driver/led_driver_process.h @@ -3,4 +3,4 @@ void LEDDriverProcessFromISR ( void ); -#endif //LED_DRIVER_PROCESS_INCLUDED \ No newline at end of file +#endif //LED_DRIVER_PROCESS_INCLUDED diff --git a/Libraries/LED_Driver/led_driver_task.c b/Libraries/LED_Driver/led_driver_task.c index 33b677a..d38deb4 100644 --- a/Libraries/LED_Driver/led_driver_task.c +++ b/Libraries/LED_Driver/led_driver_task.c @@ -1,7 +1,6 @@ #include "led_driver_task.h" #include "led_driver_config.h" -// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" @@ -19,10 +18,9 @@ void ProcessFSM_LED_RGB ( void ) } // ---------------------------------------------------------------------------- -// , RGB +// Задача ОС, реализующая задачу обработки светодиодиков RGB // ---------------------------------------------------------------------------- void LED_Driver_Task ( void *pvParameters ) { while(1)ProcessFSM_LED_RGB (); - //vTaskDelete(NULL); -} \ No newline at end of file +} diff --git a/Libraries/LTimers/ltimers.c b/Libraries/LTimers/ltimers.c index ccdbf00..61c9e6f 100644 --- a/Libraries/LTimers/ltimers.c +++ b/Libraries/LTimers/ltimers.c @@ -1,68 +1,68 @@ -/* ltimers.c - - - . , - 1 ( - , 1 - , , . ). - - ProcessLTimers(), - . ltimers.h. - , , -, . - 1 ( - ) - - ProcessLTimers();. #include "ltimers.h" - , - . , - : - -StartLTimer ( LTIMER_LED_BLINK ); // -GetLTimer ( LTIMER_LED_BLINK ); // - - : +/* Описание модуля ltimers.c + + Этот модуль используется для создания неограниченного количества +программных таймеров для программы. Модуль использует аппаратный таймер, +который генерирует прерывание каждую 1мс (можно использовать любой другой +промежуток времени, просто 1 мс это очень удобно и хватает для многих +программных пауз, задержек, таймеров и тд. в программе). +В прерывании вызывается ф-я ProcessLTimers(), которая инкрементирует значения +всех таймеров. Таймеры создаются в файле ltimers.h. + Модуль универсален, прост и может использоваться на любой платформе, +компиляторе, любом МК. + Для подключения модуля настройте аппаратный таймер на прерывание в 1мс (или +любой другой нужный промежуток времени) и добавьте в обработчик прерывания +этого таймера ф-ю ProcessLTimers();. Затем добавьте #include "ltimers.h" в тот +файл программы, где будут использоваться ф-ии модуля. Собственно, +в всего нужны две функции для работы с таймерами: + +StartLTimer ( LTIMER_LED_BLINK ); // запустить таймер +GetLTimer ( LTIMER_LED_BLINK ); // получить текущее значение таймера + + Пример использования: ... -// ltimers.h , -// , MAX_LTIMERS +// Предварительно ltimers.h создаем перечисление, в котором создаем имена для +// программных таймеров, а также в конце перечисления всегда MAX_LTIMERS #include "ltimers.h" ... int main () { ... - // 1 - InitLTimersHardWare(); + // Настройка аппаратного таймера на прерывание раз в 1 мс + InitLTimersHardWare(); - // ( ) + // Стартовая инициализация (просто обнуление) всех программных таймеров InitLTimers (); - - // + + // Запускаем таймер StartLTimer ( LTIMER_LED_BLINK ); - // + // Основной цикл программы while (1) { - // + // Проверяем значение таймера if ( GetLTimer ( LTIMER_LED_BLINK ) >= 500 ) { LED_ON; - } + } } -} +} -*** +***Примечание - 1. -. , -8- , , , . + 1. Необходимо учитывать разрядность МК и атомарность при проверке значений +таймера. То есть, если произойдет прерывание в момент проверки полубайтов на +8-ми разрядном МК, то, возможно, могут быть трудноуловимые глюки. - 2. , - ProcessLTimers() - . - StartLTimer - , , - . -, . . -. + 2. Обратите внимание, что в ф-ии ProcessLTimers() значения таймеров +инкрементируются постоянно и не перестают изменяться. Ф-я StartLTimer только +сбрасывает значение таймера в ноль, а потом программа уже ловит тот момент, +когда это значение превысило или сравнялось с нужным. И когда мы провели +сравнение, то таймер все равно продолжает маслать. Но это не важно. Пусть себе +маслает. - 3. uint32_t - . + 3. Псевдоним для типа uint32_t можно заменить на необходимый в зависимости +от среды разработки и компилятора. */ #include "ltimers.h" @@ -72,9 +72,9 @@ uint32_t LTimers [MAX_LTIMERS] = { 0 }; // ---------------------------------------------------------------------------- -// . -// - -// . +// Стартовая инициализация всех программных таймеров программиста. +// Ф-я вызывается при старте МК и просто устанавливает все значения таймеров +// в ноль. // ---------------------------------------------------------------------------- void InitLTimers (void) { @@ -83,10 +83,10 @@ void InitLTimers (void) // ---------------------------------------------------------------------------- -// - -// -// - LTimerNum_t ltimers.h -// - , 1 +// Ф-я получения значения программного счетчика +// Используется программистом для проверки значения запущенного таймера +// Ф-я принимает имя таймера из перечисления LTimerNum_t в файле ltimers.h +// Ф-я возвращает значение таймера, которое увеличивается каждую 1мс // ---------------------------------------------------------------------------- uint32_t GetLTimer ( LTimersNames_t LTimer ) { @@ -95,9 +95,9 @@ uint32_t GetLTimer ( LTimersNames_t LTimer ) // ---------------------------------------------------------------------------- -// - -// 1 -// - LTimerNum_t ltimers.h +// Ф-я запуска программного таймера для использования программистом для +// любых программных задержек разрешением 1мс +// Ф-я принимает имя таймера из перечисления LTimerNum_t в файле ltimers.h // ---------------------------------------------------------------------------- void StartLTimer ( LTimersNames_t LTimer ) { @@ -106,12 +106,12 @@ void StartLTimer ( LTimersNames_t LTimer ) // ---------------------------------------------------------------------------- -// -, . -// ltimers.h -// LTimerNum_t. MAX_LTIMERS -// . -// - TIM6_IRQHandler 1 . -// 1 +// Ф-я, инкрементирующая значения программных таймеров. Количество этих +// программных таймеров нее ограничено и задается программистом в ltimers.h +// в тайпдефе LTimerNum_t. Просто дописываем в перечислении перед MAX_LTIMERS +// имя нового таймера. +// Вызывается эта ф-я в обреботчике TIM6_IRQHandler каждую 1 мс. +// 1 мс это удобный квант времени для разных программных задержек // ---------------------------------------------------------------------------- void ProcessLTimers (void) { @@ -120,18 +120,3 @@ void ProcessLTimers (void) LTimers[i]++; } } - - - - - - - - - - - - - - - diff --git a/Libraries/LTimers/ltimers.h b/Libraries/LTimers/ltimers.h index a0370b2..4514841 100644 --- a/Libraries/LTimers/ltimers.h +++ b/Libraries/LTimers/ltimers.h @@ -3,10 +3,10 @@ #include -// LTIMER_ ---------------------------------------- // +// Имена таймеров LTIMER_ ---------------------------------------- // typedef enum { - - LTIMER_SENSE_PAD = 0, + + LTIMER_SENSE_PAD = 0, LTIMER_PRGBAR_SPEED, LTIMER_HL_CHANGE_BRIGHT_SPEED, LTIMER_HL_BUT_LED, @@ -16,9 +16,9 @@ typedef enum { LTIMER_MENU_ADJ_TIME_OUT, LTIMER_LIGHT_SENSOR, LTIMER_SENSOR_BUT_DEBOUNCE, - - MAX_LTIMERS - + + MAX_LTIMERS + } LTimersNames_t; void InitLTimers ( void ); diff --git a/Libraries/LTimers/ltimers_config.c b/Libraries/LTimers/ltimers_config.c index 069a6ca..a30b36f 100644 --- a/Libraries/LTimers/ltimers_config.c +++ b/Libraries/LTimers/ltimers_config.c @@ -4,42 +4,16 @@ // ---------------------------------------------------------------------------- -// 1 +// Инициализация аппаратного таймера для генерирования прерываний каждую 1мс // ---------------------------------------------------------------------------- void LTimersConfig ( void ) { -// NVIC_InitTypeDef NVIC_InitStructure; -// TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; -// -// /* TIM6 clock enable */ -// RCC_APB1PeriphClockCmd ( RCC_APB1Periph_TIM6 , ENABLE ); -// -// /* Enable the TIM6 global Interrupt */ -// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; -// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; -// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; -// NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; -// NVIC_Init ( &NVIC_InitStructure ); -// -// /* Configure TIM6 to generate interrupt each 1ms */ -// TIM_TimeBaseStructure.TIM_Period = 1000; -// TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; -// TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; -// TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; -// TIM_TimeBaseInit ( TIM6, &TIM_TimeBaseStructure ); -// -// /* TIM6 IT enable */ -// TIM_ITConfig ( TIM6, TIM_IT_Update , ENABLE ); -// -// /* TIM6 enable counter */ -// TIM_Cmd ( TIM6, ENABLE ); - NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - + /* LTIMER_TIMx clock enable */ LTIMER_RCC_APBxPeriphClockCmd ( LTIMER_TIM_RCC, ENABLE ); - + /* Enable the LTIMER_TIMx gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = LTIMER_TIM_IRQx; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; @@ -49,34 +23,34 @@ void LTimersConfig ( void ) /* ----------------------------------------------------------------------- In this example TIM7 counter clock (TIM7CLK) is set to APB1 clock (PCLK1), since APB1 prescaler is set to 1 and TIM7 prescaler is set to 0. - - In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), - since APB1 prescaler is set to 1. + + In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), + since APB1 prescaler is set to 1. TIM7CLK = PCLK1 = HCLK = SystemCoreClock - + With Prescaler set to 479 and Period to 24999, the TIM7 counter is updated each 250 ms (i.e. and interrupt is generated each 250 ms) TIM7 counter clock = TIM7CLK /((Prescaler + 1)*(Period + 1)) = 48 MHz / ((25000)*(480)) - = 4 Hz + = 4 Hz ==> TIM7 counter period = 250 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration - based on this variable will be incorrect. - ----------------------------------------------------------------------- */ + based on this variable will be incorrect. + ----------------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 1000; //24999; TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; //479; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit ( LTIMER_TIMx, &TIM_TimeBaseStructure ); - + /* LTIMER_TIMx Interrupts enable */ TIM_ITConfig ( LTIMER_TIMx, TIM_IT_Update, ENABLE ); - + /* LTIMER_TIMx enable counter */ TIM_Cmd ( LTIMER_TIMx, ENABLE ); } diff --git a/Libraries/LTimers/ltimers_config.h b/Libraries/LTimers/ltimers_config.h index 7e8efe2..50a75db 100644 --- a/Libraries/LTimers/ltimers_config.h +++ b/Libraries/LTimers/ltimers_config.h @@ -1,8 +1,8 @@ #ifndef LTIMERS_CONFIG_INCLUDED #define LTIMERS_CONFIG_INCLUDED -// -// , APB1 APB2 +// Примечание +// Обратить внимание на то, что таймеры тактируются от разных шин APB1 или APB2 #define LTIMER_IRQHandler TIM17_IRQHandler #define LTIMER_TIMx TIM17 diff --git a/Libraries/LightSensor/light_sensor_task.c b/Libraries/LightSensor/light_sensor_task.c index 70b6bc9..d1a0f89 100644 --- a/Libraries/LightSensor/light_sensor_task.c +++ b/Libraries/LightSensor/light_sensor_task.c @@ -1,33 +1,33 @@ #include "light_sensor_task.h" #include "ltimers.h" -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" -// : -// - ? -// - -// - -// - 50 , 100 . - -// * GL5516 . -// +3.3 10. -// 6, -// 200 , , -// . -// , , , -// . +// Если используется фоторезистор: +// - калибровка датчика освещенности ? +// - добавить гистерезис +// - плавное изменение яркости +// - как будет реагировать фоторезистор на мерцание 50 Гц, 100 Гц на диодное и тд. + +// * Фоторезистор GL5516 стоит в нижнем плече делителя. В врехнем плече на питание +// +3.3В подключен резистор 10К. +// Фоторезистор в полной темноте дает сопротивление до 6МОм, на свету у окна +// в пасмурную питерскую погоду около 200 Ом, а если на ярком солнце, то и еще +// меньше. +// В итоге, чем ярче освещение, тем ниже сопротивление, тем ниже напряжение +// на АЦП. // -// . -// . -// -// - , -// - /. +// Порог переключения яркости ламп нужно в приложении настраивать под себя. +// И сделать по умолчанию. +// +// - теперь нужно опытным путем определить порог, когда лампам нужно убавить яркость +// Для начала сделать только два варианта - светло/темно. -#define LIGHT_THREHSOLD 3300 // , +#define LIGHT_THREHSOLD 3300 // Значение АЦП, подобранное опытным путем #define LIGHT 0 #define DARK 1 @@ -44,7 +44,7 @@ QueueHandle_t queue_light_sensor; void LightSensorInit ( void ) { // - ADC init - ADC_Config (); + ADC_Config (); queue_light_sensor = xQueueCreate ( 1, sizeof (LightSensorState_t) ); configASSERT( queue_light_sensor ); } @@ -57,119 +57,102 @@ static void ADC_Config(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; - + /* GPIOC Periph clock enable */ RCC_AHBPeriphClockCmd(LIGHT_SENSOR_RCC_AHBPeriph_GPIOx, ENABLE); - + /* ADC1 Periph clock enable */ LIGHT_SENSOR_RCC_APBxPeriphClockCmd(LIGHT_SENSOR_RCC_APBxPeriph_ADCx, ENABLE); - + /* Configure ADC Channelx as analog input */ GPIO_InitStructure.GPIO_Pin = LIGHT_SENSOR_GPIO_PINx ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(LIGHT_SENSOR_GPIOx, &GPIO_InitStructure); -// /* GPIO pin configuration */ -// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; -// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; -// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; -// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; -// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; -// GPIO_Init ( GPIOB, &GPIO_InitStructure ); - - /* ADCs DeInit */ + /* ADCs DeInit */ ADC_DeInit(LIGHT_SENSOR_ADCx); - + /* Initialize ADC structure */ ADC_StructInit(&ADC_InitStructure); - + /* Configure the ADC1 in continuous mode with a resolution equal to 12 bits */ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; - ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; + ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; - ADC_Init(LIGHT_SENSOR_ADCx, &ADC_InitStructure); - - /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */ + ADC_Init(LIGHT_SENSOR_ADCx, &ADC_InitStructure); + + /* Convert the ADC1 Channel 11 with 239.5 Cycles as sampling time */ ADC_ChannelConfig(LIGHT_SENSOR_ADCx, LIGHT_SENSOR_ADC_Channelx , ADC_SampleTime_239_5Cycles); /* ADC Calibration */ ADC_GetCalibrationFactor(LIGHT_SENSOR_ADCx); - + /* Enable the ADC peripheral */ - ADC_Cmd(LIGHT_SENSOR_ADCx, ENABLE); - + ADC_Cmd(LIGHT_SENSOR_ADCx, ENABLE); + /* Wait the ADRDY flag */ - while(!ADC_GetFlagStatus(LIGHT_SENSOR_ADCx, ADC_FLAG_ADRDY)); - - /* ADC1 regular Software Start Conv */ + while(!ADC_GetFlagStatus(LIGHT_SENSOR_ADCx, ADC_FLAG_ADRDY)); + + /* ADC1 regular Software Start Conv */ ADC_StartOfConversion(LIGHT_SENSOR_ADCx); - + } // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void ProcessFSM_LightSensor ( void ) { static uint8_t process_light_state = 0; LightSensorState_t light_sensor_state; - - // - curr prev light - //static uint8_t curr_light = DARK; - //static uint8_t prev_light = LIGHT; - /* Test EOC flag */ - // - + // - заменить этот файл на проверку и выход while(ADC_GetFlagStatus(LIGHT_SENSOR_ADCx, ADC_FLAG_EOC) == RESET); - /* Get ADC1 converted data */ ADC_ConvertedValue = ADC_GetConversionValue(LIGHT_SENSOR_ADCx); - switch ( process_light_state ) { - case 0: // - if (ADC_ConvertedValue < LIGHT_THREHSOLD) // + case 0: // ждем когда посветлеет + if (ADC_ConvertedValue < LIGHT_THREHSOLD) // если стало светло { - // - , + // - запускаем таймер, в течение которого проверяем освещение StartLTimer (LTIMER_LIGHT_SENSOR); - // - + // - переходим в состояние проверки яркости в течение таймера process_light_state = 2; } break; - - case 1: // - if (ADC_ConvertedValue > LIGHT_THREHSOLD) // + case 1: // ждем когда потемнет + if (ADC_ConvertedValue > LIGHT_THREHSOLD) // если стало темно { - // - , + // - запускаем таймер, в течение которого проверяем освещение StartLTimer (LTIMER_LIGHT_SENSOR); - // - + // - переходим в состояние проверки яркости в течение таймера process_light_state = 3; } break; - case 2: if ( GetLTimer (LTIMER_LIGHT_SENSOR) >= TIME_LIGHT_SENSOR ) - { - // - , - // - // - + { + // - если таймер вышел, значит подтверждается новое значение + // освещенности + // - отправляем сообщение на смену режима light_sensor_state = LIGHT_SENSOR_STATE_LIGHT; xQueueSend ( queue_light_sensor, &light_sensor_state, 0 ); - // - + // - а затем идем проверять когда потемнеет process_light_state = 1; } else { - // - , - // , , 0 - // () + // - если таймер еще тикает, то проверяем освещенность + // и, если она изменилась, то возвращаемся в состояние 0 + // то есть в начало алгоритма проверки яркости (освещенности) if (ADC_ConvertedValue < LIGHT_THREHSOLD) { - // + // то ничего не меняем } else { @@ -177,26 +160,25 @@ void ProcessFSM_LightSensor ( void ) } } break; - case 3: if ( GetLTimer (LTIMER_LIGHT_SENSOR) >= TIME_LIGHT_SENSOR ) - { - // - , - // - // - + { + // - если таймер вышел, значит подтверждается новое значение + // освещенности + // - отправляем сообщение на смену режима light_sensor_state = LIGHT_SENSOR_STATE_DARK; xQueueSend ( queue_light_sensor, &light_sensor_state, 0 ); - // - + // - а затем идем проверять когда посветлеет process_light_state = 0; } else { - // - , - // , , 0 - // () + // - если таймер еще тикает, то проверяем освещенность + // и, если она изменилась, то возвращаемся в состояние 0 + // то есть в начало алгоритма проверки яркости (освещенности) if (ADC_ConvertedValue > LIGHT_THREHSOLD) { - // + // то ничего не меняем } else { @@ -204,22 +186,17 @@ void ProcessFSM_LightSensor ( void ) } } break; - default: break; - } - vTaskDelay (100); - //GPIOB->ODR ^= GPIO_Pin_2; } // ---------------------------------------------------------------------------- -// , +// Задача ОС, реализующая головную задачу программы // ---------------------------------------------------------------------------- void LightSensor_Task ( void *pvParameters ) { while(1)ProcessFSM_LightSensor (); - //vTaskDelete(NULL); -} \ No newline at end of file +} diff --git a/Libraries/LightSensor/light_sensor_task.h b/Libraries/LightSensor/light_sensor_task.h index f797ecc..65dbba9 100644 --- a/Libraries/LightSensor/light_sensor_task.h +++ b/Libraries/LightSensor/light_sensor_task.h @@ -3,8 +3,8 @@ #include "stm32f0xx_conf.h" -#define LIGHT_SENSOR_GPIO_PINx GPIO_Pin_6 -#define LIGHT_SENSOR_GPIOx GPIOA +#define LIGHT_SENSOR_GPIO_PINx GPIO_Pin_6 +#define LIGHT_SENSOR_GPIOx GPIOA #define LIGHT_SENSOR_RCC_AHBPeriph_GPIOx RCC_AHBPeriph_GPIOA #define LIGHT_SENSOR_ADCx ADC1 @@ -13,14 +13,12 @@ #define LIGHT_SENSOR_RCC_APBxPeriph_ADCx RCC_APB2Periph_ADC1 typedef enum { - LIGHT_SENSOR_STATE_LIGHT, LIGHT_SENSOR_STATE_DARK - } LightSensorState_t; void LightSensorInit ( void ); void LightSensor_Task ( void *pvParameters ); -#endif //LIGHT_SENSOR_TASK_INCLUDED \ No newline at end of file +#endif //LIGHT_SENSOR_TASK_INCLUDED diff --git a/Libraries/NixieDriver/nixie_driver_config.c b/Libraries/NixieDriver/nixie_driver_config.c index 6b5ce8a..defc674 100644 --- a/Libraries/NixieDriver/nixie_driver_config.c +++ b/Libraries/NixieDriver/nixie_driver_config.c @@ -1,32 +1,26 @@ #include "nixie_driver_config.h" - static void NixieDriver_TIMConfig ( void ); static void NixieDriver_SPIConfig ( void ); - -// ---------------------------------------------------------------------------- -// -// ---------------------------------------------------------------------------- void NixieDriverConfig ( void ) { NixieDriver_TIMConfig (); NixieDriver_SPIConfig (); } - // ---------------------------------------------------------------------------- -// 100 . 100 -// Nixie +// Конфигурируем таймер на 100 мкс. В прерывании каждые 100 мкс будет +// проворачиваться механизм динамической индикации ламп Nixie // ---------------------------------------------------------------------------- static void NixieDriver_TIMConfig ( void ) { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - + /* NIX_DRIVER_TIMx clock enable */ NIX_DRIVER_RCC_APBxPeriphClockCmd ( NIX_DRIVER_TIM_RCC, ENABLE ); - + /* Enable the NIX_DRIVER_TIMx gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = NIX_DRIVER_TIM_IRQx; NVIC_InitStructure.NVIC_IRQChannelPriority = 1; @@ -36,35 +30,35 @@ static void NixieDriver_TIMConfig ( void ) /* ----------------------------------------------------------------------- In this example TIM7 counter clock (TIM7CLK) is set to APB1 clock (PCLK1), since APB1 prescaler is set to 1 and TIM7 prescaler is set to 0. - - In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), - since APB1 prescaler is set to 1. + + In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1), + since APB1 prescaler is set to 1. TIM7CLK = PCLK1 = HCLK = SystemCoreClock - + With Prescaler set to 479 and Period to 24999, the TIM7 counter is updated each 250 ms (i.e. and interrupt is generated each 250 ms) TIM7 counter clock = TIM7CLK /((Prescaler + 1)*(Period + 1)) = 48 MHz / ((25000)*(480)) - = 4 Hz + = 4 Hz ==> TIM7 counter period = 250 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration - based on this variable will be incorrect. - ----------------------------------------------------------------------- */ - + based on this variable will be incorrect. + ----------------------------------------------------------------------- */ + /* Time base configuration */ - TIM_TimeBaseStructure.TIM_Period = 100; // //24999 + TIM_TimeBaseStructure.TIM_Period = 100; // Это миксросекунды //24999 TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; //479; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit ( NIX_DRIVER_TIMx, &TIM_TimeBaseStructure ); - + /* NIX_DRIVER_TIMx Interrupts enable */ TIM_ITConfig ( NIX_DRIVER_TIMx, TIM_IT_Update, ENABLE ); - + /* NIX_DRIVER_TIMx enable counter */ TIM_Cmd ( NIX_DRIVER_TIMx, ENABLE ); } @@ -78,22 +72,22 @@ static void NixieDriver_SPIConfig ( void ) GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; - + /* Enable the SPI periph */ NIX_SPIx_RCC_APBxPeriphClockCmd ( NIX_SPIx_CLK, ENABLE ); - + /* Enable SCK, MOSI, MISO and NSS GPIO clocks */ - RCC_AHBPeriphClockCmd ( NIX_SPIx_SCK_GPIO_CLK | - NIX_SPIx_MOSI_GPIO_CLK | + RCC_AHBPeriphClockCmd ( NIX_SPIx_SCK_GPIO_CLK | + NIX_SPIx_MOSI_GPIO_CLK | NIX_SPIx_ST_GPIO_CLK | NIX_GPIOx_TUB_P1_GPIO_CLK | NIX_GPIOx_TUB_P2_GPIO_CLK, ENABLE ); - + GPIO_PinAFConfig ( NIX_SPIx_SCK_GPIO_PORT, NIX_SPIx_SCK_SOURCE, NIX_SPIx_SCK_AF ); GPIO_PinAFConfig ( NIX_SPIx_MOSI_GPIO_PORT, NIX_SPIx_MOSI_SOURCE, NIX_SPIx_MOSI_AF ); //GPIO_PinAFConfig ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_SOURCE, NIX_SPIx_ST_AF ); - + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; @@ -106,7 +100,7 @@ static void NixieDriver_SPIConfig ( void ) /* SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = NIX_SPIx_MOSI_PIN; GPIO_Init ( NIX_SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure ); - + /* GPIO ST pin configuration */ GPIO_InitStructure.GPIO_Pin = NIX_SPIx_ST_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; @@ -116,29 +110,28 @@ static void NixieDriver_SPIConfig ( void ) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; GPIO_Init ( NIX_SPIx_ST_GPIO_PORT, &GPIO_InitStructure ); - // ( ) - - /* GPIO tub_dp1 pin configuration */ - GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP1_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; - GPIO_Init ( NIX_GPIOx_TUB_DP1_PORT, &GPIO_InitStructure ); - - /* GPIO tub_dp2 pin configuration */ - GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP2_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; - GPIO_Init ( NIX_GPIOx_TUB_DP2_PORT, &GPIO_InitStructure ); - - + // Пины управления точками на лампах (не хватило ног сдвиговых редисок) + + /* GPIO tub_dp1 pin configuration */ + GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP1_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; + GPIO_Init ( NIX_GPIOx_TUB_DP1_PORT, &GPIO_InitStructure ); + + /* GPIO tub_dp2 pin configuration */ + GPIO_InitStructure.GPIO_Pin = NIX_GPIOx_TUB_DP2_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; + GPIO_Init ( NIX_GPIOx_TUB_DP2_PORT, &GPIO_InitStructure ); + /* SPI configuration -------------------------------------------------------*/ SPI_I2S_DeInit ( NIX_SPIx ); - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - //SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + //SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; @@ -149,61 +142,20 @@ static void NixieDriver_SPIConfig ( void ) SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init ( NIX_SPIx, &SPI_InitStructure ); - + /* Enable the SPI peripheral */ SPI_Cmd ( NIX_SPIx, ENABLE ); - + /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = NIX_SPIx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init ( &NVIC_InitStructure ); - + // /* Enable the Tx buffer empty interrupt */ SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE ); - + NIX_DRIVER_RESET_ST_PIN; NIX_DRIVER_RESET_TUB_DP1_PIN; NIX_DRIVER_RESET_TUB_DP2_PIN; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/NixieDriver/nixie_driver_config.h b/Libraries/NixieDriver/nixie_driver_config.h index 50c0e5e..29f7a17 100644 --- a/Libraries/NixieDriver/nixie_driver_config.h +++ b/Libraries/NixieDriver/nixie_driver_config.h @@ -3,38 +3,33 @@ #include "stm32f0xx_conf.h" - /* Communication boards SPIx Interface */ #define NIX_SPIx SPI1 #define NIX_SPIx_CLK RCC_APB2Periph_SPI1 #define NIX_SPIx_IRQn SPI1_IRQn #define NIX_SPIx_IRQHandler SPI1_IRQHandler -#define NIX_SPIx_SCK_PIN GPIO_Pin_5 -#define NIX_SPIx_SCK_GPIO_PORT GPIOA +#define NIX_SPIx_SCK_PIN GPIO_Pin_5 +#define NIX_SPIx_SCK_GPIO_PORT GPIOA #define NIX_SPIx_SCK_GPIO_CLK RCC_AHBPeriph_GPIOA #define NIX_SPIx_SCK_SOURCE GPIO_PinSource5 -#define NIX_SPIx_SCK_AF GPIO_AF_0 +#define NIX_SPIx_SCK_AF GPIO_AF_0 -#define NIX_SPIx_MOSI_PIN GPIO_Pin_7 -#define NIX_SPIx_MOSI_GPIO_PORT GPIOA +#define NIX_SPIx_MOSI_PIN GPIO_Pin_7 +#define NIX_SPIx_MOSI_GPIO_PORT GPIOA #define NIX_SPIx_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOA #define NIX_SPIx_MOSI_SOURCE GPIO_PinSource7 #define NIX_SPIx_MOSI_AF GPIO_AF_0 -#define NIX_SPIx_ST_PIN GPIO_Pin_4 -#define NIX_SPIx_ST_GPIO_PORT GPIOA +#define NIX_SPIx_ST_PIN GPIO_Pin_4 +#define NIX_SPIx_ST_GPIO_PORT GPIOA #define NIX_SPIx_ST_GPIO_CLK RCC_AHBPeriph_GPIOA #define NIX_SPIx_ST_SOURCE GPIO_PinSource4 #define NIX_SPIx_ST_AF GPIO_AF_0 -//#define NIX_SPIx_ST_EXTI_PIN GPIO_Pin_14 -//#define NIX_SPIx_ST_EXTI_GPIO_PORT GPIOB -//#define NIX_SPIx_ST_EXTI_GPIO_CLK RCC_AHBPeriph_GPIOB - #define NIX_SPIx_RCC_APBxPeriphClockCmd RCC_APB2PeriphClockCmd -// NixieDriver -------------------------------------- // +// Определения для таймера NixieDriver -------------------------------------- // #define NIX_DRIVER_TIM_IRQHandler TIM16_IRQHandler #define NIX_DRIVER_TIMx TIM16 #define NIX_DRIVER_TIM_RCC RCC_APB2Periph_TIM16 @@ -44,7 +39,7 @@ #define NIX_DRIVER_SET_ST_PIN GPIO_SetBits ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_PIN ) #define NIX_DRIVER_RESET_ST_PIN GPIO_ResetBits ( NIX_SPIx_ST_GPIO_PORT, NIX_SPIx_ST_PIN ) -// (.. ) +// Определения для управления точками на лампах (т.к. не хватило ног сдвиговых редисок) #define NIX_GPIOx_TUB_P1_GPIO_CLK RCC_AHBPeriph_GPIOB #define NIX_GPIOx_TUB_P2_GPIO_CLK RCC_AHBPeriph_GPIOB #define NIX_GPIOx_TUB_DP1_PIN GPIO_Pin_14 @@ -56,51 +51,7 @@ #define NIX_DRIVER_SET_TUB_DP1_PIN NIX_GPIOx_TUB_DP1_PORT->BSRR = NIX_GPIOx_TUB_DP1_PIN #define NIX_DRIVER_SET_TUB_DP2_PIN NIX_GPIOx_TUB_DP2_PORT->BSRR = NIX_GPIOx_TUB_DP2_PIN - -//#define NIX_TEST_SET_PB12_PIN GPIO_SetBits ( GPIOB, GPIO_Pin_12 ) -//#define NIX_TEST_RESET_PB12_PIN GPIO_ResetBits ( GPIOB, GPIO_Pin_12 ) -//#define NIX_TEST_PIN_PB11_TOGGLE GPIOB->ODR ^= GPIO_Pin_11 -//#define NIX_TEST_PIN_PB12_TOGGLE GPIOB->ODR ^= GPIO_Pin_12 - void NixieDriverInitProcess ( void ); void NixieDriverConfig ( void ); - #endif //NIXIE_DRIVER_CONFIG_INCLUDED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/NixieDriver/nixie_driver_process.c b/Libraries/NixieDriver/nixie_driver_process.c index ddc728b..219494e 100644 --- a/Libraries/NixieDriver/nixie_driver_process.c +++ b/Libraries/NixieDriver/nixie_driver_process.c @@ -5,68 +5,68 @@ #include -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" -// - -// - -// - -// - 1 -// - 2 - -#define TUBE_HEATING_UP 0 - - -static const uint16_t tube_off_digit = 0; // , - -// . . -// , 1 -const uint16_t tube_digits [MAX_DIGITS] = { // - TUBE_DIGIT_0, // 0 - TUBE_DIGIT_1, // 1 - TUBE_DIGIT_2, // 2 - TUBE_DIGIT_3, // 3 - TUBE_DIGIT_4, // 4 - TUBE_DIGIT_5, // 5 - TUBE_DIGIT_6, // 6 - TUBE_DIGIT_7, // 7 - TUBE_DIGIT_8, // 8 - TUBE_DIGIT_9, // 9 - TUBE_DIGIT_DP1, // dp1 - TUBE_DIGIT_DP2, // dp2 - TUBE_DIGIT_EMPTY // +// - массив для цифр дешифратора +// - массив для номера лампы +// - счетчик номера текущей лампы +// - таймер1 для времени горения +// - таймер2 для времени затухания + +#define TUBE_HEATING_UP 0 + +static const uint16_t tube_off_digit = 0; // Символ для дешифратора, чтобы лампа не горела + +// Массив значений цифр для дешифратора. Если старший байт вперед. +// И учтено, что все значения сдвинуты на 1 влево +const uint16_t tube_digits [MAX_DIGITS] = { + // Цифра на лампе + TUBE_DIGIT_0, // 0 + TUBE_DIGIT_1, // 1 + TUBE_DIGIT_2, // 2 + TUBE_DIGIT_3, // 3 + TUBE_DIGIT_4, // 4 + TUBE_DIGIT_5, // 5 + TUBE_DIGIT_6, // 6 + TUBE_DIGIT_7, // 7 + TUBE_DIGIT_8, // 8 + TUBE_DIGIT_9, // 9 + TUBE_DIGIT_DP1, // dp1 + TUBE_DIGIT_DP2, // dp2 + TUBE_DIGIT_EMPTY, // лампа не горит }; -// . , -// SPI -// , 1 +// Лампы на плате идут слева направо. Значение ячейки массива с учетом, если +// старший байт идет вперед в SPI +// И учтено, что все значения сдвинуты на 1 влево static const uint16_t tube_num [ MAX_TUBES ] = { - TUBE_NUM_1, // 1- - TUBE_NUM_2, // 2- - TUBE_NUM_3, // 3- - TUBE_NUM_4, // 4- - TUBE_NUM_5, // 5- - TUBE_NUM_6 // 6- + TUBE_NUM_1, // 1-я лампа + TUBE_NUM_2, // 2-я лампа + TUBE_NUM_3, // 3-я лампа + TUBE_NUM_4, // 4-я лампа + TUBE_NUM_5, // 5-я лампа + TUBE_NUM_6, // 6-я лампа }; -// - +// Текущий буфер с данными-цифрами на лампы static uint16_t curr_tube_bufer [ MAX_TUBES ] = { - TUBE_DIGIT_1, // 0 - TUBE_DIGIT_1, // 1 - TUBE_DIGIT_1, // 2 - TUBE_DIGIT_1, // 3 - TUBE_DIGIT_1, // 4 - TUBE_DIGIT_1 // 5 + TUBE_DIGIT_1, // 0 + TUBE_DIGIT_1, // 1 + TUBE_DIGIT_1, // 2 + TUBE_DIGIT_1, // 3 + TUBE_DIGIT_1, // 4 + TUBE_DIGIT_1, // 5 }; -// ------------------------------------------------------------------ // +// Яркость ------------------------------------------------------------------ // -// / +// горит / не горит // time1 / time2 // 1 9 // 2 8 @@ -79,63 +79,40 @@ static uint16_t curr_tube_bufer [ MAX_TUBES ] = { // 9 1 // 10 0 -#define TIME_PERIOD_TCONST (uint32_t)80 // . - // . 100 , = 80 => T = 80*100 = 8000 = 8 -#define TIME_MIN (uint32_t)1 // = 100 . +#define TIME_PERIOD_TCONST (uint32_t)80 // Время полного периода частоты работы ламп. Единица измерения зависит от настройки + // таймера. В данном случае таймер тикает раз в 100 мкс, значит Т = 80 => T = 80*100 = 8000мкс = 8мс +#define TIME_MIN (uint32_t)1 // Минимальный шаг времени таймера = 100 мкс. Минимальное время горения лампы -// - DARK LIGHT -// ( TIME_ON TIME_OFF) +// - добавить состояния DARK и LIGHT +// (по сути это только комбинации TIME_ON и TIME_OFF) #define TIME_ON 2//5//20 #define TIME_OFF 23//22 -// / -#define TIME_OFF_BRIGHT 0 -#define TIME_OFF_DARK 100 +// Время паузы после вкл/выкл всез ламп поочереди +#define TIME_OFF_BRIGHT 0 +#define TIME_OFF_DARK 100 #define TIME_TEST 10000 -static uint32_t time_on = TIME_ON; // -static uint32_t time_off = TIME_OFF; // ( ) +static uint32_t time_on = TIME_ON; // Время горения лампы +static uint32_t time_off = TIME_OFF; // Время на угасание лампы ( чтобы она успела погаснуть полностью ) static uint32_t time_off2 = TIME_OFF_DARK; -// static uint32_t time_on = TIME_OFF; -// static uint32_t time_off = TIME_ON; -// static uint32_t time_off2 = TIME_OFF_BRIGHT; -//static uint32_t coef_brightness = 1; // . ! - -// -// .. 2 . -//static uint8_t first_byte; - -// -//static uint16_t tube_nbr_second_value; - -// +// Сообщения очереди ОСРВ QueueHandle_t queue_new_value; QueueHandle_t queue_new_data; static LightSensorState_t light_sensor_state; extern QueueHandle_t queue_light_sensor; -// -------------------------------------------------- // -// +// Прототипы функций файла -------------------------------------------------- // +// Открытые void NixieDriver_SendValue ( uint8_t *value_arr ); -// +// Закрытые static void SwitchOnTube ( uint8_t tube_nbr ); static void SwitchOffTube ( uint8_t tube_nbr ); -// - ( EE ) -// void NixieDriver_LoadBrightnessFromMemory ( void ); // - coef_brightness -//static void NewTimeCalculate ( uint32_t *time_on, uint32_t *time_off ); -// - - NixieDriver_SetBrightness ( uint32_t ??? ); // ? -// - - NixieDriver_IncreaseBrighntness ( void ); // ( . +1 ) -// - - NixieDriver_DecreaseBrighntness ( void ); // ( . -1 ) -#if TUBE_HEATING_UP == 0 static uint8_t LoadNextValueToTubes ( void ); -#else -static uint8_t LoadNextValueToTubes ( void ); -#endif -//static void TestLoadNewValueToClock ( void ); static void UpdateValueForClock ( void ); static void CheckLightSensor (void); @@ -145,8 +122,6 @@ static void CheckLightSensor (void); // ---------------------------------------------------------------------------- void NixieDriverInitProcess ( void ) { - //first_byte = 0; - queue_new_value = xQueueCreate ( 1, sizeof (uint8_t*) ); configASSERT( queue_new_value ); queue_new_data = xQueueCreate ( 1, sizeof (DataToIndicate_t) ); @@ -155,49 +130,28 @@ void NixieDriverInitProcess ( void ) // ---------------------------------------------------------------------------- -// -, Nixie -// - , 100 +// Ф-я, реализующая беспрерывный процесс динамической индикации ламп Nixie +// Ф-я вызывается из прерывания таймера, настроенного на 100 мкс // ---------------------------------------------------------------------------- void ProcessNixieDriverFromISR ( void ) { static uint8_t process_indic_state = 0; static uint32_t timer = TIME_ON; - static uint8_t curr_tube_num = 0; - + static uint8_t curr_tube_num = 0; timer++; - //timer_test++; - -#if TUBE_HEATING_UP == 0 - +#if TUBE_HEATING_UP == 0 switch ( process_indic_state ) { - case 0: - - if ( timer >= time_off ) // + if ( timer >= time_off ) // Ждем время горения лампы { curr_tube_num = LoadNextValueToTubes (); SwitchOnTube ( curr_tube_num ); timer = 0; process_indic_state = 1; - /* - if ( curr_tube_num == (MAX_TUBES - 1) ) - { - UpdateValueForClock (); - CheckLightSensor(); - - // SwitchOffTube ( curr_tube_num ); - //process_indic_state = 2; - //timer = 0; - - } - */ } - break; - case 1: - if ( timer >= time_on ) { SwitchOffTube ( curr_tube_num ); @@ -215,77 +169,38 @@ void ProcessNixieDriverFromISR ( void ) } } - break; - case 2: - - if ( timer >= time_off2 ) - { - //SwitchOnTube ( curr_tube_num ); - timer = time_off; - process_indic_state = 0; - } - - break; - - } // end switch - -#else -/* - switch ( process_indic_state ) - { - - case 0: - - SwitchOnTube ( curr_tube_num ); - timer = 0; - process_indic_state = 1; - - break; - - case 1: - - if ( timer >= time1 ) // + if ( timer >= time_off2 ) { - curr_tube_num = LoadNextValueToTubes (); - timer = 0; + timer = time_off; process_indic_state = 0; } - break; - } // end switch - */ - #endif - } // ---------------------------------------------------------------------------- -// - SPI -// . -// - , -// - +// Ф-я подготовки и запуска передачи байт по SPI в сдвиговые регистры +// управеления динамической индикацией. По сути включает нужную лампу +// Ф-я принимает текущий номер лампы, для которой будет формироваться +// пакет-кадр // ---------------------------------------------------------------------------- static void SwitchOnTube ( uint8_t tube_nbr ) { - // - - // - - + // - сначала отправляем пару байт с номером лампы + // - затем отправляем пару байт с номером цифры static uint16_t temp; - temp = 0; - temp = tube_num [ tube_nbr ]; //(uint16_t)curr_tube_bufer [ tube_nbr ]; + temp = tube_num [ tube_nbr ]; temp |= curr_tube_bufer [ tube_nbr ]; - NIX_DRIVER_RESET_ST_PIN; - - // .. GPIO, - // - // : - // , SPI, - // , ST + // Т.к. точки на лампах управляются напрямую с МК через GPIO, + // то нужно проверять вручную идет ли в пакете точка + // Маленький нюанс: + // Если мы выставим сигнал на точки раньше, чем передадим пакет на включение ламп по SPI, + // то по идее точки включатся раньше, чем подастся сигнал ST if (curr_tube_bufer [ tube_nbr ] & TUBE_DIGIT_DP1) { NIX_DRIVER_SET_TUB_DP1_PIN; @@ -294,7 +209,6 @@ static void SwitchOnTube ( uint8_t tube_nbr ) { NIX_DRIVER_RESET_TUB_DP1_PIN; } - if (curr_tube_bufer [ tube_nbr ] & TUBE_DIGIT_DP2) { NIX_DRIVER_SET_TUB_DP2_PIN; @@ -303,82 +217,32 @@ static void SwitchOnTube ( uint8_t tube_nbr ) { NIX_DRIVER_RESET_TUB_DP2_PIN; } - SPI_I2S_SendData16 ( NIX_SPIx, temp ); SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE ); } - // ---------------------------------------------------------------------------- -// - +// Ф-я отключает лампу // ---------------------------------------------------------------------------- static void SwitchOffTube ( uint8_t tube_nbr ) { - //static uint16_t value_to_spi1; - //static uint16_t temp1; - - //value_to_spi1 = (uint16_t)tube_off_digit; - //value_to_spi1 <<= 8; - - //temp1 = 0; - //temp1 = (uint16_t)tube_num [ tube_nbr ]; - - //value_to_spi1 |= temp1; - - //first_byte = 1; - //tube_nbr_second_value = tube_off_digit; NIX_DRIVER_RESET_ST_PIN; - NIX_DRIVER_RESET_TUB_DP1_PIN; NIX_DRIVER_RESET_TUB_DP2_PIN; SPI_I2S_SendData16 ( NIX_SPIx, tube_off_digit ); SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, ENABLE ); } -// ---------------------------------------------------------------------------- -// - -// SPI -// - SPI -// , GPIO -// ---------------------------------------------------------------------------- -// void NixieDriverCheckDPPins (void) -// { -// ; -// } - - -// ---------------------------------------------------------------------------- -// - 2 SPI -// - NIX_SPIx_IRQHandler -// ---------------------------------------------------------------------------- -// uint8_t NixieDriverProcessCheckIsFirstByte (void) -// { -// //return first_byte; -// return 0; -// } - - -// ---------------------------------------------------------------------------- -// - -// ---------------------------------------------------------------------------- -// void NixieDriverProcessSendSecondByte ( void ) -// { -// first_byte = 0; -// SPI_I2S_SendData16 ( NIX_SPIx, tube_nbr_second_value ); -// } - - #if TUBE_HEATING_UP == 1 // ---------------------------------------------------------------------------- -// - +// Временная ф-я для прогрева каждой лампы по каждому катоду // ---------------------------------------------------------------------------- static uint8_t LoadNextValueToTubes ( void ) { static uint8_t curr_tube_num = 0; static uint8_t curr_digit = 0; - if ( curr_digit == 10 ) - { + { if ( curr_tube_num == 5 ) { curr_tube_num = 0; @@ -402,91 +266,39 @@ static uint8_t LoadNextValueToTubes ( void ) static uint8_t LoadNextValueToTubes ( void ) { static uint8_t curr_tube_num = 5; - if ( curr_tube_num == 5 ) { curr_tube_num = 0; - //NIX_TEST_PIN_PB11_TOGGLE; } else { curr_tube_num++; } - return curr_tube_num; } #endif - -// ---------------------------------------------------------------------------- -// - -// -// ---------------------------------------------------------------------------- -//static void NewTimeCalculate ( uint32_t *time_on, uint32_t *time_off ) -//{ -//// uint32_t time_check; -//// -//// time_on = TIME_MIN*coef_brightness; -//// -//// if ( time_on > TIME_PERIOD_TCONST ) { return; } -// -//} - - -// ---------------------------------------------------------------------------- -// - -// -// ---------------------------------------------------------------------------- -//static void TestLoadNewValueToClock ( void ) -//{ -// static uint8_t digit_num = 0; -// -// //curr_tube_bufer [] = tube_digits []; -// // -// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ ) -// { -// curr_tube_bufer [tube_num] = tube_digits [digit_num]; -// } -// digit_num++; -// -// if ( digit_num == MAX_DIGITS ) -// { -// digit_num = 0; -// } -//} - - // ---------------------------------------------------------------------------- -// -// - - ProcessNixieDriverFromISR () -// ( 6- ) +// Обновления значения выводимого на индикаторы +// Ф-я вызывается из ф-ии ProcessNixieDriverFromISR () после вывода одного +// цикла ( то есть 6-ти индикаторов ) // ---------------------------------------------------------------------------- -// - ! , -// SPI. , -// . . -// , . -// , . +// - внимание! нужно сделать два буфера, из которых в прерывании берутся +// данные на передачу в лампы в SPI. Это нужно, чтобы не тратить время на +// заполнение данных буфера. Сделать флаг или семафор. Пока из одного +// буфера данные уходят, то в другой заполняют новые данные. А когда они +// заполнятся, то просто поменять указатель на массив. -// - tube_digits [10] -// ( 10) +// - сделать защиту от выхода за границы массива tube_digits [10] +// (не больше 10) static void UpdateValueForClock ( void ) { - // - - // , curr_tube_bufer [] - //uint8_t *value_arr; + // - проверяем сообщение очереди с новыми данными для отображения + // если есть, то заполняем буфер curr_tube_bufer [] новыми значениями DataToIndicate_t data_struct; - -// if ( pdPASS == xQueueReceive ( queue_new_value, &value_arr, 0 ) ) -// { -// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ ) -// { -// curr_tube_bufer [tube_num] = tube_digits [ value_arr [tube_num] ]; -// } -// } - if ( pdPASS == xQueueReceive ( queue_new_data, &data_struct, 0 ) ) { @@ -496,9 +308,7 @@ static void UpdateValueForClock ( void ) curr_tube_bufer [3] = tube_digits [ data_struct.indic_4 ]; curr_tube_bufer [4] = tube_digits [ data_struct.indic_5 ]; curr_tube_bufer [5] = tube_digits [ data_struct.indic_6 ]; - } - } @@ -527,69 +337,10 @@ static void CheckLightSensor (void) // ---------------------------------------------------------------------------- -// - -// 6 ( ) +// Ф-я кладет сообщение в очередь ОС и передает указатель на массив с данными +// Размер массива всегда 6 (количество ламп) // ---------------------------------------------------------------------------- void NixieDriver_SendValue ( uint8_t *value_arr ) { xQueueSend ( queue_new_value, &value_arr, 0 ); } - -//void NixieDriver_SendValue2 ( uint8_t *value_arr ) -//{ -// xQueueSend ( queue_new_value, &value_arr, 0 ); -//} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/NixieDriver/nixie_driver_process.h b/Libraries/NixieDriver/nixie_driver_process.h index 00f08f5..bc4b4ca 100644 --- a/Libraries/NixieDriver/nixie_driver_process.h +++ b/Libraries/NixieDriver/nixie_driver_process.h @@ -5,50 +5,48 @@ #include "FreeRTOS.h" #include "queue.h" -// 8- . -// , - -#define MAX_TUBES 6 -#define MAX_DIGITS 13//11 - -// tube_digit [] 16- -#define TUBE_DIGIT_0 8192 //0010 0000 0000 0000 -#define TUBE_DIGIT_1 128 //0000 0000 1000 0000 -#define TUBE_DIGIT_2 64 //0000 0000 0100 0000 -#define TUBE_DIGIT_3 32 //0000 0000 0010 0000 -#define TUBE_DIGIT_4 16 //0000 0000 0001 0000 -#define TUBE_DIGIT_5 8 //0000 0000 0000 1000 -#define TUBE_DIGIT_6 4 //0000 0000 0000 0100 -#define TUBE_DIGIT_7 2 //0000 0000 0000 0010 -#define TUBE_DIGIT_8 32768 //1000 0000 0000 0000 -#define TUBE_DIGIT_9 16384 //0100 0000 0000 0000 -#define TUBE_DIGIT_DP1 1 //0000 0000 0000 0001 , .. GPIO -#define TUBE_DIGIT_DP2 256 //0000 0001 0000 0000 , .. GPIO -#define TUBE_DIGIT_EMPTY 0 - -#define TUBE_EMPTY_VALUE 0 // "10". , - // , - // - -// tube_num [ MAX_TUBES ] -#define TUBE_NUM_6 1 -#define TUBE_NUM_5 256 -#define TUBE_NUM_4 512 -#define TUBE_NUM_3 1024 -#define TUBE_NUM_2 2048 -#define TUBE_NUM_1 4096 - -// -// +// Схема драйвера Никси на трех сдвиговых 8-разрядных регистрах. +// Первые два регистра для цифр, третий регистр для выбора лампы + +#define MAX_TUBES 6 +#define MAX_DIGITS 13//11 + +// Коды цифр ламп для буфера tube_digit [] Значения 16-разрядные +#define TUBE_DIGIT_0 8192 //0010 0000 0000 0000 +#define TUBE_DIGIT_1 128 //0000 0000 1000 0000 +#define TUBE_DIGIT_2 64 //0000 0000 0100 0000 +#define TUBE_DIGIT_3 32 //0000 0000 0010 0000 +#define TUBE_DIGIT_4 16 //0000 0000 0001 0000 +#define TUBE_DIGIT_5 8 //0000 0000 0000 1000 +#define TUBE_DIGIT_6 4 //0000 0000 0000 0100 +#define TUBE_DIGIT_7 2 //0000 0000 0000 0010 +#define TUBE_DIGIT_8 32768 //1000 0000 0000 0000 +#define TUBE_DIGIT_9 16384 //0100 0000 0000 0000 +#define TUBE_DIGIT_DP1 1 //0000 0000 0000 0001 любое отличное от остальных число, т.к. точки на лампах управляются от отдельных GPIO +#define TUBE_DIGIT_DP2 256 //0000 0001 0000 0000 любое отличное от остальных число, т.к. точки на лампах управляются от отдельных GPIO +#define TUBE_DIGIT_EMPTY 0 + +#define TUBE_EMPTY_VALUE 0 // Было "10". Число, которое нужно записать в массив + // данных на вывод, чтобы получить негорящий + // индикатор + +// Коды номера лампы для буфера tube_num [ MAX_TUBES ] +#define TUBE_NUM_6 1 +#define TUBE_NUM_5 256 +#define TUBE_NUM_4 512 +#define TUBE_NUM_3 1024 +#define TUBE_NUM_2 2048 +#define TUBE_NUM_1 4096 + +// Структура данных на индикацию для передачи целиком всей структуры через +// очередь ОС typedef struct { - uint8_t indic_1; uint8_t indic_2; uint8_t indic_3; uint8_t indic_4; uint8_t indic_5; - uint8_t indic_6; - + uint8_t indic_6; } DataToIndicate_t; @@ -60,8 +58,5 @@ extern QueueHandle_t queue_new_data; #define NixieDriver_SendValue2(X) send(X) void ProcessNixieDriverFromISR ( void ); -//uint8_t NixieDriverProcessCheckIsFirstByte (void); -//void NixieDriverCheckDPPins (void); -//void NixieDriverProcessSendSecondByte (void); -#endif //NIXIE_DRIVER_PROCESS_INCLUDED \ No newline at end of file +#endif //NIXIE_DRIVER_PROCESS_INCLUDED diff --git a/Libraries/NixieDriver/nixie_driver_task.c b/Libraries/NixieDriver/nixie_driver_task.c index 18e554c..b968128 100644 --- a/Libraries/NixieDriver/nixie_driver_task.c +++ b/Libraries/NixieDriver/nixie_driver_task.c @@ -2,7 +2,6 @@ #include "nixie_driver_config.h" #include "nixie_driver_process.h" -// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" @@ -20,7 +19,7 @@ void NixieDriverInit ( void ) // ---------------------------------------------------------------------------- -// - , ? +// - нужна ли эта задача, если все работает в прерывании? // ---------------------------------------------------------------------------- void ProcessFSM_NixieDriver ( void ) { @@ -29,60 +28,9 @@ void ProcessFSM_NixieDriver ( void ) // ---------------------------------------------------------------------------- -// , NixieClockSimply +// Задача ОС, реализующая головную задачу программы NixieClockSimply // ---------------------------------------------------------------------------- void NixieDriver_Task ( void *pvParameters ) { while(1)ProcessFSM_NixieDriver (); - //vTaskDelete(NULL); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/NixieDriver/nixie_driver_task.h b/Libraries/NixieDriver/nixie_driver_task.h index 1c9fb39..71546cd 100644 --- a/Libraries/NixieDriver/nixie_driver_task.h +++ b/Libraries/NixieDriver/nixie_driver_task.h @@ -5,4 +5,4 @@ void NixieDriverInit ( void ); void NixieDriver_Task ( void *pvParameters ); -#endif //NIXIE_DRIVER_TASK_INCLUDED \ No newline at end of file +#endif //NIXIE_DRIVER_TASK_INCLUDED diff --git a/Libraries/Time/time.c b/Libraries/Time/time.c index ab5cbde..4159f44 100644 --- a/Libraries/Time/time.c +++ b/Libraries/Time/time.c @@ -158,19 +158,3 @@ static void RTC_TimeRegulate ( void ) /* Indicator for the RTC configuration */ RTC_WriteBackupRegister(RTC_BKP_DR0, BKP_VALUE); } - - - - - - - - - - - - - - - - diff --git a/Libraries/Time/time.h b/Libraries/Time/time.h index b6b611b..ea1f265 100644 --- a/Libraries/Time/time.h +++ b/Libraries/Time/time.h @@ -3,4 +3,4 @@ void TimeInit (void); -#endif // TIME_INCLUDED \ No newline at end of file +#endif // TIME_INCLUDED diff --git a/Project/src/main.c b/Project/src/main.c index d831fbf..41e5f86 100644 --- a/Project/src/main.c +++ b/Project/src/main.c @@ -1,6 +1,6 @@ /** ****************************************************************************** - * @file STM32L152_Ex01_3TKeys_EVAL\src\main.c + * @file STM32L152_Ex01_3TKeys_EVAL\src\main.c * @author MCD Application Team * @version V1.1.0 * @date 24-February-2014 @@ -16,34 +16,32 @@ * * http://www.st.com/software_license_agreement_liberty_v2 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** - */ + */ /* - . - . , - STM32CubeMX. + Здесь необходимо создать большой комментарий о характеристиках железа МК. Или +же лучше создать отдельный файл и сделать на него ссылку. Кстати, такой файл +создает программа STM32CubeMX. - , , - ( , , , ) +И вообще, нужно создать глобальную папку проекта, где будет лежать все по +полочкам ( схема, программа, текстовые файлы, документация и тд ) */ -//#define LED_DRIVER - -// NixieClock_v2, +// Это программа для версии NixieClock_v2, которая является модифицированной версией предыдущей // NixieLUT /* Includes ------------------------------------------------------------------*/ #include "time.h" #include "main.h" -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" @@ -69,26 +67,26 @@ /* Private defines -----------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ -// -// - ? +// Задаем размеры кучи для каждой задачи отдельно +// - как правильно определить необходимый минимум для кучи задачи? -#define STACK_SIZE_HEAD ( (unsigned short) 230 ) -#define STACK_SIZE_NIXIE_DRIVER ( (unsigned short) 80 ) -#define STACK_SIZE_BUTTON ( (unsigned short) 200 ) +#define STACK_SIZE_HEAD ( (unsigned short) 230 ) +#define STACK_SIZE_NIXIE_DRIVER ( (unsigned short) 80 ) +#define STACK_SIZE_BUTTON ( (unsigned short) 200 ) #define STACK_SIZE_LIGHT_SENSOR ( (unsigned short) 70 ) #ifdef LED_DRIVER -#define STACK_SIZE_LED_DRIVER ( (unsigned short) 70 ) +#define STACK_SIZE_LED_DRIVER ( (unsigned short) 70 ) #endif -#define STACK_SIZE_INDICATE_MODES ( (unsigned short) 250 ) +#define STACK_SIZE_INDICATE_MODES ( (unsigned short) 250 ) /* Private functions prototype ---------------------------------------------- */ // ---------------------------------------------------------------------------- -// +// Инициализация до создания задач // ---------------------------------------------------------------------------- void InitAll ( void ) -{ +{ InitLTimers (); NixieDriverInit (); LightSensorInit(); @@ -102,47 +100,44 @@ void InitAll ( void ) ButtonInit (); } +BaseType_t TaskSuccess = NULL; -BaseType_t TaskSuccess = NULL; - -// ------------------------------------------------------------- // +// Главный цикл ------------------------------------------------------------- // int main () -{ +{ InitAll (); - - // FreeRTOS ----------------------------------------------- // - - // !!! - // ! ( ) - - // , - // , . - // - - //BaseType_t TaskSuccess = NULL; - - TaskSuccess = xTaskCreate ( Head_Task, "Head_Task", STACK_SIZE_HEAD, NULL, tskIDLE_PRIORITY + 2, NULL ); + + // Создаем задачи FreeRTOS ----------------------------------------------- // + + // ВНИМАНИЕ !!! + // Необходимо проверять кучу при создании задачи! ( и очереди ) + + // Если в программе используется подключаемая библиотека, которая использует + // ОСРВ, то задача должна там и создаватья. То есть это нужно оформить в + // в виде специальной функции + + TaskSuccess = xTaskCreate ( Head_Task, "Head_Task", STACK_SIZE_HEAD, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); - - TaskSuccess = xTaskCreate ( IndicateModes_Task, "IndicateModes_Task", STACK_SIZE_INDICATE_MODES, NULL, tskIDLE_PRIORITY + 2, NULL ); + + TaskSuccess = xTaskCreate ( IndicateModes_Task, "IndicateModes_Task", STACK_SIZE_INDICATE_MODES, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); - TaskSuccess = xTaskCreate ( Button_Task, "Button_Task", STACK_SIZE_BUTTON, NULL, tskIDLE_PRIORITY + 2, NULL ); + TaskSuccess = xTaskCreate ( Button_Task, "Button_Task", STACK_SIZE_BUTTON, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); - TaskSuccess = xTaskCreate ( LightSensor_Task, "LightSensor_Task", STACK_SIZE_LIGHT_SENSOR, NULL, tskIDLE_PRIORITY + 2, NULL ); + TaskSuccess = xTaskCreate ( LightSensor_Task, "LightSensor_Task", STACK_SIZE_LIGHT_SENSOR, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); - - TaskSuccess = xTaskCreate ( NixieDriver_Task, "NixieDriver_Task", STACK_SIZE_NIXIE_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); + + TaskSuccess = xTaskCreate ( NixieDriver_Task, "NixieDriver_Task", STACK_SIZE_NIXIE_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); - + #ifdef LED_DRIVER - TaskSuccess = xTaskCreate ( LED_Driver_Task, "LED_Driver_Task", STACK_SIZE_LED_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); + TaskSuccess = xTaskCreate ( LED_Driver_Task, "LED_Driver_Task", STACK_SIZE_LED_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); configASSERT( TaskSuccess ); #endif - vTaskStartScheduler (); // ( ) - + vTaskStartScheduler (); // И запускаем диспетчер задач ( он же планировщик ) + } // end of main @@ -156,7 +151,7 @@ int main () * @retval None */ void assert_failed ( uint8_t* file, uint32_t line ) -{ +{ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ @@ -168,12 +163,9 @@ void assert_failed ( uint8_t* file, uint32_t line ) #endif -// - FreeRTOS ------------------------------------------------ // +// Специальные ф-ии FreeRTOS ------------------------------------------------ // void vApplicationMallocFailedHook ( void ) { for( ;; ); } void vApplicationStackOverflowHook ( TaskHandle_t pxTask, char *pcTaskName ) { for( ;; ); } void vApplicationIdleHook ( void ) { } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - - - diff --git a/Project/src/platform/stm32f0-gcc/freertos/FreeRTOSConfig.h b/Project/src/platform/stm32f0-gcc/freertos/FreeRTOSConfig.h index 0f23839..031cb01 100644 --- a/Project/src/platform/stm32f0-gcc/freertos/FreeRTOSConfig.h +++ b/Project/src/platform/stm32f0-gcc/freertos/FreeRTOSConfig.h @@ -1,5 +1,5 @@ /* - FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd. + FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd. All rights reserved VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. @@ -65,8 +65,8 @@ /* The following #error directive is to remind users that a batch file must be - * executed prior to this project being built. The batch file *cannot* be - * executed from within CCS4! Once it has been executed, re-open or refresh + * executed prior to this project being built. The batch file *cannot* be + * executed from within CCS4! Once it has been executed, re-open or refresh * the CCS4 project and remove the #error line below. */ //#error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above. @@ -87,68 +87,68 @@ * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ -#define configUSE_PREEMPTION 1 // 1 - , 0 - -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 0 -#define configCPU_CLOCK_HZ ( 48000000UL ) // tros 24000000UL -#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) -#define configMAX_PRIORITIES ( 5 ) - -#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) // trots, was 70 -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) // trots, was 10 // MEM_SIZE lwipopts.h - -#define configMAX_TASK_NAME_LEN ( 10 ) -#define configUSE_TRACE_FACILITY 0 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 0 -#define configGENERATE_RUN_TIME_STATS 0 -#define configCHECK_FOR_STACK_OVERFLOW 2 // trots was 2 -#define configUSE_RECURSIVE_MUTEXES 0 -#define configUSE_MALLOC_FAILED_HOOK 1 -#define configUSE_APPLICATION_TASK_TAG 0 -#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_PREEMPTION 1 // 1 - Вытесняющаяя многозадачность, 0 - Кооперативная +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( 48000000UL ) // tros было 24000000UL +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 5 ) + +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) // trots, was 70 +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 10 * 1024 ) ) // trots, was 10 // Уменьшил MEM_SIZE в файле lwipopts.h + +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configGENERATE_RUN_TIME_STATS 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 // trots was 2 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 0 /* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 // , ( ) +#define configUSE_CO_ROUTINES 0 // Чтобы использовать программные таймеры, нужно единичку (там прототипы содержатся) #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Software timer definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY ( 3 ) -#define configTIMER_QUEUE_LENGTH 5 -#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 3 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 /* Use the system definition, if there is one */ #ifdef __NVIC_PRIO_BITS - #define configPRIO_BITS __NVIC_PRIO_BITS + #define configPRIO_BITS __NVIC_PRIO_BITS #else - #define configPRIO_BITS 4 /* 15 priority levels */ + #define configPRIO_BITS 4 /* 15 priority levels */ #endif -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 11 +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 11 /* The lowest priority. */ -#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* Priority 5, or 95 as only the top four bits are implemented. */ /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) - -#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } - +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } + #define vPortSVCHandler SVCALL_handler #define xPortPendSVHandler PENDSV_handler #define xPortSysTickHandler SYSTICK_handler diff --git a/Project/src/stm32f0xx_it.c b/Project/src/stm32f0xx_it.c index b628455..9327bed 100644 --- a/Project/src/stm32f0xx_it.c +++ b/Project/src/stm32f0xx_it.c @@ -1,11 +1,11 @@ /** ****************************************************************************** - * @file Projects\Demonstration\stm32f0xx_it.c + * @file Projects\Demonstration\stm32f0xx_it.c * @author MCD Application Team * @version V1.0.0 * @date 17-January-2014 * @brief Main Interrupt Service Routines. - * This file provides template for all exceptions handler and + * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention @@ -18,14 +18,14 @@ * * http://www.st.com/software_license_agreement_liberty_v2 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** - */ + */ /* Includes ------------------------------------------------------------------*/ #include "stm32f0xx_it.h" @@ -86,7 +86,7 @@ void HardFault_Handler(void) * @brief This function handles SVCall exception. * @param None * @retval None - * @ portasm.s + * @ Используется в файле portasm.s */ //void SVC_Handler(void) //{ @@ -96,7 +96,7 @@ void HardFault_Handler(void) * @brief This function handles PendSVC exception. * @param None * @retval None - * @ portasm.s + * @ Используется в файле portasm.s */ //void PendSV_Handler(void) //{ @@ -121,16 +121,15 @@ void HardFault_Handler(void) /******************************************************************************/ // ---------------------------------------------------------------------------- -// 1 +// Обработчик прерывания таймера общего назначения для тиков в 1 мс // ---------------------------------------------------------------------------- void LTIMER_IRQHandler ( void ) { if ( TIM_GetITStatus ( LTIMER_TIMx, TIM_IT_Update ) != RESET ) - { + { TIM_ClearITPendingBit ( LTIMER_TIMx, TIM_IT_Update ); - + ProcessLTimers (); - //NIX_TEST_PIN_PB11_TOGGLE; } } @@ -138,16 +137,16 @@ void TIM17_handler(void) { LTIMER_IRQHandler(); } // ---------------------------------------------------------------------------- -// NixieDriver -// , -// Nixie +// Обработчик прерывания таймера для работы NixieDriver +// Это прерывание имеет самый высокий приоритет, чтобы обеспечить стабильную +// частоту динамической индикации ламп Nixie // ---------------------------------------------------------------------------- void NIX_DRIVER_TIM_IRQHandler ( void ) { if ( TIM_GetITStatus ( NIX_DRIVER_TIMx, TIM_IT_Update ) != RESET ) - { + { TIM_ClearITPendingBit ( NIX_DRIVER_TIMx, TIM_IT_Update ); - + ProcessNixieDriverFromISR (); } } @@ -156,14 +155,14 @@ void TIM16_handler(void) { NIX_DRIVER_TIM_IRQHandler(); } // ---------------------------------------------------------------------------- -// LED_Driver +// Обработчик прерывания таймера для работы LED_Driver // ---------------------------------------------------------------------------- void LED_TIM_IRQHandler ( void ) { if ( TIM_GetITStatus ( LED_TIMx, TIM_IT_Update ) != RESET ) - { + { TIM_ClearITPendingBit ( LED_TIMx, TIM_IT_Update ); - + LEDDriverProcessFromISR (); } } @@ -172,21 +171,20 @@ void TIM3_handler(void) { LED_TIM_IRQHandler(); } // ---------------------------------------------------------------------------- -// - , 2 -// ( ? -// ?) +// - поставить этому прерыванию наивысший приоритет, чтобы передавать 2 байта +// подряд гарантированно без промежутка времени (или не так важно? может ли +// между двумя байтами задержка повлиять на вывод данных на лампы?) // ---------------------------------------------------------------------------- -//static uint16_t empty_data; void NIX_SPIx_IRQHandler ( void ) -{ +{ /* SPI in Master Receiver mode--------------------------------------- */ if ( SPI_I2S_GetITStatus ( NIX_SPIx, SPI_I2S_IT_TXE ) == SET ) { - // , + // Обязательно надо считать, чтобы сбросить флаг SPI_I2S_ReceiveData16 ( NIX_SPIx ); SPI_I2S_ITConfig ( NIX_SPIx, SPI_I2S_IT_TXE, DISABLE ); - //NixieDriverCheckDPPins(); + //NixieDriverCheckDPPins(); NIX_DRIVER_SET_ST_PIN; } } @@ -199,13 +197,13 @@ void SPI1_handler(void) { NIX_SPIx_IRQHandler(); } // ---------------------------------------------------------------------------- #ifdef LED_DRIVER void LED_SPIx_IRQHandler ( void ) -{ +{ /* SPI in Master Receiver mode--------------------------------------- */ if ( SPI_I2S_GetITStatus ( LED_SPIx, SPI_I2S_IT_RXNE ) == SET ) { - //empty_data = SPI_I2S_ReceiveData16 ( LED_SPIx ); - // , - SPI_I2S_ReceiveData16 ( LED_SPIx ); + //empty_data = SPI_I2S_ReceiveData16 ( LED_SPIx ); + // Обязательно надо считать, чтобы сбросить флаг + SPI_I2S_ReceiveData16 ( LED_SPIx ); LED_ST_PIN_SET; } } -- cgit v1.2.3