Skip to main content
Eliso
Associate II
April 9, 2021
Question

How to generate a 1000Hz signal on PC7 using TIM3 or TIM8 on STM32L476QE 80MHz. Using a prescaler 1000.

  • April 9, 2021
  • 20 replies
  • 3913 views

With the SW generated by MX as example I have a timer that seems to work, but not a signal on PC7.

This topic has been closed for replies.

20 replies

waclawek.jan
Super User
April 9, 2021

As a test, set it as GPIO output and toggle.

JW

Eliso
ElisoAuthor
Associate II
April 9, 2021
I did some change in SW generated by MX (lines marked as sujested) , but possibly I didn´t understood your suggestion. With this change does not work. void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspPostInit 0 */ /* USER CODE END TIM8_MspPostInit 0 */ __HAL_RCC_GPIOC_CLK_ENABLE(); /**TIM8 GPIO Configuration PC7 ------> TIM8_CH2 */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USER CODE BEGIN TIM8_MspPostInit 1 */ /* USER CODE END TIM8_MspPostInit 1 */ } } void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspInit 0 */ /* USER CODE END TIM3_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_TIM8_CLK_ENABLE(); /* USER CODE BEGIN TIM3_MspInit 1 */ /* USER CODE END TIM8_MspInit 1 */ } } /** * @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example * @param htim_base: TIM_Base handle pointer * @retval None */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM8) { /* USER CODE BEGIN TIM8_MspDeInit 0 */ /* USER CODE END TIM3_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM8_CLK_DISABLE(); /* USER CODE BEGIN TIM3_MspDeInit 1 */ /* USER CODE END TIM8_MspDeInit 1 */ } } /** * @brief TIM3 Initialization Function * @param None * @retval None */ void BuzzerInit(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; /* USER CODE BEGIN TIM8_Init 1 */ /* USER CODE END TIM8_Init 1 */ htim8.Instance = TIM8; htim8.Init.Prescaler = 1000; htim8.Init.CounterMode = TIM_COUNTERMODE_UP; htim8.Init.Period = 39; htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim8.Init.RepetitionCounter = 0; htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim8) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_OC_Init(&htim8) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; // SUGEST was TIM_OCMODE_TIMING; sConfigOC.Pulse = 0; 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_OC_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != 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.BreakFilter = 0; sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE; sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH; sBreakDeadTimeConfig.Break2Filter = 0; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; // SUGESTED was TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM8_Init 2 */ /* USER CODE END TIM8_Init 2 */ HAL_TIM_MspPostInit(&htim8); CLEAR_BIT(htim8.Instance->CR1, TIM_CR1_CEN); } Em sex., 9 de abr. de 2021 às 11:16, ST Community escreveu:
Mike_ST
ST Technical Moderator
April 9, 2021

I suggest that you show main.c and attach .ioc file so people might be able to help.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. 
Eliso
ElisoAuthor
Associate II
April 9, 2021
Thanks for your answer. Em sex., 9 de abr. de 2021 às 11:27, ST Community escreveu:
waclawek.jan
Super User
April 9, 2021

My point is, that your hardware might be faulty (bad solder joint, some other problem on your board), and you can easily find it out by toggling the pin as GPIO, exactly as when blinking a LED.

JW

Eliso
ElisoAuthor
Associate II
April 9, 2021
Yes this is ever possible. But generation of 1000Hz by SW on the same HW and pin works. Em sex., 9 de abr. de 2021 às 12:01, ST Community escreveu:
waclawek.jan
Super User
April 9, 2021

Read out and check/post the TIM and relevant GPIO registers content.

Note that TIM8 is an Advanced Timer, so it has to have TIMx_BDTR.MOE set.

> CLEAR_BIT(htim8.Instance->CR1, TIM_CR1_CEN);

This will stop the timer.

JW

Eliso
ElisoAuthor
Associate II
April 9, 2021
Hi annexed there is imagens of TIM8 and GPIOC registers now with MOE setted. Em sex., 9 de abr. de 2021 às 13:18, ST Community escreveu:
waclawek.jan
Super User
April 9, 2021

Image paste does not work here, even if it appears that it does.

Please upload it as a file - click on the "image" icon in the bar at bottom of edit window.

Please make sure the values are not displayed as decimal.

JW

Eliso
ElisoAuthor
Associate II
April 9, 2021
Sorry, I´m sending as txt file. Em sex., 9 de abr. de 2021 às 18:16, ST Community escreveu:
DavidAlfa
Senior II
April 9, 2021

sConfigOC.Pulse = 0;

Also, prescaler should be 999.

Shouldn't you put a value here?

Like 50% of the timer period. Whatever, but not 0.

0 will never trigger the OC.

Also, why run the timer at 2KHz to toggle the output and achieve 1KHz.

You can just set it into PWM mode.

Pre=999

Period=79

Pulse=39

Start PWM and it'll be toggling the output at 1KHz.

Eliso
ElisoAuthor
Associate II
April 10, 2021
I test putting sConfigOC.Pulse = 20; but nothing change on PC7. Em sex., 9 de abr. de 2021 às 20:03, ST Community escreveu:
waclawek.jan
Super User
April 10, 2021

Are you trying to send the registers content through e-mail? Nothing arrived here.

If so, can you please do it through the web interface.

Or just enter it as plain text into the message, once you have it in text form.

JW

Eliso
ElisoAuthor
Associate II
April 10, 2021
I´m sending the register content. Em sáb., 10 de abr. de 2021 às 05:12, ST Community escreveu:
DavidAlfa
Senior II
April 10, 2021

Export the project in zip and upload here.

Delete Debug and Release folders, they take a lot of space.

waclawek.jan
Super User
April 10, 2021

Sending e-mails with attachments to this forum apparently does not work.

Please use the web interface.

JW

Eliso
ElisoAuthor
Associate II
April 10, 2021
memory GPIOC 0x48000800 FFFFBFFF 00000000 00000000 00000000 0x48000810 00000000 00000000 00000000 00000000 0x48000820 30000000 00000000 00000000 00000000 0x48000830 00000000 00000000 00000000 00000000 0x48000840 00000000 00000000 00000000 00000000 0x48000850 00000000 00000000 00000000 00000000 0x48000860 00000000 00000000 00000000 00000000 Memory TIM8 0x40013400 00000001 00000000 00000000 00000000 0x40013410 0003001f 00000000 00000000 00000000 0x40013420 00000000 00000020 000003e8 00000027 0x40013430 00000000 00000000 00000000 00000000 0x40013440 00000000 00008000 00000000 00000001 0x40013450 00000000 00000000 00000000 00000000 0x40013460 00000001 00000001 00000000 00000000 0x40013470 00000000 00000000 00000000 00000000 0x40013480 00000000 00000000 00000000 00000000 0x40013490 00000000 00000000 00000000 00000000 0x400134A0 00000000 00000000 00000000 00000000 0x400134B0 00000000 00000000 00000000 00000000 0x400134C0 00000000 00000000 00000000 00000000 0x400134D0 00000000 00000000 00000000 00000000 0x400134E0 00000000 00000000 00000000 00000000 Em sáb., 10 de abr. de 2021 às 12:53, ST Community escreveu:
waclawek.jan
Super User
April 10, 2021

GPIOC is OK.

00000001 __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
00000000 __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
00000000 __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
00000000 __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
0003001f __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */
00000000 __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
00000000 __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
00000000 __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
00000000 __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
00000020 __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
000003e8 __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
00000027 __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
00000000 __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
00000000 __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
00000000 __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
00000000 __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
00000000 __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
00008000 __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
00000000 __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
00000001 __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
00000000 __IO uint32_t OR1; /*!< TIM option register 1, Address offset: 0x50 */
00000000 __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x54 */
00000000 __IO uint32_t CCR5; /*!< TIM capture/compare register5, Address offset: 0x58 */
00000000 __IO uint32_t CCR6; /*!< TIM capture/compare register6, Address offset: 0x5C */
00000001 __IO uint32_t OR2; /*!< TIM option register 2, Address offset: 0x60 */
00000001 __IO uint32_t OR3; /*!< TIM option register 3, Address offset: 0x64 */
 

This is a running timer, but channel 2 is not set to PWM. You need to:

  • set TIM8_CCMR1.OC2M to one of the PWM modes, i.e. to 6 or 7 (0b110 or 0b111)
  • set TIM8_CCER.CC2E in order to enable that channel's output
  • set TIM8_CCR2 to nonzero value less than what's in TIM8_ARR

I don't use Cube so I don't know how to do that in Cube.

JW

Eliso
ElisoAuthor
Associate II
April 11, 2021
Hi Very thanks, JW. It is working, it works fine also using the compare without PWM. Eliso I Em sáb., 10 de abr. de 2021 às 17:51, ST Community escreveu: