STM32 + N канальный транзер

Тема в разделе "Силовая электроника", создана пользователем Kisa9000, 27 июн 2019.

  1. Kisa9000

    Kisa9000 Нуб

    Код (C++):
    /* USER CODE BEGIN Header */

    /* USER CODE END Header */

    /* Includes ------------------------------------------------------------------*/
    #include "main.h"

    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */

    /* USER CODE END Includes */

    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */

    /* USER CODE END PTD */

    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */

    /* USER CODE END PD */

    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */

    /* USER CODE END PM */

    /* Private variables ---------------------------------------------------------*/
    ADC_HandleTypeDef hadc1;

    TIM_HandleTypeDef htim4;

    /* USER CODE BEGIN PV */
    uint16_t pwm = 50;
    /* USER CODE END PV */

    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_TIM4_Init(void);
    static void MX_ADC1_Init(void);
    /* USER CODE BEGIN PFP */

    /* 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)
    {
      /* USER CODE BEGIN 1 */

      /* USER CODE END 1 */

      /* MCU Configuration--------------------------------------------------------*/

      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();

      /* USER CODE BEGIN Init */

      /* USER CODE END Init */

      /* Configure the system clock */
      SystemClock_Config();

      /* USER CODE BEGIN SysInit */

      /* USER CODE END SysInit */

      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_TIM4_Init();
      MX_ADC1_Init();
      /* USER CODE BEGIN 2 */
        HAL_TIM_Base_Start_IT(&htim4);
        HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
      /* USER CODE END 2 */

      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
            HAL_ADC_Start(&hadc1);
            HAL_ADC_PollForConversion(&hadc1,100);
            pwm = HAL_ADC_GetValue(&hadc1) / (4096 / 255);
            HAL_ADC_Stop(&hadc1);
            TIM4 -> CCR1 = pwm;
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }

    /**
      * @brief System Clock Configuration
      * @retval None
      */

    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

      /**Initializes the CPU, AHB and APB busses clocks
      */

      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /**Initializes the CPU, AHB and APB busses clocks
      */

      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
      {
        Error_Handler();
      }
      PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
      PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
      {
        Error_Handler();
      }
    }

    /**
      * @brief ADC1 Initialization Function
      * @param None
      * @retval None
      */

    static void MX_ADC1_Init(void)
    {

      /* USER CODE BEGIN ADC1_Init 0 */

      /* USER CODE END ADC1_Init 0 */

      ADC_ChannelConfTypeDef sConfig = {0};

      /* USER CODE BEGIN ADC1_Init 1 */

      /* USER CODE END ADC1_Init 1 */
      /**Common config
      */

      hadc1.Instance = ADC1;
      hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
      hadc1.Init.ContinuousConvMode = DISABLE;
      hadc1.Init.DiscontinuousConvMode = DISABLE;
      hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
      hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
      hadc1.Init.NbrOfConversion = 1;
      if (HAL_ADC_Init(&hadc1) != HAL_OK)
      {
        Error_Handler();
      }
      /**Configure Regular Channel
      */

      sConfig.Channel = ADC_CHANNEL_7;
      sConfig.Rank = ADC_REGULAR_RANK_1;
      sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN ADC1_Init 2 */

      /* USER CODE END ADC1_Init 2 */

    }

    /**
      * @brief TIM4 Initialization Function
      * @param None
      * @retval None
      */

    static void MX_TIM4_Init(void)
    {

      /* USER CODE BEGIN TIM4_Init 0 */

      /* USER CODE END TIM4_Init 0 */

      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      TIM_OC_InitTypeDef sConfigOC = {0};

      /* USER CODE BEGIN TIM4_Init 1 */

      /* USER CODE END TIM4_Init 1 */
      htim4.Instance = TIM4;
      htim4.Init.Prescaler = 719;
      htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim4.Init.Period = 250;
      htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sConfigOC.OCMode = TIM_OCMODE_PWM1;
      sConfigOC.Pulse = 0;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
      if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM4_Init 2 */

      /* USER CODE END TIM4_Init 2 */
      HAL_TIM_MspPostInit(&htim4);

    }

    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */

    static void MX_GPIO_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};

      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();

      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_SET);

      /*Configure GPIO pin : PC13 */
      GPIO_InitStruct.Pin = GPIO_PIN_13;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

      /*Configure GPIO pin : PC14 */
      GPIO_InitStruct.Pin = GPIO_PIN_14;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    }

    /* USER CODE BEGIN 4 */

    /* USER CODE END 4 */

    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */

    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */

      /* USER CODE END Error_Handler_Debug */
    }

    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */

    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
     
     
  2. parovoZZ

    parovoZZ Гуру

    ТС утверждает, что:
    не понимаешь, что там заявка на патент готовится?
     
  3. Kisa9000

    Kisa9000 Нуб

    :DDDD да просто разобраться хочу
     
  4. parovoZZ

    parovoZZ Гуру

    В чем?
     
  5. Kisa9000

    Kisa9000 Нуб

    Почему сие творение не работает как задумано.
     
  6. parovoZZ

    parovoZZ Гуру

    с транзистором разобрался? Смысл мудрить с кодом, если смехотехника не рабочая?
     
  7. Kisa9000

    Kisa9000 Нуб

    Да все все, не пашет транзер. Чисто на землю Gate кинул и не гаснет. Чуть чуть яркость ниже становится и все.
     
  8. DetSimen

    DetSimen Guest

    ты картинками и мышкой штоли программируешь?
     
  9. b707

    b707 Гуру

    Это код явно из Куба (STMCube)
    Киса, проверьте, правильно ли Вы выбрали пин, в инете пишут что Timer4 CH1 это PD12
    Кроме того, по умолчанию этот же пин задействован в USB. поэтому лучше взять канал 2 или 3 этого же таймера - они свободны
     
  10. parovoZZ

    parovoZZ Гуру

    Не знаю, есть там на затворе ESD диод или нет, но в следующий раз лучше перемкнуть все выводы при пайке.
    может лучше из даташита черпть инфу?

    а низзя?
     
  11. b707

    b707 Гуру

    Киса - и еще хочу отметить, что никакого "программного ШИМ" в Вашем коде я не вижу. То. что вы пытаетесь сделать(не уврен, что правильно) - как раз аппаратный ШИМ.
    Программный ШИМ делается так - вы запускаете таймер, пишите к нему обработчик прерывания по совпадению или переполнению , а уже в обработчике сами дергаете нужные пины. В итоге одним таймером можно ШИМить любое число цифровых выходов и выходы не имеют жесткой привязки к таймеру.
    А то что делаете Вы - обычный аппаратный PWM
     
    Последнее редактирование: 27 июн 2019
  12. Kisa9000

    Kisa9000 Нуб

    Да с ногой все Ок. Шью и питаю микруху через китайST-link. Кручу потенциометр и напряжение на вольтметре плавно меняется с 0 до ~3.2.
     
  13. Kisa9000

    Kisa9000 Нуб

    Да, чтобы разобраться с транзистором я решил пока использовать "аппаратный ШИМ" (в самом первом сообщении писал). Программный на один канал написал, но он похож на костыль сделанный из костылей который крутится в HAL_TIM_PeriodElapsedCallback...ну и собственно стыдно на люди еще и это выставлять))
     
  14. Kisa9000

    Kisa9000 Нуб

    Ладно ребят, спасибки вам большое за ваше время и мега мозги! Сорри за возможный вред вашей нервной системе и душевному состоянию, постараюсь исправиться.
     
  15. b707

    b707 Гуру

    ну-ну :)
    что "очень маловероятно"? что у кого-то окажется Куб? :)
    Чтобы "экспертам" разобраться в программе, сам Куб и проект иметь вовсе не обязательно, куб оперирует стандартными директивами HAL, которые применяли задолго до появления Куба
    И вообще сам Куб полноценной ИДЕ не является, это всего лишь красивый генератор инициализационных скриптов
     
    parovoZZ нравится это.
  16. Kisa9000

    Kisa9000 Нуб

    Ну и если кто может посоветовать проверенный N канальный полевик в корпусе SOT23 для STMки то было бы классно увидеть сей вариант
     
  17. b707

    b707 Гуру

    тот, что вы использовали - по даташиту совсем неплох
    Для СТМ сложно подбирать, потому что большинству даже логических мосфетов уровня 3.3в для включения все-таки мало. Лучше включать мосфеты через драйвер
     
  18. Kisa9000

    Kisa9000 Нуб

    Спасибо!
     
  19. parovoZZ

    parovoZZ Гуру

    В качестве драйвера можно использовать логику ТТЛШ. Она совсем копейки стоит.
     
  20. sser

    sser Гик

    С ШИМом вот этот шилд хорошо работает, но он до 20кгц
    Модуль MOSFET AOD4184