summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-03-04 16:25:06 +0300
committerOxore <oxore@protonmail.com>2023-03-04 16:25:06 +0300
commit29c163578452d111c75c6582a8640cf9946bc6fb (patch)
tree09075f7715269017a9f1dd2bd9e7475148832eb8
parentf47ac9c074f097605b9a4ac8576da687b7ebffb9 (diff)
USART1 works
-rw-r--r--CMakeLists.txt2
-rw-r--r--Libraries/Head_Task/head_task.c2
-rw-r--r--Libraries/Indicate/indicate_modes_task.c204
-rw-r--r--Libraries/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_usart.c1
-rw-r--r--Project/src/main.c134
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