Skip to main content
Associate III
Nov 12, 2025 6:59 AM UTC
Solved

PWM output on PA8 (TIM1_CH1) does not reach 0V — waveform distorted

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "usb_host.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 ---------------------------------------------------------*/
CRC_HandleTypeDef hcrc;

DCMI_HandleTypeDef hdcmi;

DMA2D_HandleTypeDef hdma2d;

I2C_HandleTypeDef hi2c1;

SPI_HandleTypeDef hspi5;

TIM_HandleTypeDef htim1;

UART_HandleTypeDef huart1;

SDRAM_HandleTypeDef hsdram1;

osThreadId defaultTaskHandle;
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CRC_Init(void);
static void MX_DMA2D_Init(void);
static void MX_FMC_Init(void);
static void MX_SPI5_Init(void);
static void MX_TIM1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_DCMI_Init(void);
static void MX_I2C1_Init(void);
void StartDefaultTask(void const * argument);

/* USER CODE BEGIN PFP */
void I2C_Scan(void);
/* 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_CRC_Init();
 MX_DMA2D_Init();
 MX_FMC_Init();
 MX_SPI5_Init();
 MX_TIM1_Init();
 MX_USART1_UART_Init();
 MX_DCMI_Init();
 MX_I2C1_Init();
 /* USER CODE BEGIN 2 */
 Start_XCLK(); //PWM開始
 I2C_Scan(); //I2C接続確認
 Read_MT9M001_ChipID(); //チップIDを読み取る
 /* USER CODE END 2 */

 /* USER CODE BEGIN RTOS_MUTEX */
 /* add mutexes, ... */
 /* USER CODE END RTOS_MUTEX */

 /* USER CODE BEGIN RTOS_SEMAPHORES */
 /* add semaphores, ... */
 /* USER CODE END RTOS_SEMAPHORES */

 /* USER CODE BEGIN RTOS_TIMERS */
 /* start timers, add new ones, ... */
 /* USER CODE END RTOS_TIMERS */

 /* USER CODE BEGIN RTOS_QUEUES */
 /* add queues, ... */
 /* USER CODE END RTOS_QUEUES */

 /* Create the thread(s) */
 /* definition and creation of defaultTask */
 osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 4096);
 defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

 /* USER CODE BEGIN RTOS_THREADS */
 /* add threads, ... */
 /* USER CODE END RTOS_THREADS */

 /* Start scheduler */
 osKernelStart();

 /* We should never get here as control is now taken by the scheduler */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* 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};

 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 8;
 RCC_OscInitStruct.PLL.PLLN = 360;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 7;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Activate the Over-Drive mode
 */
 if (HAL_PWREx_EnableOverDrive() != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses 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_DIV4;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief CRC Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_CRC_Init(void)
{

 /* USER CODE BEGIN CRC_Init 0 */

 /* USER CODE END CRC_Init 0 */

 /* USER CODE BEGIN CRC_Init 1 */

 /* USER CODE END CRC_Init 1 */
 hcrc.Instance = CRC;
 if (HAL_CRC_Init(&hcrc) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN CRC_Init 2 */

 /* USER CODE END CRC_Init 2 */

}

/**
 * @brief DCMI Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_DCMI_Init(void)
{

 /* USER CODE BEGIN DCMI_Init 0 */

 /* USER CODE END DCMI_Init 0 */

 /* USER CODE BEGIN DCMI_Init 1 */

 /* USER CODE END DCMI_Init 1 */
 hdcmi.Instance = DCMI;
 hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
 hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
 hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
 hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
 hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
 hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
 hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
 if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DCMI_Init 2 */

 /* USER CODE END DCMI_Init 2 */

}

/**
 * @brief DMA2D Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_DMA2D_Init(void)
{

 /* USER CODE BEGIN DMA2D_Init 0 */

 /* USER CODE END DMA2D_Init 0 */

 /* USER CODE BEGIN DMA2D_Init 1 */

 /* USER CODE END DMA2D_Init 1 */
 hdma2d.Instance = DMA2D;
 hdma2d.Init.Mode = DMA2D_M2M;
 hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888;
 hdma2d.Init.OutputOffset = 0;
 hdma2d.LayerCfg[1].InputOffset = 0;
 hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
 hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
 hdma2d.LayerCfg[1].InputAlpha = 0;
 if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DMA2D_ConfigLayer(&hdma2d, 1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DMA2D_Init 2 */

 /* USER CODE END DMA2D_Init 2 */

}

/**
 * @brief I2C1 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_I2C1_Init(void)
{

 /* USER CODE BEGIN I2C1_Init 0 */

 /* USER CODE END I2C1_Init 0 */

 /* USER CODE BEGIN I2C1_Init 1 */

 /* USER CODE END I2C1_Init 1 */
 hi2c1.Instance = I2C1;
 hi2c1.Init.ClockSpeed = 100000;
 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
 hi2c1.Init.OwnAddress1 = 0;
 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
 hi2c1.Init.OwnAddress2 = 0;
 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
 if (HAL_I2C_Init(&hi2c1) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Analogue filter
 */
 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Digital filter
 */
 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN I2C1_Init 2 */

 /* USER CODE END I2C1_Init 2 */

}

/**
 * @brief SPI5 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_SPI5_Init(void)
{

 /* USER CODE BEGIN SPI5_Init 0 */

 /* USER CODE END SPI5_Init 0 */

 /* USER CODE BEGIN SPI5_Init 1 */

 /* USER CODE END SPI5_Init 1 */
 /* SPI5 parameter configuration*/
 hspi5.Instance = SPI5;
 hspi5.Init.Mode = SPI_MODE_MASTER;
 hspi5.Init.Direction = SPI_DIRECTION_2LINES;
 hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi5.Init.NSS = SPI_NSS_SOFT;
 hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
 hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi5.Init.CRCPolynomial = 10;
 if (HAL_SPI_Init(&hspi5) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SPI5_Init 2 */

 /* USER CODE END SPI5_Init 2 */

}

/**
 * @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 */

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

 /* USER CODE BEGIN TIM1_Init 1 */

 /* USER CODE END TIM1_Init 1 */
 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 0;
 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim1.Init.Period = 7;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 4;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
 sBreakDeadTimeConfig.DeadTime = 0;
 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM1_Init 2 */
 __HAL_TIM_MOE_ENABLE(&htim1); // ★ Advanced-timerの出力許可
 /* USER CODE END TIM1_Init 2 */
 HAL_TIM_MspPostInit(&htim1);

}

/**
 * @brief USART1 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART1_UART_Init(void)
{

 /* USER CODE BEGIN USART1_Init 0 */

 /* USER CODE END USART1_Init 0 */

 /* USER CODE BEGIN USART1_Init 1 */

 /* USER CODE END USART1_Init 1 */
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 115200;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART1_Init 2 */

 /* USER CODE END USART1_Init 2 */

}

/* FMC initialization function */
static void MX_FMC_Init(void)
{

 /* USER CODE BEGIN FMC_Init 0 */

 /* USER CODE END FMC_Init 0 */

 FMC_SDRAM_TimingTypeDef SdramTiming = {0};

 /* USER CODE BEGIN FMC_Init 1 */

 /* USER CODE END FMC_Init 1 */

 /** Perform the SDRAM1 memory initialization sequence
 */
 hsdram1.Instance = FMC_SDRAM_DEVICE;
 /* hsdram1.Init */
 hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
 hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
 hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
 hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
 hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
 hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
 hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
 hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
 hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
 hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
 /* SdramTiming */
 SdramTiming.LoadToActiveDelay = 2;
 SdramTiming.ExitSelfRefreshDelay = 7;
 SdramTiming.SelfRefreshTime = 4;
 SdramTiming.RowCycleDelay = 7;
 SdramTiming.WriteRecoveryTime = 3;
 SdramTiming.RPDelay = 2;
 SdramTiming.RCDDelay = 2;

 if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
 {
 Error_Handler( );
 }

 /* USER CODE BEGIN FMC_Init 2 */

 /* USER CODE END FMC_Init 2 */
}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 /* USER CODE BEGIN MX_GPIO_Init_1 */

 /* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOE_CLK_ENABLE();
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOF_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(ACP_RST_GPIO_Port, ACP_RST_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOD, RDX_Pin|WRX_DCX_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin : ENABLE_Pin */
 GPIO_InitStruct.Pin = ENABLE_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(ENABLE_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : NCS_MEMS_SPI_Pin CSX_Pin OTG_FS_PSO_Pin */
 GPIO_InitStruct.Pin = NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin;
 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);

 /*Configure GPIO pins : B1_Pin MEMS_INT1_Pin MEMS_INT2_Pin TP_INT1_Pin */
 GPIO_InitStruct.Pin = B1_Pin|MEMS_INT1_Pin|MEMS_INT2_Pin|TP_INT1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pins : B5_Pin R4_Pin R5_Pin */
 GPIO_InitStruct.Pin = B5_Pin|R4_Pin|R5_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /*Configure GPIO pin : ACP_RST_Pin */
 GPIO_InitStruct.Pin = ACP_RST_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(ACP_RST_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : OTG_FS_OC_Pin */
 GPIO_InitStruct.Pin = OTG_FS_OC_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(OTG_FS_OC_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : R3_Pin R6_Pin */
 GPIO_InitStruct.Pin = R3_Pin|R6_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF9_LTDC;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : BOOT1_Pin */
 GPIO_InitStruct.Pin = BOOT1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(BOOT1_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : G4_Pin G5_Pin */
 GPIO_InitStruct.Pin = G4_Pin|G5_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : TE_Pin */
 GPIO_InitStruct.Pin = TE_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(TE_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : RDX_Pin WRX_DCX_Pin */
 GPIO_InitStruct.Pin = RDX_Pin|WRX_DCX_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 /*Configure GPIO pins : R7_Pin DOTCLK_Pin B3_Pin */
 GPIO_InitStruct.Pin = R7_Pin|DOTCLK_Pin|B3_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

 /*Configure GPIO pin : R2_Pin */
 GPIO_InitStruct.Pin = R2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(R2_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : B2_Pin */
 GPIO_InitStruct.Pin = B2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
 HAL_GPIO_Init(B2_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : G3_Pin B4_Pin */
 GPIO_InitStruct.Pin = G3_Pin|B4_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF9_LTDC;
 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

 /*Configure GPIO pins : LD3_Pin LD4_Pin */
 GPIO_InitStruct.Pin = LD3_Pin|LD4_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

 /* USER CODE BEGIN MX_GPIO_Init_2 */
 // GPIO設定:PA8をTIM1_CH1として出力
 	__HAL_RCC_GPIOA_CLK_ENABLE();
 	GPIO_InitStruct.Pin = GPIO_PIN_8;
 	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 	GPIO_InitStruct.Pull = GPIO_NOPULL;
 	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 	GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
 	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void Start_XCLK(void)
{
	HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); //PWM出力開始
}

// I2C スキャナ関数
void I2C_Scan(void)
{
 char msg[64]; //文字列を一時的に格納するためのバッファ(UART通信)
 HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n[I2C Scan Start]\r\n", 19, HAL_MAX_DELAY); //UART1で文字列を送信

 for (uint8_t addr = 1; addr < 128; addr++) //I²C の 7bit アドレス範囲(1~127)を総当たりでチェック
 	{
 	if (HAL_I2C_IsDeviceReady(&hi2c1, addr << 1, 1, 100) == HAL_OK) //HAL_I2C_IsDeviceReady() =指定アドレスの I²C デバイスに問い合わせて応答があるか確認する関数
 		{
 		sprintf(msg, "Found device at 7bit address 0x%02X\r\n", addr); //応答があった場合,そのアドレスをメッセージに整形,msgに入れる.
 HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); //UART1経由で送信
 }
 	}
 HAL_UART_Transmit(&huart1, (uint8_t*)"[I2C Scan End]\r\n", 16, HAL_MAX_DELAY);
}


//Chip ID読み取り関数
void Read_MT9M001_ChipID(void)
{
	uint8_t buf[2]; //I²Cで受け取った2バイト(上位+下位)を一時保存
	uint16_t chip_id; //MSB+LSBして得られる16bitのチップID
	char msg[64]; //UARTで出力するメッセージを一時格納

	HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n[Read MT9M001 CHIP ID]\r\n", 26, HAL_MAX_DELAY);

	uint8_t devAddr = 0xBA; //MT9M001の8bitアドレス:0xBA(write)

	if(HAL_I2C_Mem_Read(&hi2c1, devAddr, 0x00, I2C_MEMADD_SIZE_8BIT, buf, 2, 100) == HAL_OK)
	{
		chip_id = (buf[0] << 8) | buf[1]; //MSB→LSB
		sprintf(msg, "CHIP_VERSION = 0x%04X\r\n", chip_id);
		HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
	}
	else
	{
 HAL_UART_Transmit(&huart1, (uint8_t*)"I2C read error!\r\n", 17, HAL_MAX_DELAY);
	}
}

/* USER CODE END 4 */

/* USER CODE BEGIN Header_StartDefaultTask */
/**
 * @brief Function implementing the defaultTask thread.
 * @PAram argument: Not used
 * @retval None
 */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
 /* init code for USB_HOST */
 MX_USB_HOST_Init();
 /* USER CODE BEGIN 5 */
 /* Infinite loop */
 for(;;)
 {
 osDelay(1);
 }
 /* USER CODE END 5 */
}

/**
 * @brief Period elapsed callback in non blocking mode
 * @note This function is called when TIM6 interrupt took place, inside
 * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
 * a global variable "uwTick" used as application time base.
 * @PAram htim : TIM handle
 * @retval None
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
 /* USER CODE BEGIN Callback 0 */

 /* USER CODE END Callback 0 */
 if (htim->Instance == TIM6)
 {
 HAL_IncTick();
 }
 /* USER CODE BEGIN Callback 1 */

 /* USER CODE END Callback 1 */
}

/**
 * @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 */
 __disable_irq();
 while (1)
 {
 }
 /* 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,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

Hello,
I’m using the STM32F429I-Discovery board.
I’m trying to generate an external clock (XCLK, about 24 MHz) for a camera module from TIM1 CH1 (PA8), but the PWM waveform doesn’t look correct on the oscilloscope.
A square wave appears, but the voltage never drops to 0 V and the waveform is distorted.

Here are my settings and environment:

  • Board: STM32F429I-Discovery

  • IDE: STM32CubeIDE 1.19.0

  • Clock config: PLL = HSE (8 MHz) × 360 / 2 = 180 MHz

  • TIM1: Prescaler = 0, Period = 7 (≈ 22.5 MHz output)

  • PWM mode: PWM1, Duty = 50 %

  • GPIO: PA8 (AF1, Push-Pull, Very High Speed)

  • __HAL_TIM_MOE_ENABLE(&htim1); is called

  • Observation: square wave visible, but it does not go down to 0 V

Could anyone suggest possible causes or points to check?
I suspect a GPIO AF conflict or initialization order issue, but I’m not sure.

Thank you in advance for your help.

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Nov 12, 2025 4:11 PM UTC

PA8 has a 4K7 pull and is connected too the STMPE811QTR, across the board, and to multiple headers

Try and find a pin that's less conflicted.

Use scope probe in 10X mode, and appropriate settings.

Does it look better at lower frequencies?

 

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

12 replies

MGogr.1
Senior
Nov 12, 2025 7:08 AM UTC

If it does not goes to 0v then can you please tell how much it remains??

Associate III
Nov 12, 2025 7:39 AM UTC

Thank you for replying.

My PWM signal doesn’t drop to 0 V.
The oscilloscope reads: max 2.72 V, min 1.60 V, average 2.192 V.
I’ve attached the scope screenshot for reference—could you please take a look?

MGogr.1
Senior
Dec 2, 2025 5:25 AM UTC

Sorry for not replying earlier as I got busy with other projects.

Glad to hear that issue has been resolved. 

TDK
Nov 12, 2025 3:52 PM UTC

The scope plot show a square wave which has been smoothed out due to excess capacitance on the line. The line may only be this way when you have a probe attached. Some thing you can do:

  • Ensure pin speed is set to VERY HIGH.
  • Ensure scope probes are in 10x mode to reduce capacitance on line.
  • Is anything else connected to that pin? Disconnect it.
  • Measure the signal directly at the pin and using a nearby ground.

Looks like the signal is roughly 20 MHz, which the STM32 can drive without issue and much cleaner than what is shown.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate III
Nov 13, 2025 5:58 AM UTC

I have already tried everything you suggested:

  • set the pin speed to VERY HIGH,

  • switched the oscilloscope probe to 10x,

  • ensured nothing else is connected to the pin,

  • and measured with a short ground lead near the pin.

Unfortunately, the waveform did not change at all.

If there are any other possible causes or checks I should perform, I would appreciate your advice.

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Nov 12, 2025 4:11 PM UTC

PA8 has a 4K7 pull and is connected too the STMPE811QTR, across the board, and to multiple headers

Try and find a pin that's less conflicted.

Use scope probe in 10X mode, and appropriate settings.

Does it look better at lower frequencies?

 

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Associate III
Nov 13, 2025 6:01 AM UTC

Thank you for your suggestions.
I changed the pin speed to VERY HIGH and checked the probe settings as you described.
However, the waveform did not change.

One thing I would like to mention is that I could generate a proper PWM on the same pin with the same frequency before.
That’s why I feel there might be some other issue (maybe with my current firmware or the board configuration).

If you have any further ideas about what could cause this, I would really appreciate it.

RobK1
Associate II
Nov 13, 2025 12:19 PM UTC

You do not, by any chance, have the bandwidth limiting on your scope enabled?

TDK
Nov 14, 2025 4:43 PM UTC

It's excess capacitance. Keep checking. ESD damage would tend to skew the signal to 0 V or 3.3 V, not midline. Missing something. Verify the pin can output 0 V and 3.3 V cleanly when set to output mode.

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