2024-11-03 02:14 PM
Hello, i have a stm32wb15cc
i'm trying to make a hold button, that toggles a led on/off when pressed for 2 seconds. my HCLK1 is running at 4Mhz and my prescaler is at 3999, meaning it should count up every 1ms. I'm using TIM1 which is a 16bit timer, so the counter overflows every 65 seconds.
the program works as intended for the first 65 seconds, but after that the timer is stuck at 0.
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 3999;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
}
int main(void)
{
/* USER CODE BEGIN 1 */
bool hasBeenPressed = false;
uint16_t timer_value;
/* 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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Initialize leds */
BSP_LED_Init(LED_BLUE);
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_RED);
/* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI);
BSP_PB_Init(BUTTON_SW2, BUTTON_MODE_EXTI);
BSP_PB_Init(BUTTON_SW3, BUTTON_MODE_EXTI);
/* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
BspCOMInit.BaudRate = 115200;
BspCOMInit.WordLength = COM_WORDLENGTH_8B;
BspCOMInit.StopBits = COM_STOPBITS_1;
BspCOMInit.Parity = COM_PARITY_NONE;
BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;
if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
{
Error_Handler();
}
/* USER CODE BEGIN BSP */
BSP_LED_Off(LED_BLUE);
BSP_LED_Off(LED_GREEN);
BSP_LED_Off(LED_RED);
/* USER CODE END BSP */
/* USER CODE BEGIN WHILE */
HAL_TIM_Base_Start(&htim1);
timer_value = __HAL_TIM_GET_COUNTER(&htim1);
while (1)
{
if(HAL_GPIO_ReadPin(GPIOA, Green_button_Pin))
{
BSP_LED_On(LED_RED);
BSP_LED_Off(LED_BLUE);
if(!hasBeenPressed && __HAL_TIM_GET_COUNTER(&htim1) - timer_value >= 2000)
{
hasBeenPressed = true;
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_3);
BSP_LED_Toggle(LED_GREEN);
timer_value = __HAL_TIM_GET_COUNTER(&htim1);
}
}
else
{
hasBeenPressed = false;
timer_value = __HAL_TIM_GET_COUNTER(&htim1);
BSP_LED_Off(LED_RED);
BSP_LED_On(LED_BLUE);
}
if(__HAL_TIM_GET_COUNTER(&htim1) <= 10)
{
BSP_LED_On(LED_GREEN);
}
else
{
BSP_LED_Off(LED_GREEN);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Solved! Go to Solution.
2024-11-03 02:20 PM - edited 2024-11-03 02:21 PM
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
So it does exactly this: the OnePulse mode means, that the timer is stopped after CNT reaches ARR value.
JW
2024-11-03 02:20 PM - edited 2024-11-03 02:21 PM
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
So it does exactly this: the OnePulse mode means, that the timer is stopped after CNT reaches ARR value.
JW