STM32 PWM to stop after n pluses
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-21 10:38 PM
Is there a way to stop STM32 PWM after 10 pluses ?
I know one solution is using the system time and issue a stop via the code, however my issue is the stm CPU might be very busy to handle the stop signal.
- Labels:
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-21 10:53 PM
Which STM32?
Use a timer which has the repetition counter (TIM_RTR), see TIM1/TIM8.
If there's no timer with TIM_RTR available, you can use another timer as master, in master-slave configuration, this timer in gated mode. Another option is to use DMA to load 0 into ARR or into CR1. Both these options are more complex than using the repetition counter.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-23 1:25 AM
Thanks for your reply, but how do you load 0 into ARR using DMA ? Is there any example ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-23 10:09 AM
In the same way as you'd write to any other TIM register using DMA. Read the TIM, DMA chapters in the Reference Manual, and the Timer Cookbook application note AN4776.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-23 10:25 AM
Which STM32?
What frequency, and how busy?
The STM32 could get an update interrupt at each pulse. Or at multiples with the repetition count. At 8-bit provides for 1 thru 256 as I recall.
Posted examples to forum before doing N pulse PWM using One-Shot Mode + Repetition Count
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-23 10:38 PM
Thanks for the reply, I tried the TIM DMA, and got the DMA and TIM register to the following settings, however it seems that no interrupt is happening, I don't see the ARR change. Can you help me check if my settings are correct ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-24 5:24 AM
Okay, from the screenshots we can guess it's 'F723. You should've told us.
DMA1 Stream 0 (set to Channel 2) is triggered by TIM4_CH1, you should've set TIM4_DIER.CC1DE for that.
Then that should work, but IMO it's better to leave the trigger from update (DIER.UDE=1 as it is now), and use the respective DMA1 Stream 6 (at channel 2).
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-24 7:07 PM
Hi thanks for the reply ! I have got the interrupt now and the DMA is running, however I encounter something very strange.
so I have set an data array
#define n 9
#define transfer 6
uint32_t buffer[n] = {500, 251, 252, 253, 504, 255, 506, 257, 258};
uint32_t DCR = 0x20B;
and I call the following function to kick start:
HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA_MODIFIED(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
if (htim->State == HAL_TIM_STATE_BUSY)
{
return HAL_BUSY;
}
else if (htim->State == HAL_TIM_STATE_READY)
{
if ((pData == NULL) && (Length > 0U))
{
return HAL_ERROR;
}
else
{
htim->State = HAL_TIM_STATE_BUSY;
}
}
else
{
/* nothing to do */
}
switch (Channel)
{
case TIM_CHANNEL_1:
{
/* Set the DMA compare callbacks */
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
/* Set the DMA error callback */
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
/* Enable the DMA stream */
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->DMAR, Length) != HAL_OK) <----- i Change this from CCR1 to DMAR
{
return HAL_ERROR;
}
/* Enable the TIM Capture/Compare 1 DMA request */
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
break;
}
default:
break;
}
int main(void)
{
...
htim4.Instance->ARR = 1000;
htim4.Instance->CCR1 = 100;
HAL_TIM_PWM_Start_DMA_MODIFIED(&htim4, TIM_CHANNEL_1, buffer, transfer);
...
}
I wired a interrupt pin to the TIM output, and each interrupt i will save ARR and CCR1 to an array:
int arr[100] = {0};
int ccr1[100] = {0};
...
/**
* @brief This function handles EXTI line[9:5] interrupts.
*/
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
if(i<100)
{
arr[i] = htim4.Instance->ARR;
ccr1[i] = htim4.Instance->CCR1;
}else{
//i++;
}
i++;
/* USER CODE END EXTI9_5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
I was expecting:
arr[] = 1000, 500, 253 ...
ccr1[]=100, 251, 253 ...
what I actually got is:
arr[] = 1000, 1000, 252 ...
ccr1[]=100, 251, 504 ...
why is this so strange ? It says in the document if I set DCR to 0x20B, it should DMA 3 element in the array each time the DMA is triggered, why the pattern seems so "random".
here is my register set:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-24 7:59 PM
I don't understand what are you trying to do, but don't use both the CC1DE and UDE - use only UDE and change the DMA stream as I wrote above.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-06-24 8:13 PM
I am trying to change ARR and CCR1 for each and every pulses.
