2021-04-01 11:13 PM
I want to print out 5 waveforms during 1us.
So, I printed out 5 MHz period PWM from TIM3.
We tried to change the duty cycle of TIM3 to zero at interrupt time by running a 1 MHz timer counter on TIM6. However, it was confirmed that TIM6's 1 MHz timer counter interrupt failed to generate a signal for re-timing. Do you know the solution?
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
while (1)
{
uint8_t dater;
HAL_UART_Receive(&huart6, &dater, sizeof(dater), 10);
if(dater=='p'){
dater=0;
a=1;
}
if(a==1){
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, ADC_BUF_LEN);
TIM6->ARR=41;
TIM3->CCR1=7;
a=0;
}
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance ==TIM6){
TIM3->CCR1=0;
TIM6->ARR=0;
}
}
2021-04-02 02:35 AM
Which STM32?
Do I understand correctly that you want to generate exactly 5 pulses within one microsecond, and then stop generating futher pulses?
This may be the consequence of setting ARR-preload during initialization, together with ARR=0 ("Period"). So try to look at that first.
But also expecting sub-microsecond precision from interrupts is generally unreasonable. So try to solve this entirely in hardware.
The easiest way is to use the Repetition Count (TIMx_RCR) together with one-pulse mode, but RCR is generally available only in the Advanced timers (TIM1/TIM8/TIM2, but also in TIM15/TIM16/TIM17).
A slightly more complicated but still viable option is to set the "main" timer generating the pulses, as a slave in Gated mode, and a suitable other timer (not TIM6) as Master, generating a 1us pulse as TRGO.
JW
2021-04-02 06:17 AM
i am use stm32f407ve
2021-04-02 08:00 AM
As I've said, the easiest is to use TIM1 or TIM8, set one-pulse mode (TIMx_CR1.OPM) and RCR = 4 (= 5 - 1). Set also ARR right at the beginning to the required value, just don't enable the timer yet.
When you need the 5 pulses, simply enable the timer. It will disable itself automatically after the 5 pulses.
JW
2021-04-03 10:45 AM
i am use stm32cubeide
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 33-1;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 5-1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 33/2-1;
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_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != 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.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
I set it like this
Start is HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
Is this right?