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
TDK
Guru

There's a big difference in how that FET behaves when VGS is 3.3V and when it's 5V. Driving the pin to 3.3V just doesn't turn it on fully.

Threshold is listed as 2V min, 4V max.

0693W00000FBgtoQAD.png 

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

@TDK​ @Community member​ @Community member​ 

So is there a chance that my pins might be putting out voltage 3.3v ?

I mean as far as I know all pins will give out 5V ... since my board is getting USB input it should be 5V?

I am getting my multimeter tomorrow so will also give feedback asap.

In the meantime I put my TIP102 (cause its all I have) between the GATE of the FET and the PWM out PIN.

Now it shines a little bit brighter but still not full capability.

The mcu runs off of 3.3V. The pins will output 3.3V when high.
The 5V input gets fed into a voltage regulator which supplies the mcu.
If you feel a post has answered your question, please click "Accept as Solution".

It has pins which are 5V tolerant, but frequently the DISCO/NUCLEO's run the MCU at 3.0V or 3.3V, and you certainly can't be attaching 5 VDC to the VDD pins of the MCU

You could configure the GPIO in OD (Open Drain), and pull the pin to 5V for the high side voltage of pins marked "FT" in the data sheet.

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