diff options
author | Oxore <oxore@protonmail.com> | 2023-03-04 16:25:06 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-03-04 16:25:06 +0300 |
commit | 29c163578452d111c75c6582a8640cf9946bc6fb (patch) | |
tree | 09075f7715269017a9f1dd2bd9e7475148832eb8 | |
parent | f47ac9c074f097605b9a4ac8576da687b7ebffb9 (diff) |
USART1 works
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Libraries/Head_Task/head_task.c | 2 | ||||
-rw-r--r-- | Libraries/Indicate/indicate_modes_task.c | 204 | ||||
-rw-r--r-- | Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c | 1 | ||||
-rw-r--r-- | Project/src/main.c | 134 |
5 files changed, 168 insertions, 175 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c8edd8a..40efc3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ set(nixie_clock_sources "Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_misc.c" "Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_adc.c" #"Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_i2c.c" - #"Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c" + "Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c" "Libraries/LightSensor/light_sensor_task.c" "Libraries/Time/time.c" "Project/src/main.c" diff --git a/Libraries/Head_Task/head_task.c b/Libraries/Head_Task/head_task.c index 3a1729a..db693f7 100644 --- a/Libraries/Head_Task/head_task.c +++ b/Libraries/Head_Task/head_task.c @@ -90,7 +90,7 @@ void MenuFunc_SimpleTimeView ( void ) // ---------------------------------------------------------------------------- void MenuFunc_AdjTime ( void ) { - static const uint32_t TIME_ADJ_OUT = 5000; //ms + static const uint32_t TIME_ADJ_OUT = 5000; //ms static IndicModesMsgBlink_t blink_data_struct; static ButtonCombName_t but_comb_name; diff --git a/Libraries/Indicate/indicate_modes_task.c b/Libraries/Indicate/indicate_modes_task.c index ef237b1..95d8da5 100644 --- a/Libraries/Indicate/indicate_modes_task.c +++ b/Libraries/Indicate/indicate_modes_task.c @@ -2,7 +2,7 @@ #include "nixie_driver_process.h" #include "ltimers.h" -// FreeRTOS includes +// FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "queue.h" @@ -10,11 +10,11 @@ typedef enum { - + STATE_BLINK_START_OFF, STATE_BLINK_TIMER_OFF, STATE_BLINK_TIMER_ON - + } IndicModesBlinkStates_t; static IndicModesBlinkStates_t state_blink = STATE_BLINK_TIMER_OFF; @@ -26,7 +26,7 @@ QueueHandle_t queue_data_to_blink_mode; extern QueueHandle_t queue_switch_indic_mode; -// +// Прототипы функций меню static void IndicMode_Standart ( void ); static void IndicMode_Blink ( void ); @@ -35,46 +35,46 @@ void DataCopyToStruct ( DataToIndicate_t *data_struct, uint8_t *data_arr ); void WriteOffByte ( uint8_t *array, uint8_t mask ); -// - +// Массив указателей на функции-меню typedef void ( *IndicModes_t ) ( void ); static const IndicModes_t IndicModes[MAX_INDIC_MODES] = { - + IndicMode_Standart, IndicMode_Blink - + }; // ---------------------------------------------------------------------------- -// +// // ---------------------------------------------------------------------------- void IndicateModesInit ( void ) { queue_data_to_indic = xQueueCreate ( 1, sizeof (DataToIndicate_t) ); configASSERT( queue_data_to_indic ); - + queue_data_to_blink_mode = xQueueCreate ( 1, sizeof (IndicModesMsgBlink_t) ); configASSERT( queue_data_to_indic ); } // ---------------------------------------------------------------------------- -// "", +// Режим инжикации "Стандартный", когда время выводится без эффектов // ---------------------------------------------------------------------------- static void IndicMode_Standart ( void ) { ; - - // ! - // - // , . - // - - // - - // , - + + // Важное замечание! + // При передаче указателя массива через очередь ОС нужно передавать весь + // массив целиком, чтобы полученный экземпляр данных не менялся. Для передачи + // шести байт можно сделать небольшую структуру + + // - тут проверяем сообщение из очереди ОС на обновление выводимых данных + // и если они изменились, то отправляем их в модуль Никси + static DataToIndicate_t data_struct; - + if ( pdPASS == xQueueReceive ( queue_data_to_indic, &data_struct, 0 ) ) { NixieDriver_SendValue2 ( data_struct ); @@ -83,73 +83,71 @@ static void IndicMode_Standart ( void ) // ---------------------------------------------------------------------------- -// "" -// , , -// -, , -// . , . -// . . -// -// - +// Режим "моргания" индикаторов +// В сообщении из очереди принимаются данные, которые нужно вывести, и +// маска-байт, которая соответствует номеру индикатора, который должен +// моргать. Если байт установлен, то индикатор моргает. Могут моргать сразу +// несколько индикаторов. Моргание синхронное. +// Останавливать задачу в этих функция нельзя +// - тут лучше было бы сделать ожидание завершения фазы моргания // ---------------------------------------------------------------------------- static void IndicMode_Blink ( void ) { ; - // - , - // , . - // "" . - // "" - -//#if 0 + // - принимаем сообщение с данными и маской, и на номер установленного + // байта записываем пустой символ, запоминая его. Затем запускаем таймер + // и отправляем массив данных с "дыркой" на вывод. После таймера + // записываем сохраненное значение и выводим с таймером "чистые" значения static const uint32_t TIME_BLINK_OFF = 250; // ms static const uint32_t TIME_BLINK_ON = 250; // ms - + static DataToIndicate_t data_struct; static IndicModesMsgBlink_t data_new_struct; - + static uint8_t indic_data_off [MAX_TUBES]; static uint8_t prev_indic_data_off [MAX_TUBES]; static uint8_t new_indic_data_off [MAX_TUBES]; - + static uint8_t prev_mask_byte = 0; static uint8_t is_blink_tube = 0; - - + + if ( pdPASS == xQueueReceive ( queue_data_to_blink_mode, &data_new_struct, 0 ) ) { DataCopyToArray ( &new_indic_data_off[0], &data_new_struct.data ); - + DataCopyToArray ( &indic_data_off[0], &data_new_struct.data ); - WriteOffByte ( &indic_data_off[0], data_new_struct.mask_byte ); // - DataCopyToStruct ( &data_struct, &indic_data_off[0] ); - - // , - // + WriteOffByte ( &indic_data_off[0], data_new_struct.mask_byte ); // теперь можно вместо пустой цифры отправлять точку + DataCopyToStruct ( &data_struct, &indic_data_off[0] ); + + // Если изменилась только маска байта, то начинаем моргать с отрицательной + // фазы if ( prev_mask_byte != data_new_struct.mask_byte ) - { + { prev_mask_byte = data_new_struct.mask_byte; NixieDriver_SendValue2 ( data_struct ); StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF ); state_blink = STATE_BLINK_TIMER_OFF; } - else - { - // , - // + else + { + // А если изменились данные моргающей лампы, то начинать с + // положительной фазы for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ ) { - if ( (prev_indic_data_off[tube_num] != new_indic_data_off[tube_num]) )// ? - { - if ( data_new_struct.mask_byte & ( 32 >> tube_num ) ) // ? + if ( (prev_indic_data_off[tube_num] != new_indic_data_off[tube_num]) )// В этой лампе данные не равны? + { + if ( data_new_struct.mask_byte & ( 32 >> tube_num ) ) // И эта лампа моргающая? { is_blink_tube = 1; break; } } } // end for - + if ( is_blink_tube == 1 ) - { + { NixieDriver_SendValue2 ( data_new_struct.data ); StartLTimer ( LTIMER_INDIC_MODE_BLINK_ON ); state_blink = STATE_BLINK_TIMER_ON; @@ -167,55 +165,34 @@ static void IndicMode_Blink ( void ) } } } - + DataCopyToArray ( &prev_indic_data_off[0], &data_new_struct.data ); } - + switch ( state_blink ) { -// case STATE_BLINK_START_OFF: -// -// for ( uint8_t tube_num = 0; tube_num < MAX_TUBES; tube_num++ ) -// { -// if ( data_new_struct.mask_byte & ( 32 >> tube_num ) ) -// { -// indic_data_off [tube_num] = TUBE_EMPTY_VALUE; // - 10 TUBE_DIGIT_EMPTY -// } -// } -// -// DataCopyToStruct ( &data_struct, &indic_data_off[0] ); -// -// NixieDriver_SendValue2 ( data_struct ); -// -// state_blink = STATE_BLINK_TIMER_OFF; -// StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF ); -// -// break; - case STATE_BLINK_TIMER_OFF: - + if ( GetLTimer ( LTIMER_INDIC_MODE_BLINK_OFF ) >= TIME_BLINK_OFF ) { NixieDriver_SendValue2 ( data_new_struct.data ); state_blink = STATE_BLINK_TIMER_ON; StartLTimer ( LTIMER_INDIC_MODE_BLINK_ON ); } - + break; - + case STATE_BLINK_TIMER_ON: - + if ( GetLTimer ( LTIMER_INDIC_MODE_BLINK_ON ) >= TIME_BLINK_ON ) { NixieDriver_SendValue2 ( data_struct ); state_blink = STATE_BLINK_TIMER_OFF; StartLTimer ( LTIMER_INDIC_MODE_BLINK_OFF ); } - + break; } - -//#endif } @@ -237,7 +214,7 @@ void DataCopyToStruct ( DataToIndicate_t *data_struct, uint8_t *data_arr ) // // ---------------------------------------------------------------------------- void DataCopyToArray ( uint8_t *data_arr, DataToIndicate_t *data_struct ) -{ +{ data_arr[0] = data_struct->indic_1; data_arr[1] = data_struct->indic_2; data_arr[2] = data_struct->indic_3; @@ -248,7 +225,7 @@ void DataCopyToArray ( uint8_t *data_arr, DataToIndicate_t *data_struct ) // ---------------------------------------------------------------------------- -// - "" +// Ф-я записи в массив "темной" лампы // ---------------------------------------------------------------------------- void WriteOffByte ( uint8_t *array, uint8_t mask ) { @@ -256,76 +233,53 @@ void WriteOffByte ( uint8_t *array, uint8_t mask ) { if ( mask & ( 32 >> tube_num ) ) { - //array [tube_num] = TUBE_EMPTY_VALUE; // - 10 TUBE_DIGIT_EMPTY - // - array [tube_num] = 12; // tube_digits [MAX_DIGITS] + //array [tube_num] = TUBE_EMPTY_VALUE; // - тут цифра 10 это TUBE_DIGIT_EMPTY + // Можно поробовать здесь отправлять точку вместо пустого символа + array [tube_num] = 12; // Шлем номер значения цифры из массива tube_digits [MAX_DIGITS] } } } // ---------------------------------------------------------------------------- -// (, .) +// Режимы работы индикации (моргать, плавно переключаться и тд.) // ---------------------------------------------------------------------------- void ProcessFSM_IndicateModes ( void ) { - // - - // - // , , - // , , - // . - + // - тут нужно принимать сообщения из модуля Меню и переходить в нужный режим + // индикации + // При этом нужно помнить, что режим индикации может иметь много состояний, + // поэтому нужно сбрасывать это состояние и, возможно, другие переменные + // перед переключением в другой режим. + IndicModesNums_t indic_mode_num; - + if ( pdPASS == xQueueReceive ( queue_switch_indic_mode, &indic_mode_num, 0 ) ) - { - // + { + // Сначала переведем состояние отключаемого режима в начальное switch ( curr_indic_mode ) { case INDIC_MODE_STANDART: break; - + case INDIC_MODE_BLINK: state_blink = STATE_BLINK_TIMER_OFF; break; } - + curr_indic_mode = indic_mode_num; } - + IndicModes [curr_indic_mode](); taskYIELD(); } // ---------------------------------------------------------------------------- -// , NixieClockSimply +// Задача ОС, реализующая головную задачу программы NixieClockSimply // ---------------------------------------------------------------------------- void IndicateModes_Task ( void *pvParameters ) -{ +{ while(1)ProcessFSM_IndicateModes (); - //vTaskDelete(NULL); } - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c b/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c index 43392f0..7bb2f71 100644 --- a/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c +++ b/Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c @@ -80,6 +80,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32f0xx_usart.h" #include "stm32f0xx_rcc.h" +#include "stm32f0xx_conf.h" /** @addtogroup STM32F0xx_StdPeriph_Driver * @{ diff --git a/Project/src/main.c b/Project/src/main.c index bc9c4ac..2132d87 100644 --- a/Project/src/main.c +++ b/Project/src/main.c @@ -61,6 +61,7 @@ #include "indicate_modes_task.h" #include "tsl_user.h" #include "time.h" +#include "stm32f0xx_usart.h" /* Private typedefs ----------------------------------------------------------*/ @@ -70,75 +71,112 @@ // Задаем размеры кучи для каждой задачи отдельно // - как правильно определить необходимый минимум для кучи задачи? -#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 ) +#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 ---------------------------------------------- */ +static void USART1Init(void) +{ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_Init(GPIOA, &GPIO_InitStructure); + USART_InitTypeDef usart1_init = {0}; + usart1_init.USART_BaudRate = 115200; + usart1_init.USART_WordLength = USART_WordLength_8b; + usart1_init.USART_StopBits = USART_StopBits_1; + usart1_init.USART_Parity = USART_Parity_No; + usart1_init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + usart1_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_Init(USART1, &usart1_init); + USART_Cmd(USART1, ENABLE); +} // ---------------------------------------------------------------------------- // Инициализация до создания задач // ---------------------------------------------------------------------------- void InitAll ( void ) { - SystemInit(); - InitLTimers (); - NixieDriverInit (); - LightSensorInit(); + SystemInit(); + USART1Init(); + InitLTimers(); + LightSensorInit(); +#if 0 + NixieDriverInit(); + HeadTaskInit(); + IndicateModesInit(); +#endif #ifdef LED_DRIVER - LED_DriverInit (); + LED_DriverInit(); #endif - TSL_user_Init (); - TimeInit (); - HeadTaskInit (); - IndicateModesInit (); - ButtonInit (); + TSL_user_Init(); + TimeInit(); + ButtonInit(); } -BaseType_t TaskSuccess = NULL; +static void TestUart(void *arg) +{ + (void) arg; + while (1) { + if (USART1->ISR & USART_ISR_FE) { + USART1->ICR &= USART_ICR_FECF; + } + if (USART1->ISR & USART_ISR_RXNE) { + const uint16_t data = USART_ReceiveData(USART1); + USART_SendData(USART1, data); + } + } +} + +BaseType_t TaskSuccess; // Главный цикл ------------------------------------------------------------- // int main () { - InitAll (); - - // Создаем задачи 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 ); - configASSERT( TaskSuccess ); - - 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 ); - configASSERT( TaskSuccess ); - - TaskSuccess = xTaskCreate ( NixieDriver_Task, "NixieDriver_Task", STACK_SIZE_NIXIE_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); - configASSERT( TaskSuccess ); - + InitAll (); + // Создаем задачи FreeRTOS ----------------------------------------------- // + + // ВНИМАНИЕ !!! + // Необходимо проверять кучу при создании задачи! ( и очереди ) + + // Если в программе используется подключаемая библиотека, которая использует + // ОСРВ, то задача должна там и создаватья. То есть это нужно оформить в + // в виде специальной функции + 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); + configASSERT(TaskSuccess); +#if 0 + 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); + configASSERT(TaskSuccess); + TaskSuccess = xTaskCreate(NixieDriver_Task, "NixieDriver_Task", STACK_SIZE_NIXIE_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL); + configASSERT(TaskSuccess); +#endif #ifdef LED_DRIVER - TaskSuccess = xTaskCreate ( LED_Driver_Task, "LED_Driver_Task", STACK_SIZE_LED_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL ); - configASSERT( TaskSuccess ); + TaskSuccess = xTaskCreate(LED_Driver_Task, "LED_Driver_Task", STACK_SIZE_LED_DRIVER, NULL, tskIDLE_PRIORITY + 2, NULL); + configASSERT(TaskSuccess); #endif - - vTaskStartScheduler (); // И запускаем диспетчер задач ( он же планировщик ) - + TaskSuccess = xTaskCreate(TestUart, "TestUart", 200, NULL, tskIDLE_PRIORITY + 2, NULL); + configASSERT(TaskSuccess); + vTaskStartScheduler(); // И запускаем диспетчер задач ( он же планировщик ) } // end of main |