cancel
Showing results for 
Search instead for 
Did you mean: 

Difficulty configuring TIM16 for simple PWM output on STM32G483

SSton.1
Associate III

I am working on an STM32G483VET6 in my own hardware. I am trying to use TIM16 CH1 (pin PE0) to generate a PWM signal which drives a sounder. I believe that in early tests I verified that it was working but I was probably messing around manually with register values in the debugger. I therefore think that my initialisation code is wrong but I can’t see why.

First of all, the pin is correctly connected; if I configure PEO as a GPIO output by setting the MODER bits for PE0 to 2 (output) and set PE0 high or low in the ODR, the output value gets to the sounder.

So far TIM16 is running in PWM mode, I can see the CNT register running up to ARR

and resetting but it the PE0 is tri-state when configured to be the output for TIM16_CH1.

Rather than paste pages of code, these are the values in the relevant GPIOE and TIM16 registers I observe in the stopped debugger when I believe that PE0 should be driven by TIM16_CH1 but is tri-state:

GPIOE registers	Bits	Value	Comment
MODER		[0:1]	0x2	Alternate function
AFRL0		0x4		PE0=AF4 (TIM16_CH1)

 I think the PE0 is correctly mapped to TIM16_CH1.

The HRM says that "tim_ocx output is enabled by a

combination of the CCxE, CCxNE, MOE, OSSI and OSSR bits (TIMx_CCER and

TIMx_BDTR registers).�?

Relevant TIM16 Register values observed are:

Register CCER
CC1NP	0
CC1NE	0
CC1P	0
CC1E	1           
 
                           
 
Register BDTR
MOE	1
OSSI	0
OSSR	0

I think that according to HRM0440 Rev 7 (Table 303), the output control for TIM16_CH1 should be being driven but it isn’t.

Is there anything else that needs setting up to get the pin correctly driven?

1 ACCEPTED SOLUTION

Accepted Solutions

That was a good thought, @Community member​ , thanks - I hadn't checked the CC1E bit in CCMR1, but it was actually set correctly. That looks like an omission in section 28.3.13 of the HRM not to mention this.

The fault turned out to be an incomplete initialisation of the TIM_OC_InitTypeDef variable used by the HAL to configure TIM16. This was causing random bits to be written into CR2 (none of which ought to cause a tristate output, as far as I can see).

	TIM_OC_InitTypeDef sConfigOC;
	timer.Init.Period = period; // set the period duration
	HAL_TIM_PWM_Init(&timer); // reinititialise with new period value
 
	sConfigOC.OCMode = TIM_OCMODE_PWM1;
	sConfigOC.Pulse = pulse; // set the pulse duration
	sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
	HAL_TIM_PWM_ConfigChannel(&timer, &sConfigOC, channel);
SABLE;

Zeroing the sConfigOC contents when declared and before use worked.

TIM_OC_InitTypeDef sConfigOC = {0};

Obviously, not fully initialising it was asking for trouble.

View solution in original post

3 REPLIES 3

Everything you've shown looks OK, but are you sure the channel is set as output, i.e. check CCMR1, or post all TIM16 registers content.

JW

That was a good thought, @Community member​ , thanks - I hadn't checked the CC1E bit in CCMR1, but it was actually set correctly. That looks like an omission in section 28.3.13 of the HRM not to mention this.

The fault turned out to be an incomplete initialisation of the TIM_OC_InitTypeDef variable used by the HAL to configure TIM16. This was causing random bits to be written into CR2 (none of which ought to cause a tristate output, as far as I can see).

	TIM_OC_InitTypeDef sConfigOC;
	timer.Init.Period = period; // set the period duration
	HAL_TIM_PWM_Init(&timer); // reinititialise with new period value
 
	sConfigOC.OCMode = TIM_OCMODE_PWM1;
	sConfigOC.Pulse = pulse; // set the pulse duration
	sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
	HAL_TIM_PWM_ConfigChannel(&timer, &sConfigOC, channel);
SABLE;

Zeroing the sConfigOC contents when declared and before use worked.

TIM_OC_InitTypeDef sConfigOC = {0};

Obviously, not fully initialising it was asking for trouble.

MaxEE
Associate II

Hello, had a similar issue. Anyway I found out CCER regiser sets in TIM_PWM_Start function calling TIM_CCxChannelCmd function.

MaxEE_0-1731082856679.png

You can find TIM_CCx_ENABLE equals 0x1 and it doesn't change by built-in configurator. You can recalculate register value and put it there to make the driver operating fine according to the rm0454(item 19.6.8 TIMx capture/compare enable register (TIMx_CCER)(x = 16 to 17)). Since the 0x1 match the settings for CH1,  direct PWM option works fine.So just change the TIM_PWM_Start function in xxx_tim.c. or change the CCER register after calling the TIM_PWM_Start function.