Browse Source

First attempt ofr v.3 of hardware.

Vladimir N. Shilov 3 years ago
parent
commit
8becc3694b
8 changed files with 419 additions and 175 deletions
  1. 73 47
      Inc/main.h
  2. 0 1
      Inc/stm32g0xx_it.h
  3. 5 0
      MDK-ARM/MNC-IN12x5.uvprojx
  4. 9 2
      MNC-IN12x5.cbp
  5. 1 2
      Makefile
  6. 22 0
      ReadMe.txt
  7. 255 108
      Src/main.c
  8. 54 15
      Src/stm32g0xx_it.c

+ 73 - 47
Inc/main.h

@@ -28,8 +28,8 @@ extern "C" {
 #endif
 
 /* Includes ------------------------------------------------------------------*/
-#include "stm32g0xx_ll_dma.h"
 #include "stm32g0xx.h"
+#include "stm32g0xx_ll_dma.h"
 #include "stm32g0xx_ll_i2c.h"
 #include "stm32g0xx_ll_rcc.h"
 #include "stm32g0xx_ll_bus.h"
@@ -78,7 +78,12 @@ volatile struct {
   uint32_t I2C_TX_Err:  1;
   uint32_t I2C_RX_Err:  1;
   uint32_t BME280:      1;
-  uint32_t _reserv:    25;
+  uint32_t Blink_1:     1;
+  uint32_t Blink_2:     1;
+  uint32_t Blink_3:     1;
+  uint32_t Blink_4:     1;
+  uint32_t Blink_5:     1;
+  uint32_t _reserv:    20;
 } Flag;
 
 typedef union {
@@ -127,16 +132,27 @@ typedef union {
 #define TUBE_PWR_ON   GPIOA->BRR = 0x10
 #define TUBE_PWR_OFF  GPIOA->BSRR = 0x10
 
+#define TUBE_A_ON     TIM1->CCER |= (TIM_CCER_CC1E)
+#define TUBE_B_ON     TIM3->CCER |= (TIM_CCER_CC4E)
+#define TUBE_C_ON     TIM3->CCER |= (TIM_CCER_CC3E)
+#define TUBE_D_ON     TIM3->CCER |= (TIM_CCER_CC2E)
+#define TUBE_E_ON     TIM3->CCER |= (TIM_CCER_CC1E)
+
+#define TUBE_A_OFF    TIM1->CCER &= ~(TIM_CCER_CC1E)
+#define TUBE_B_OFF    TIM3->CCER &= ~(TIM_CCER_CC4E)
+#define TUBE_C_OFF    TIM3->CCER &= ~(TIM_CCER_CC3E)
+#define TUBE_D_OFF    TIM3->CCER &= ~(TIM_CCER_CC2E)
+#define TUBE_E_OFF    TIM3->CCER &= ~(TIM_CCER_CC1E)
+
 #define IN15_P        GPIOA->BSRR = 0x1
 #define IN15_Plus     GPIOA->BSRR = 0x2
 #define IN15_Minus    GPIOA->BSRR = 0x4
 #define IN15_Percent  GPIOA->BSRR = 0x8
 #define IN15_OFF      GPIOA->BRR = 0xF
 
-#define COLOR_R(x)          TIM3->CCR1 = x
-#define COLOR_B(x)          TIM3->CCR2 = x
-#define COLOR_G(x)          TIM3->CCR3 = x
-#define COLOR_RGB(r, g, b)  TIM3->CCR1 = r; TIM3->CCR3 = g; TIM3->CCR2 = b
+#define COLOR_R(x)          TIM1->CCR2 = x
+#define COLOR_B(x)          TIM1->CCR3 = x
+#define COLOR_G(x)          TIM1->CCR4 = x
 
 /* USER CODE END EM */
 
@@ -148,58 +164,68 @@ void Error_Handler(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
-#define LC0_Pin LL_GPIO_PIN_0
+#define BTN1_GPIO_Port GPIOB
+#define BTN1_Pin LL_GPIO_PIN_2
+#define BTN2_GPIO_Port GPIOA
+#define BTN2_Pin LL_GPIO_PIN_12
+#define BTN3_GPIO_Port GPIOB
+#define BTN3_Pin LL_GPIO_PIN_4
+#define BTN4_GPIO_Port GPIOA
+#define BTN4_Pin LL_GPIO_PIN_5
+#define IRQ_EXTI_IRQn EXTI4_15_IRQn
+#define IRQ_GPIO_Port GPIOC
+#define IRQ_Pin LL_GPIO_PIN_14
+#define Latch_GPIO_Port GPIOC
+#define Latch_Pin LL_GPIO_PIN_6
 #define LC0_GPIO_Port GPIOA
-#define LC1_Pin LL_GPIO_PIN_1
+#define LC0_Pin LL_GPIO_PIN_0
 #define LC1_GPIO_Port GPIOA
-#define LC2_Pin LL_GPIO_PIN_2
+#define LC1_Pin LL_GPIO_PIN_1
 #define LC2_GPIO_Port GPIOA
-#define LC3_Pin LL_GPIO_PIN_3
+#define LC2_Pin LL_GPIO_PIN_2
 #define LC3_GPIO_Port GPIOA
-#define SHDN_Pin LL_GPIO_PIN_4
-#define SHDN_GPIO_Port GPIOA
-#define PWM_R_Pin LL_GPIO_PIN_6
-#define PWM_R_GPIO_Port GPIOA
-#define PWM_G_Pin LL_GPIO_PIN_7
+#define LC3_Pin LL_GPIO_PIN_3
+#define PWM_1_GPIO_Port GPIOA
+#define PWM_1_Pin LL_GPIO_PIN_8
+#define PWM_2_GPIO_Port GPIOB
+#define PWM_2_Pin LL_GPIO_PIN_1
+#define PWM_3_GPIO_Port GPIOB
+#define PWM_3_Pin LL_GPIO_PIN_0
+#define PWM_4_GPIO_Port GPIOA
+#define PWM_4_Pin LL_GPIO_PIN_7
+#define PWM_5_GPIO_Port GPIOA
+#define PWM_5_Pin LL_GPIO_PIN_6
+#define PWM_B_GPIO_Port GPIOA
+#define PWM_B_Pin LL_GPIO_PIN_10
 #define PWM_G_GPIO_Port GPIOA
-#define PWM_B_Pin LL_GPIO_PIN_0
-#define PWM_B_GPIO_Port GPIOB
-#define PWM_T_Pin LL_GPIO_PIN_1
-#define PWM_T_GPIO_Port GPIOB
-#define BTN1_Pin LL_GPIO_PIN_8
-#define BTN1_GPIO_Port GPIOA
-#define BTN2_Pin LL_GPIO_PIN_9
-#define BTN2_GPIO_Port GPIOA
-#define BTN3_Pin LL_GPIO_PIN_10
-#define BTN3_GPIO_Port GPIOA
-#define BTN4_Pin LL_GPIO_PIN_11
-#define BTN4_GPIO_Port GPIOA
-#define Latch_Pin LL_GPIO_PIN_6
-#define Latch_GPIO_Port GPIOC
-#define IRQ_Pin LL_GPIO_PIN_14
-#define IRQ_GPIO_Port GPIOC
-#define IRQ_EXTI_IRQn EXTI4_15_IRQn
-#define UART_EN_Pin LL_GPIO_PIN_15
+#define PWM_G_Pin LL_GPIO_PIN_11
+#define PWM_R_GPIO_Port GPIOA
+#define PWM_R_Pin LL_GPIO_PIN_9
+#define SHDN_GPIO_Port GPIOA
+#define SHDN_Pin LL_GPIO_PIN_4
+#define SWCLK_GPIO_Port GPIOA
+#define SWCLK_Pin LL_GPIO_PIN_14
+#define SWDIO_GPIO_Port GPIOA
+#define SWDIO_Pin LL_GPIO_PIN_13
 #define UART_EN_GPIO_Port GPIOC
-#define UART_ST_Pin LL_GPIO_PIN_15
+#define UART_EN_Pin LL_GPIO_PIN_15
 #define UART_ST_GPIO_Port GPIOA
+#define UART_ST_Pin LL_GPIO_PIN_15
 /* USER CODE BEGIN Private defines */
-#define USE_FULL_LL_DRIVER 1
 
 /* BTNs */
 #define BTN_NUM         4
-#define BTN1_PIN        GPIO_IDR_ID8
-#define BTN2_PIN        GPIO_IDR_ID9
-#define BTN3_PIN        GPIO_IDR_ID10
-#define BTN4_PIN        GPIO_IDR_ID11
-#define BTN_PORT        GPIOA
-#define BTN_PINS        (BTN1_PIN | BTN2_PIN | BTN3_PIN | BTN4_PIN)
-#define BTN1_STATE      (BTN_PORT->IDR & BTN1_PIN)
-#define BTN2_STATE      (BTN_PORT->IDR & BTN2_PIN)
-#define BTN3_STATE      (BTN_PORT->IDR & BTN3_PIN)
-#define BTN4_STATE      (BTN_PORT->IDR & BTN4_PIN)
-#define BTNS_STATE      (BTN_PORT->IDR & BTN_PINS)
-#define BTN_STATE(pin)  (BTN_PORT->IDR & pin)
+#define BTN1_PIN        GPIO_IDR_ID2
+#define BTN2_PIN        GPIO_IDR_ID12
+#define BTN3_PIN        GPIO_IDR_ID4
+#define BTN4_PIN        GPIO_IDR_ID5
+#define BTN1_STATE      (BTN1_GPIO_Port->IDR & BTN1_PIN)
+#define BTN2_STATE      (BTN2_GPIO_Port->IDR & BTN2_PIN)
+#define BTN3_STATE      (BTN3_GPIO_Port->IDR & BTN3_PIN)
+#define BTN4_STATE      (BTN4_GPIO_Port->IDR & BTN4_PIN)
+#define BTNS1_STATE     (GPIOB->IDR & (BTN1_PIN | BTN3_PIN))
+#define BTNS2_STATE     (GPIOA->IDR & (BTN2_PIN | BTN4_PIN))
+#define BTNS_STATE      (BTNS1_STATE | BTNS2_STATE)
 /* time constant in ms */
 #define BTN_SCAN_PERIOD    10
 #define BTN_SCAN_PAUSE     200

+ 0 - 1
Inc/stm32g0xx_it.h

@@ -52,7 +52,6 @@ void HardFault_Handler(void);
 void SVC_Handler(void);
 void PendSV_Handler(void);
 void SysTick_Handler(void);
-void RCC_IRQHandler(void);
 void EXTI4_15_IRQHandler(void);
 void DMA1_Channel1_IRQHandler(void);
 void DMA1_Channel2_3_IRQHandler(void);

+ 5 - 0
MDK-ARM/MNC-IN12x5.uvprojx

@@ -509,6 +509,11 @@
     <Layers>
       <Layer>
         <LayName>&lt;Project Info&gt;</LayName>
+        <LayDesc></LayDesc>
+        <LayUrl></LayUrl>
+        <LayKeys></LayKeys>
+        <LayCat></LayCat>
+        <LayLic></LayLic>
         <LayTarg>0</LayTarg>
         <LayPrjMark>1</LayPrjMark>
       </Layer>

+ 9 - 2
MNC-IN12x5.cbp

@@ -25,17 +25,24 @@
 					<Add directory="Drivers/CMSIS/Include" />
 					<Add directory="Drivers/CMSIS/Device/ST/STM32G0xx/Include" />
 				</Compiler>
+				<Environment>
+					<Variable name="USE_FULL_LL_DRIVER" value="1" />
+				</Environment>
 			</Target>
+			<Environment>
+				<Variable name="USE_FULL_LL_DRIVER" value="1" />
+			</Environment>
 		</Build>
 		<Compiler>
+			<Add option="-mcpu=arm7tdmi" />
+			<Add option="-O2" />
 			<Add option="-Wall" />
 			<Add option="-g" />
-			<Add option="-O2" />
 			<Add option="-fno-common" />
-			<Add option="-mcpu=arm7tdmi" />
 			<Add option="-DEK_AT91SAM7A3" />
 			<Add option="-D__NO_CTOR_DTOR_SUPPORT__" />
 			<Add option="-DUSE_IRQ" />
+			<Add option="-DUSE_FULL_LL_DRIVER" />
 			<Add directory="src" />
 			<Add directory="h" />
 		</Compiler>

+ 1 - 2
Makefile

@@ -154,8 +154,7 @@ LDSCRIPT = Drivers/STM32G030K8Tx_FLASH.ld
 # libraries
 LIBS = -lc -lm -lnosys 
 LIBDIR = 
-LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref
-LDFLAGS += -Wl,--gc-sections
+LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
 
 # default action: build all
 all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

+ 22 - 0
ReadMe.txt

@@ -32,3 +32,25 @@ MCU - STM32G030K8.
 Закончил третю версии схемы и платы - с индивидуальным управлением анодами 
 ламп. Опыты показали, что писк на частоте 100 Гц отсутвует, на частотах 200 и 
 больше - появляется.
+---
+30.09.2021
+
+Правка софта под третью версию железа.
+
+Таймеры 1 и 3 пока 100 Гц.
+PWM:
+ TIM1_CH1 - PWM_1
+ TIM1_CH2 - PWM_R
+ TIM1_CH3 - PWM_B
+ TIM1_CH4 - PWM_G
+ TIM3_CH1 - PWM_5
+ TIM3_CH2 - PWM_4
+ TIM3_CH3 - PWM_3
+ TIM3_CH4 - PWM_2
+
+Таймер 14 попробую использовать для "блинка" - 0.75 сек вкл, 0.25 сек выкл.
+
+может стоит Т14 пинать по прерыванию в начале каждой секунды в режме one 
+pulse mode? тогда будет синхронизация со сменой секунд. пока оставлю в 
+качестве идеи.
+

+ 255 - 108
Src/main.c

@@ -94,6 +94,7 @@ static void MX_GPIO_Init(void);
 static void MX_DMA_Init(void);
 static void MX_I2C1_Init(void);
 static void MX_SPI1_Init(void);
+static void MX_TIM1_Init(void);
 static void MX_TIM3_Init(void);
 static void MX_TIM14_Init(void);
 static void MX_TIM16_Init(void);
@@ -108,6 +109,7 @@ int8_t i2c_check_err(void);
 static void sensorStartMeasure(void);
 static void sensorGetData(void);
 static void btnProcess(void);
+static void Color_RGB(uint8_t r, uint8_t g, uint8_t b);
 /* USER CODE END PFP */
 
 /* Private user code ---------------------------------------------------------*/
@@ -157,6 +159,7 @@ int main(void)
   MX_DMA_Init();
   MX_I2C1_Init();
   MX_SPI1_Init();
+  MX_TIM1_Init();
   MX_TIM3_Init();
   MX_TIM14_Init();
   MX_TIM16_Init();
@@ -168,19 +171,26 @@ int main(void)
   /* Initialize Event State Machine */
   ES_Init(stShowTime);
 
-  /* Start RGB PWM */
-  LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH1);
-  LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH2);
-  LL_TIM_CC_EnableChannel(TIM3, LL_TIM_CHANNEL_CH3);
-  LL_TIM_EnableCounter(TIM3);
-
-  /* Start Tube PWR PWM */
-  LL_TIM_CC_EnableChannel(TIM14, LL_TIM_CHANNEL_CH1);
-  LL_TIM_EnableCounter(TIM14);
-
   /* Enable tube power */
   TUBE_PWR_ON;
 
+  /** Start RGB & Tube Power PWM */
+  /* LL_TIM_CC_EnableChannel */
+  TIM1->CCER |= (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E);
+  /* LL_TIM_EnableCounter */
+  TIM1->CR1 |= TIM_CR1_CEN;
+
+  TIM3->CCER |= (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E);
+  TIM3->CR1 |= TIM_CR1_CEN;
+
+  /* Start Blink Engine */
+  Flag.Blink_1 = 0;
+  Flag.Blink_2 = 0;
+  Flag.Blink_3 = 0;
+  Flag.Blink_4 = 0;
+  Flag.Blink_5 = 0;
+  TIM14->CR1 |= TIM_CR1_CEN;
+
   /* Set DMA source and destination addresses. */
   /* Source: Address of the SPI buffer. */
   DMA1_Channel1->CMAR = (uint32_t)&tubesBuffer;
@@ -208,16 +218,7 @@ int main(void)
   rsltSensor = bme280_init(&SensorDev);
   if (rsltSensor == BME280_OK) {
     Flag.BME280 = 1;
-  }
-
-  /* Set tasks for Sheduler */
-  RTOS_SetTask(btnProcess, 1, BTN_SCAN_PERIOD);
-  /* USER CODE END 2 */
 
-  /* USER CODE BEGIN WHILE */
-  RTC_ReadAll(&Clock);
-
-  if (Flag.BME280 != 0) {
     /* BME280 Recommended mode of operation: Indoor navigation */
     SensorDev.settings.osr_h = BME280_OVERSAMPLING_1X;
     SensorDev.settings.osr_p = BME280_OVERSAMPLING_16X;
@@ -228,8 +229,16 @@ int main(void)
     RTOS_SetTask(sensorGetData, 603, 1000);
   }
 
+
+  /* Set tasks for Sheduler */
+  RTOS_SetTask(btnProcess, 1, BTN_SCAN_PERIOD);
+  /* USER CODE END 2 */
+
+  /* USER CODE BEGIN WHILE */
+  RTC_ReadAll(&Clock);
+
   es_event_t event = eventNull;
-  COLOR_RGB(0xFF, 0x12, 0x0); // Nixie color. FF7E00 or FFBF00
+  Color_RGB(0xFF, 0x12, 0x0); // Nixie color. FF7E00 or FFBF00
   showTime();
 
   /* Infinite loop */
@@ -658,6 +667,119 @@ static void MX_SPI1_Init(void)
 
 }
 
+/**
+  * @brief TIM1 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_TIM1_Init(void)
+{
+
+  /* USER CODE BEGIN TIM1_Init 0 */
+
+  /* USER CODE END TIM1_Init 0 */
+
+  LL_TIM_InitTypeDef TIM_InitStruct = {0};
+  LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
+  LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0};
+
+  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+  /* Peripheral clock enable */
+  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
+
+  /* USER CODE BEGIN TIM1_Init 1 */
+
+  /* USER CODE END TIM1_Init 1 */
+  TIM_InitStruct.Prescaler = (240 - 1);
+  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
+  TIM_InitStruct.Autoreload = 1000;
+  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
+  TIM_InitStruct.RepetitionCounter = 0;
+  LL_TIM_Init(TIM1, &TIM_InitStruct);
+  LL_TIM_EnableARRPreload(TIM1);
+  LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL);
+  LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
+  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
+  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
+  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
+  TIM_OC_InitStruct.CompareValue = 500;
+  TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
+  TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
+  TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
+  TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
+  LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
+  LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1);
+  LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH2);
+  LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
+  LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH2);
+  LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3);
+  LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct);
+  LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3);
+  LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH4);
+  LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
+  LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH4);
+  LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_RESET);
+  LL_TIM_SetTriggerOutput2(TIM1, LL_TIM_TRGO2_RESET);
+  LL_TIM_DisableMasterSlaveMode(TIM1);
+  TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
+  TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
+  TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
+  TIM_BDTRInitStruct.DeadTime = 0;
+  TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE;
+  TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
+  TIM_BDTRInitStruct.BreakFilter = LL_TIM_BREAK_FILTER_FDIV1;
+  TIM_BDTRInitStruct.BreakAFMode = LL_TIM_BREAK_AFMODE_INPUT;
+  TIM_BDTRInitStruct.Break2State = LL_TIM_BREAK2_DISABLE;
+  TIM_BDTRInitStruct.Break2Polarity = LL_TIM_BREAK2_POLARITY_HIGH;
+  TIM_BDTRInitStruct.Break2Filter = LL_TIM_BREAK2_FILTER_FDIV1;
+  TIM_BDTRInitStruct.Break2AFMode = LL_TIM_BREAK_AFMODE_INPUT;
+  TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
+  LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct);
+  /* USER CODE BEGIN TIM1_Init 2 */
+
+  /* USER CODE END TIM1_Init 2 */
+  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
+  /**TIM1 GPIO Configuration
+  PA8   ------> TIM1_CH1
+  PA9   ------> TIM1_CH2
+  PA10   ------> TIM1_CH3
+  PA11 [PA9]   ------> TIM1_CH4
+  */
+  GPIO_InitStruct.Pin = PWM_1_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+  GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
+  LL_GPIO_Init(PWM_1_GPIO_Port, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = PWM_R_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+  GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
+  LL_GPIO_Init(PWM_R_GPIO_Port, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = PWM_B_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+  GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
+  LL_GPIO_Init(PWM_B_GPIO_Port, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = PWM_G_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+  GPIO_InitStruct.Alternate = LL_GPIO_AF_2;
+  LL_GPIO_Init(PWM_G_GPIO_Port, &GPIO_InitStruct);
+
+}
+
 /**
   * @brief TIM3 Initialization Function
   * @param None
@@ -681,9 +803,9 @@ static void MX_TIM3_Init(void)
   /* USER CODE BEGIN TIM3_Init 1 */
 
   /* USER CODE END TIM3_Init 1 */
-  TIM_InitStruct.Prescaler = 94;
+  TIM_InitStruct.Prescaler = (240 - 1);
   TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
-  TIM_InitStruct.Autoreload = 255;
+  TIM_InitStruct.Autoreload = 1000;
   TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
   LL_TIM_Init(TIM3, &TIM_InitStruct);
   LL_TIM_EnableARRPreload(TIM3);
@@ -691,20 +813,19 @@ static void MX_TIM3_Init(void)
   TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
   TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
   TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
-  TIM_OC_InitStruct.CompareValue = 25;
+  TIM_OC_InitStruct.CompareValue = 500;
   TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
   LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
   LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH1);
   LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH2);
-  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
-  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
   LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct);
   LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH2);
   LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH3);
-  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
-  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
   LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct);
   LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH3);
+  LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH4);
+  LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
+  LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH4);
   LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
   LL_TIM_DisableMasterSlaveMode(TIM3);
   /* USER CODE BEGIN TIM3_Init 2 */
@@ -716,30 +837,39 @@ static void MX_TIM3_Init(void)
   PA6   ------> TIM3_CH1
   PA7   ------> TIM3_CH2
   PB0   ------> TIM3_CH3
+  PB1   ------> TIM3_CH4
   */
-  GPIO_InitStruct.Pin = PWM_R_Pin;
+  GPIO_InitStruct.Pin = PWM_5_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
   GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
   GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
   GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
-  LL_GPIO_Init(PWM_R_GPIO_Port, &GPIO_InitStruct);
+  LL_GPIO_Init(PWM_5_GPIO_Port, &GPIO_InitStruct);
 
-  GPIO_InitStruct.Pin = PWM_G_Pin;
+  GPIO_InitStruct.Pin = PWM_4_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
   GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
   GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
   GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
-  LL_GPIO_Init(PWM_G_GPIO_Port, &GPIO_InitStruct);
+  LL_GPIO_Init(PWM_4_GPIO_Port, &GPIO_InitStruct);
 
-  GPIO_InitStruct.Pin = PWM_B_Pin;
+  GPIO_InitStruct.Pin = PWM_3_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
   GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
   GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
   GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
-  LL_GPIO_Init(PWM_B_GPIO_Port, &GPIO_InitStruct);
+  LL_GPIO_Init(PWM_3_GPIO_Port, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = PWM_2_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
+  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
+  LL_GPIO_Init(PWM_2_GPIO_Port, &GPIO_InitStruct);
 
 }
 
@@ -747,6 +877,7 @@ static void MX_TIM3_Init(void)
   * @brief TIM14 Initialization Function
   * @param None
   * @retval None
+  * "Áëèíêîâàíèå" ðàçðÿäàìè, 0,75/0,25 ñåê âêë/âûêë.
   */
 static void MX_TIM14_Init(void)
 {
@@ -758,8 +889,6 @@ static void MX_TIM14_Init(void)
   LL_TIM_InitTypeDef TIM_InitStruct = {0};
   LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
 
-  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
-
   /* Peripheral clock enable */
   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM14);
 
@@ -770,34 +899,24 @@ static void MX_TIM14_Init(void)
   /* USER CODE BEGIN TIM14_Init 1 */
 
   /* USER CODE END TIM14_Init 1 */
-  TIM_InitStruct.Prescaler = 240;
+  TIM_InitStruct.Prescaler = (24000 - 1);
   TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
   TIM_InitStruct.Autoreload = 1000;
   TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
   LL_TIM_Init(TIM14, &TIM_InitStruct);
   LL_TIM_EnableARRPreload(TIM14);
-  LL_TIM_OC_EnablePreload(TIM14, LL_TIM_CHANNEL_CH1);
-  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
+  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_INACTIVE;
   TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
   TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
   TIM_OC_InitStruct.CompareValue = 750;
   TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
   LL_TIM_OC_Init(TIM14, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
   LL_TIM_OC_DisableFast(TIM14, LL_TIM_CHANNEL_CH1);
+  LL_TIM_OC_EnablePreload(TIM14, LL_TIM_CHANNEL_CH1);
   /* USER CODE BEGIN TIM14_Init 2 */
-
+  TIM14->DIER |= TIM_DIER_UIE;
+  TIM14->DIER |= TIM_DIER_CC1IE;
   /* USER CODE END TIM14_Init 2 */
-  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
-  /**TIM14 GPIO Configuration
-  PB1   ------> TIM14_CH1
-  */
-  GPIO_InitStruct.Pin = PWM_T_Pin;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
-  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
-  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
-  GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
-  LL_GPIO_Init(PWM_T_GPIO_Port, &GPIO_InitStruct);
 
 }
 
@@ -827,7 +946,7 @@ static void MX_TIM16_Init(void)
   /* USER CODE BEGIN TIM16_Init 1 */
 
   /* USER CODE END TIM16_Init 1 */
-  TIM_InitStruct.Prescaler = 24;
+  TIM_InitStruct.Prescaler = (24 - 1);
   TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
   TIM_InitStruct.Autoreload = 1000;
   TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
@@ -886,7 +1005,7 @@ static void MX_TIM17_Init(void)
   /* USER CODE BEGIN TIM17_Init 1 */
 
   /* USER CODE END TIM17_Init 1 */
-  TIM_InitStruct.Prescaler = 240;
+  TIM_InitStruct.Prescaler = (240 - 1);
   TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
   TIM_InitStruct.Autoreload = 1000;
   TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
@@ -1031,6 +1150,9 @@ static void MX_GPIO_Init(void)
   LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOC);
   LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
 
+  /**/
+  LL_GPIO_ResetOutputPin(UART_EN_GPIO_Port, UART_EN_Pin);
+
   /**/
   LL_GPIO_ResetOutputPin(LC0_GPIO_Port, LC0_Pin);
 
@@ -1049,6 +1171,30 @@ static void MX_GPIO_Init(void)
   /**/
   LL_GPIO_ResetOutputPin(Latch_GPIO_Port, Latch_Pin);
 
+  /**/
+  LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTC, LL_EXTI_CONFIG_LINE14);
+
+  /**/
+  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_14;
+  EXTI_InitStruct.LineCommand = ENABLE;
+  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
+  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
+  LL_EXTI_Init(&EXTI_InitStruct);
+
+  /**/
+  LL_GPIO_SetPinPull(IRQ_GPIO_Port, IRQ_Pin, LL_GPIO_PULL_UP);
+
+  /**/
+  LL_GPIO_SetPinMode(IRQ_GPIO_Port, IRQ_Pin, LL_GPIO_MODE_INPUT);
+
+  /**/
+  GPIO_InitStruct.Pin = UART_EN_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
+  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
+  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+  LL_GPIO_Init(UART_EN_GPIO_Port, &GPIO_InitStruct);
+
   /**/
   GPIO_InitStruct.Pin = LC0_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
@@ -1089,36 +1235,6 @@ static void MX_GPIO_Init(void)
   GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
   LL_GPIO_Init(SHDN_GPIO_Port, &GPIO_InitStruct);
 
-  /**/
-  GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
-  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
-  /**/
-  GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
-  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
-  /**/
-  GPIO_InitStruct.Pin = BTN1_Pin;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
-  LL_GPIO_Init(BTN1_GPIO_Port, &GPIO_InitStruct);
-
-  /**/
-  GPIO_InitStruct.Pin = BTN2_Pin;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
-  LL_GPIO_Init(BTN2_GPIO_Port, &GPIO_InitStruct);
-
-  /**/
-  GPIO_InitStruct.Pin = BTN3_Pin;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
-  LL_GPIO_Init(BTN3_GPIO_Port, &GPIO_InitStruct);
-
   /**/
   GPIO_InitStruct.Pin = BTN4_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
@@ -1126,10 +1242,10 @@ static void MX_GPIO_Init(void)
   LL_GPIO_Init(BTN4_GPIO_Port, &GPIO_InitStruct);
 
   /**/
-  GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
-  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = BTN1_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+  LL_GPIO_Init(BTN1_GPIO_Port, &GPIO_InitStruct);
 
   /**/
   GPIO_InitStruct.Pin = Latch_Pin;
@@ -1140,34 +1256,22 @@ static void MX_GPIO_Init(void)
   LL_GPIO_Init(Latch_GPIO_Port, &GPIO_InitStruct);
 
   /**/
-  GPIO_InitStruct.Pin = UART_EN_Pin;
-  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
-  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
-  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
-  LL_GPIO_Init(UART_EN_GPIO_Port, &GPIO_InitStruct);
+  GPIO_InitStruct.Pin = BTN2_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+  LL_GPIO_Init(BTN2_GPIO_Port, &GPIO_InitStruct);
 
   /**/
   GPIO_InitStruct.Pin = UART_ST_Pin;
   GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
-  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
   LL_GPIO_Init(UART_ST_GPIO_Port, &GPIO_InitStruct);
 
   /**/
-  LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTC, LL_EXTI_CONFIG_LINE14);
-
-  /**/
-  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_14;
-  EXTI_InitStruct.LineCommand = ENABLE;
-  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
-  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
-  LL_EXTI_Init(&EXTI_InitStruct);
-
-  /**/
-  LL_GPIO_SetPinPull(IRQ_GPIO_Port, IRQ_Pin, LL_GPIO_PULL_UP);
-
-  /**/
-  LL_GPIO_SetPinMode(IRQ_GPIO_Port, IRQ_Pin, LL_GPIO_MODE_INPUT);
+  GPIO_InitStruct.Pin = BTN3_Pin;
+  GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+  LL_GPIO_Init(BTN3_GPIO_Port, &GPIO_InitStruct);
 
   /* EXTI interrupt init*/
   NVIC_SetPriority(EXTI4_15_IRQn, 0);
@@ -1196,8 +1300,11 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
     tubesBuffer[0] = 0;
     tubesBuffer[1] &= nixieCathodeMask[Tube_E][1];
     if (Tube_E != 0xf) {
+      TUBE_E_ON;
       tubesBuffer[0] = (uint8_t)(nixieCathodeMap[Tube_E][dig] >> 8);
       tubesBuffer[1] |= (uint8_t)(nixieCathodeMap[Tube_E][dig]);
+    } else {
+      TUBE_E_OFF;
     }
     break;
 
@@ -1205,8 +1312,11 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
     tubesBuffer[1] &= nixieCathodeMask[Tube_D][0];
     tubesBuffer[2] &= nixieCathodeMask[Tube_D][1];
     if (Tube_D != 0xf) {
+      TUBE_D_ON;
       tubesBuffer[1] |= (uint8_t)(nixieCathodeMap[Tube_D][dig] >> 8);
       tubesBuffer[2] |= (uint8_t)(nixieCathodeMap[Tube_D][dig]);
+    } else {
+      TUBE_D_OFF;
     }
     break;
 
@@ -1214,8 +1324,11 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
     tubesBuffer[2] &= nixieCathodeMask[Tube_B][0];
     tubesBuffer[3] &= nixieCathodeMask[Tube_B][1];
     if (Tube_B != 0xf) {
+      TUBE_B_ON;
       tubesBuffer[2] |= (uint8_t)(nixieCathodeMap[Tube_B][dig] >> 8);
       tubesBuffer[3] |= (uint8_t)(nixieCathodeMap[Tube_B][dig]);
+    } else {
+      TUBE_B_OFF;
     }
     break;
 
@@ -1223,8 +1336,11 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
     tubesBuffer[3] &= nixieCathodeMask[Tube_A][0];
     tubesBuffer[4] = 0;
     if (Tube_A != 0xf) {
+      TUBE_A_ON;
       tubesBuffer[3] |= (uint8_t)(nixieCathodeMap[Tube_A][dig] >> 8);
       tubesBuffer[4] = (uint8_t)(nixieCathodeMap[Tube_A][dig]);
+    } else {
+      TUBE_A_OFF;
     }
     break;
 
@@ -1233,6 +1349,32 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
   }
 }
 
+/**
+  * @brief  Âûâîä HEX çíà÷åíèé öâåòà â òàéìåð.
+  * @param  : RGB value in range 0x00-0xFF
+  * @retval : None
+  */
+static void Color_RGB(uint8_t r, uint8_t g, uint8_t b) {
+  /* Áîëåå áûñòðûé âàðèàíò, íà ïðîáó. */
+  COLOR_R(r * 4);
+  COLOR_G(g * 4);
+  COLOR_B(b * 4);
+
+  /* Ïðåäâàðèòåëüíûé îáñ÷¸ò â ïåðåìåííûå ñäåëàí äëÿ òîãî,
+     ÷òî-áû âûâåñòè çíà÷åíèÿ â òàéìåð ìàêñèìàëüíî îäíîâðåìåííî. */
+/*
+  uint32_t val_r, val_g, val_b;
+
+  val_r = ((uint32_t)(r * 1000) + 128) / 256;
+  val_g = ((uint32_t)(g * 1000) + 128) / 256;
+  val_b = ((uint32_t)(b * 1000) + 128) / 256;
+
+  COLOR_R((uint16_t)val_r);
+  COLOR_G((uint16_t)val_g);
+  COLOR_B((uint16_t)val_b);
+*/
+}
+
 /**
   * @brief  Îáðàáîòêà êíîïîê.
   * @param  : None
@@ -1240,7 +1382,7 @@ static void showDigit(tube_pos_t pos, uint8_t dig)
   */
 static void btnProcess(void) {
   /* get pin state */
-  uint32_t pins = BTN_PORT->IDR & BTN_PINS;
+  uint32_t pins = BTNS_STATE;
 
   int i;
   for (i=0; i<BTN_NUM; i++) {
@@ -1271,25 +1413,30 @@ static void btnProcess(void) {
 
 void in15Off(void) {
   IN15_OFF;
+  TUBE_C_OFF;
 }
 
 void in15Minus(void) {
   IN15_OFF;
+  TUBE_C_ON;
   IN15_Minus;
 }
 
 void in15Plus(void) {
   IN15_OFF;
+  TUBE_C_ON;
   IN15_Plus;
 }
 
 void in15Percent(void) {
   IN15_OFF;
+  TUBE_C_ON;
   IN15_Percent;
 }
 
 void in15P(void) {
   IN15_OFF;
+  TUBE_C_ON;
   IN15_P;
 }
 

+ 54 - 15
Src/stm32g0xx_it.c

@@ -143,19 +143,6 @@ void SysTick_Handler(void)
 /* please refer to the startup file (startup_stm32g0xx.s).                    */
 /******************************************************************************/
 
-/**
-  * @brief This function handles RCC global interrupt.
-  */
-void RCC_IRQHandler(void)
-{
-  /* USER CODE BEGIN RCC_IRQn 0 */
-
-  /* USER CODE END RCC_IRQn 0 */
-  /* USER CODE BEGIN RCC_IRQn 1 */
-
-  /* USER CODE END RCC_IRQn 1 */
-}
-
 /**
   * @brief This function handles EXTI line 4 to 15 interrupts.
   */
@@ -245,14 +232,66 @@ void DMA1_Channel2_3_IRQHandler(void)
 
 /**
   * @brief This function handles TIM14 global interrupt.
+  * Ïðè ïåðåïîëíåíèè àêòèâèðóåì âñå êàíàëû, ïðè ñîâïàäåíèè îòêëþ÷àåì íóæíûå.
   */
 void TIM14_IRQHandler(void)
 {
   /* USER CODE BEGIN TIM14_IRQn 0 */
-
+  static uint32_t _flg = 0;
+  if ((TIM14->SR & TIM_SR_UIF) != 0) {
+    /* Update interrupt */
+    TIM14->SR |= TIM_SR_UIF;
+
+    /* enable channels */
+    if ((_flg & 0x1) != 0) {
+      TUBE_A_ON;
+      _flg &= ~0x1;
+    }
+    if ((_flg & 0x2) != 0) {
+      TUBE_B_ON;
+      _flg &= ~0x2;
+    }
+    if ((_flg & 0x4) != 0) {
+      TUBE_C_ON;
+      _flg &= ~0x4;
+    }
+    if ((_flg & 0x8) != 0) {
+      TUBE_D_ON;
+      _flg &= ~0x8;
+    }
+    if ((_flg & 0x10) != 0) {
+      TUBE_E_ON;
+      _flg &= ~0x10;
+    }
+  }
   /* USER CODE END TIM14_IRQn 0 */
   /* USER CODE BEGIN TIM14_IRQn 1 */
-
+  if ((TIM14->SR & TIM_SR_CC1IF) != 0) {
+    /* Capture/Compare Interrupt */
+    TIM14->SR |= TIM_SR_CC1IF;
+
+    /* disable needed channel */
+    if (Flag.Blink_1 != 0) {
+      TUBE_A_OFF;
+      _flg |= 0x1;
+    }
+    if (Flag.Blink_2 != 0) {
+      TUBE_B_OFF;
+      _flg |= 0x2;
+    }
+    if (Flag.Blink_3 != 0) {
+      TUBE_C_OFF;
+      _flg |= 0x4;
+    }
+    if (Flag.Blink_4 != 0) {
+      TUBE_D_OFF;
+      _flg |= 0x8;
+    }
+    if (Flag.Blink_5 != 0) {
+      TUBE_E_OFF;
+      _flg |= 0x10;
+    }
+  }
   /* USER CODE END TIM14_IRQn 1 */
 }