cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 PWM Duty Cycle Setting.

Karthik DM
Associate III

Hello,

In my motor control project, I'm reading potentiometer value and set it as a duty cycle value. Initially I'm using "htim1.Instance->CCR1 = 50;" this function for pwm. but this is not giving correct phase voltage. Can anyone please tell me which is better way to to set pwm duty cycle.

and difference between htim1.Instance->CCR1 = 0; and TIM1->CCR1 = 50 command.

Thanks

4 REPLIES 4
TDK
Guru

> difference between htim1.Instance->CCR1 = 0; and TIM1->CCR1 = 50 command.

The first sets a value in memory which is used during initialization, but doesn't immediately affect anything. The second modifies the actual timer register and will have an immediate impact.

 

The fastest way would be to modify the register directly.

Modifying htim1.Instance->CCR1 and modifying TIM1->CCR1 do the same thing (assuming htim1 is initialized correctly).

TIM1->CCR1 = 0 will give you a 0% duty cycle

TIM1->CCR1 = TIM1->ARR + 1 will give you a 100% duty cycle

Put it somewhere between those to give your desired result. You can see how having a high ARR (counter period) is beneficial here.

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

htim1.Instance->CCR1 uses the HAL (Hardware Abstraction Layer) to access the CCR1 register indirectly. This provides a more structured and consistent way to manage hardware resources.


TIM1->CCR1 directly accesses the CCR1 register through its memory address. This can be more efficient in terms of code execution but requires a deeper understanding of the hardware registers.


htim1.Instance->CCR1 is typically used within the HAL framework, where the htim1 handle is properly initialized with the relevant timer configuration.


TIM1->CCR1 can be used independently of the HAL, but it's crucial to ensure the timer is correctly configured before using it.


HAL provides abstraction for better portability and code readability.
Direct register access can be more efficient but requires more hardware knowledge.
Initialization:


Ensure proper initialization with HAL or manual configuration for direct access.

 

Avoid mixing HAL and direct register access for the same timer to prevent potential conflicts.
In general, it's recommended to use the HAL-based approach (htim1.Instance->CCR1) for most cases to benefit from its advantages in terms of code structure, readability, and portability. Consider direct register access only when specific performance requirements or hardware-specific optimizations are necessary.

 

Thank you

gbm
Lead III

@Arya1:

1. htim1.Instance->CCR1 does not access the register using HAL. only the HAL data structure is used which results in an extra indirection and slower (but logically equivalent) access.

2. The method does not provide better absrtaction and code portability because it still uses CCR1, which is not abstracted. A more portable way would be: PWM_TIMER->PWM_DUTY, where PWM TIMER is #defined as TIMx, and PWM_DUTY as CCRx.

3. HAL provides better portability at the cost of WORSE readability (and performance), since one must write many more statements using many more strange constants when using HAL vs. when using register access.

4. htim1.Instance->CCR1 does not cause any conflict, it's simply faster than HAL routine call for duty setting but still slower than TIMx->CCR1 (and requires more typing than the latter).

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Arya1
Associate II

yes , you are also right