cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G031 output pin output can not drive TIP102 into saturation?

CMcC.1
Associate II

My STM Nucleo G031K6 board has a very simple app running on it.

It simply outputs a PWM signal from 0 to 100% duty cycle and then resets and starts over.

It runs this into a TIP102s Base with 1K Ohm resistance between them.

However even at 100% Duty Cycle the LEDS on the tip are hardly even 50% of their capability.

When I put the same led strip directly to 5V on the same board it is much brighter. IF I put the BASE of the TIP102 on the 5V rail it is also much brighter.

So I though that there is something wrong with my PWM. I then set pin PA10 to output and connected the Base pin to it and the same result as the PWM was seen. I am not sure why my board won't saturate the TIP102?

I then checked that there is a Output Level option on each GPIO pin and set both the PWM pin and the PA10 pin to HIGH but the results where the same.

Thanks

#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
enum ACTION{
    UP = 0,
    SUSTAIN = 1,
    DOWN = 2,
    IDLE = 3
};
 
struct LEDSTATE {
    int Current_Led_Action;
    int Inc_Dec_Definer;
    uint32_t Current_PWM_Degree;
    int LED_DEGREE_MAX ;
    int LED_DEGREE_MIN;
    uint32_t SUSTAIN_COUNTER;
    uint32_t SUSTAIN_COUNTER_LIMIT;
} LED_STATE;
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void init_all(){
    LED_STATE.Current_Led_Action = DOWN;
    LED_STATE.Inc_Dec_Definer = -1;
    LED_STATE.Current_PWM_Degree = 0;
    LED_STATE.LED_DEGREE_MAX = 3200;
    LED_STATE.LED_DEGREE_MIN = 0;
    LED_STATE.SUSTAIN_COUNTER = 0;
    LED_STATE.SUSTAIN_COUNTER_LIMIT = 200;//4294000000;
}
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim16;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM16_Init(void);
/* USER CODE BEGIN PFP */
void LED_SERVICE_ROUTINE(){
    switch (LED_STATE.Current_Led_Action){
        case UP:{
            //Switch Inc_Dec_Definer to increment if it was on decrement (X*1);
            if (LED_STATE.Current_PWM_Degree >= LED_STATE.LED_DEGREE_MAX) {
                //Set LED_STATE.Current_Led_Action = SUSTAIN.
                LED_STATE.Current_Led_Action = SUSTAIN;
                LED_STATE.SUSTAIN_COUNTER = 0;
            } else {
                LED_STATE.Current_PWM_Degree++;
                TIM2->CCR1 = LED_STATE.Current_PWM_Degree;
            }
            break;
        }
        case SUSTAIN:{
            if (LED_STATE.SUSTAIN_COUNTER < LED_STATE.SUSTAIN_COUNTER_LIMIT){
                LED_STATE.SUSTAIN_COUNTER++;
            } else {
                LED_STATE.Current_Led_Action = DOWN;
            }
            //Do nothing with PWM for a couple of seconds.
            break;
        }
        case DOWN:{
            //Switch Inc_Dec_Definer to decrement if it was on increment (X*-1);
            if (LED_STATE.Current_PWM_Degree CCR1 = LED_STATE.Current_PWM_Degree;
            }
            break;
        }
        case IDLE:{
            int x = 0 ;
            x ++;
        }
    }
}
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
 
  HAL_Init();
 
 
  SystemClock_Config();
 
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM16_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim16);
 
  /* USER CODE END 2 */
 
 
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  while (1)
  {
 
          if(HAL_GPIO_ReadPin (GPIOB, GPIO_PIN_0))
          {
            LED_STATE.Current_Led_Action = UP;
 
              // Set The LED ON!
              //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
              //TIM2->CCR1 = 50;
          }
          else
          {
              // Else .. Turn LED OFF!
              //HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
              //TIM2->CCR1 = 2000;
          }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage 
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_TIM2_Init(void)
{
 
  /* USER CODE BEGIN TIM2_Init 0 */
 
  /* USER CODE END TIM2_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
 
  /* USER CODE BEGIN TIM2_Init 1 */
 
  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 3200;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 0;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 300;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */
 
  /* USER CODE END TIM2_Init 2 */
  HAL_TIM_MspPostInit(&htim2);
 
}
 
static void MX_TIM16_Init(void)
{
 
  htim16.Instance = TIM16;
  htim16.Init.Prescaler = 32000-1;
  htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim16.Init.Period = 100-1;
  htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim16.Init.RepetitionCounter = 0;
  htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim16) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
 
  /*Configure GPIO pin : PB0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PA9 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PC6 */
  GPIO_InitStruct.Pin = GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
}
 
/* USER CODE BEGIN 4 */
//TIM6 CALLBACK
uint32_t *** = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim){
    if (htim == &htim16){
        //LED_SERVICE_ROUTINE();
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_6);
        TIM2->CCR1  = ***++;
 
        if (*** == 3200){
            *** = 0 ;
        }
    }
}
 void Error_Handler(void)
{
 
}
 
#ifdef  USE_FULL_ASSERT
 
void assert_failed(uint8_t *file, uint32_t line)
{ 
 
}
#endif /* USE_FULL_ASSERT */

13 REPLIES 13
  1. htim2.Instance = TIM2;
  2. htim2.Init.Prescaler = 3200; //NO ZERO
  3. htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  4. htim2.Init.Period = 0; // NO 3200-1
  5. htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  6. htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
CMcC.1
Associate II

@Community member​ 

Hmmm ok but that does not solve my low power output issue?

Unless I'm missing something setting the Period to Zero will turn off the timer, it won't count.

Where is the GPIO related to TIM2 configured?

If you set the GPIO High/Low does that work?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
CMcC.1
Associate II

@Community member​ 

Yea that must have been one of my attempts. It definitely worked. I even did your example also. If you check the code you will see that if its 0 it will just get incremented gradually in the interrupt anyway.

Well I had a seperate GPIO om HIGH (PA10)​.

I removed the base from the PWM signal and attached it to PA10 and it was the same.

Soo different pin and set to HIGH and still couldn't saturate the TIP102.

​This is mind boggling... Perhaps damaged IO?

TDK
Guru

Perhaps a damaged light strip. If you have a 1k resistor in series, doubtful that it can't bring that up to 3.3V regardless of what's on the other end.

If you feel a post has answered your question, please click "Accept as Solution".
CMcC.1
Associate II

@TDK​ @Community member​ 

No that led strip works fine when I set the strip 5V -> Strip directly.

The 1K resistor is just on the Base of the Darlington.

With 3V power supply of the STM32, 1kOhm resistor in base and 2V drop on the darlington's B-E, you can't push more than 1mA to the base, which is probably far from saturation.

Also, with GPIO_OSPEEDR setting on lowest, the pin's output impedance is in the kOhms region, too.

So

  1. change GPIO_OSPEEDR setting for given pin(s) to high (maybe highest)
  2. decrease series resistor

JW

TDK
Guru

I was assuming the transistor was part of the light strip. But the point still stands. Perhaps measure voltage at the output pin directly and provide the relevant schematic. Is the transistor on the GND side of the strip or the 5V side? Seems way more likely to be a hardware error than an STM32 issue, especially as different pins behave the same.

If you feel a post has answered your question, please click "Accept as Solution".
CMcC.1
Associate II

@TDK​ @Community member​ @Community member​ 

Ok so I waited for my FETs to come before I reply to this. Cause I wanted to see if this is perhaps the issue.

The Tips where not the issue. It does exactly the same with the FETS than it did with the TIPS.

I am still waiting for my multimeter to come.

I have ticked HIGH for all the pins I have active and it didn't really change anything.

Although it starts off Dimmed and then gradually gets brighter cause of PWM CCR1 changes, it does not get as bright as it does when I put the GATE directly on the 5V rail.

So my configuration at the moment is.

PWM -> 1K -> GATE(FET) ; 5V-> LED Strip -> DRAIN(FET) ; SOURCE -> GND

I am using this FET-> https://pdf1.alldatasheet.com/datasheet-pdf/view/719836/TOSHIBA/TK72A12N1.html