2020-12-08 07:35 AM
i am trying to read two timers frequency count and store in DMA , here i have configured two timers in TIM2_CH1, TIM5_CH2 in the input capture direct mode. i used HAL_TIM_IC_Start_DMA() functions to get frequency into DMA . is it correct approach .
i thought when we configure HAL_TIM_IC_Start_DMA() the Channel count wil store in DMA, but in some STM32 examples i saw few of are doing capture and compare and difference why we need this , when we configure in HAL_TIM_IC_Start_DMA() we get directly get into DMA and we will read back whenever required . i am searching on this from last one month still i didn't clarity . if one help it would be great please see my code and suggest me.
The frequency count and store in DMA for every 1sec using systic timer
=====================================================================
TIM2_CH1, TIM5_CH4 :32 bit Timers
The TIM2, TIM5 intilized in input capture direct mode configured as acounter mode start counting the frequency
volatile uint32_t uFrequency1=0,uFrequency2=0;
volatile uint32_t vuPreviousFreqCnt1 = 0,vuPreviousFreqCnt2 = 0;
uint8_t uFREQUENCY_INPUT_1, uFREQUENCY_INPUT_2;
uint32_t ret =0;
uint32_t ucapture_count1[IC_BufSize] = {0x00000000}; // DMA buffer of CH1 used to store rising edge capture data
uint32_t ucapture_count2[IC_BufSize] = {0x00000000}; // DMA buffer of CH1 used to store rising edge capture data
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim5;
extern DMA_HandleTypeDef hdma_tim2_ch1;
extern DMA_HandleTypeDef hdma_tim5_ch4_trig;
int main ()
{
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
MX_TIM5_Init();
FrqCnt_init();
return (0);
}
/*Getting the frquency count */
void FrqCnt_init()
{
if(HAL_TIM_IC_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t *)ucapture_count1, IC_BufSize) != HAL_OK); // Get the T2 frquency count input capture mode
{
/* Error Code */
Diag_SetErrorCode(ERROR_CODE_FI_ERR);
}
htim2.State = HAL_TIM_STATE_READY;
if(HAL_TIM_IC_Start_DMA(&htim5, TIM_CHANNEL_4, (uint32_t *)ucapture_count2, IC_BufSize) != HAL_OK);// Get the T5 frquency count input capture mode
{
/* Error Code */
Diag_SetErrorCode(ERROR_CODE_FI_ERR);
}
}
/*frquency Deintlize fun */
void Freq_DeInit(void)
{
HAL_TIM_IC_Stop_DMA(&htim2, TIM_CHANNEL_1);
HAL_TIM_IC_Stop_DMA(&htim5, TIM_CHANNEL_4);
}
/* TIM2 init function */
void MX_TIM2_Init(void)
{
TIM_IC_InitTypeDef sConfigIC;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xffffffff;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_IC_Init(&htim2);
htim2.Instance->CR1 &= ~(1<<0); //clear counter register
htim2.Instance->CNT = 0; //initialy counter zero
htim2.Instance->EGR = 0; //Update event can be generated at each counter overflow desabled
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
}
/* TIM5 init function */
void MX_TIM5_Init(void)
{
TIM_IC_InitTypeDef sConfigIC;
htim5.Instance = TIM5;
htim5.Init.Prescaler = 0;
htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
htim5.Init.Period = 0xffffffff;
htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_IC_Init(&htim5);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
HAL_TIM_IC_ConfigChannel(&htim5, &sConfigIC, TIM_CHANNEL_4);
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef* htim_ic)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (htim_ic->Instance == TIM2) {
/* Peripheral clock enable */
__TIM2_CLK_ENABLE();
/**TIM2 GPIO Configuration
PA5 ------> TIM2_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
// GPIO_InitStruct.Alternate = GPIO_AF2_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_tim2_ch1.Instance = DMA1_Stream5;
hdma_tim2_ch1.Init.Channel = DMA_CHANNEL_3;
hdma_tim2_ch1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim2_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim2_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim2_ch1.Init.Mode = DMA_NORMAL;
hdma_tim2_ch1.Init.Priority = DMA_PRIORITY_LOW;
hdma_tim2_ch1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one channel to perform all the requested DMAs. */
__HAL_LINKDMA(htim_ic, hdma[TIM_DMA_ID_CC1], hdma_tim2_ch1);
}
if (htim_ic->Instance == TIM5) {
/* Peripheral clock enable */
__TIM5_CLK_ENABLE();
/* Peripheral DMA init*/
hdma_tim5_ch4_trig.Instance = DMA1_Stream1;
hdma_tim5_ch4_trig.Init.Channel = DMA_CHANNEL_6;
hdma_tim5_ch4_trig.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim5_ch4_trig.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim5_ch4_trig.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim5_ch4_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim5_ch4_trig.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim5_ch4_trig.Init.Mode = DMA_NORMAL;
hdma_tim5_ch4_trig.Init.Priority = DMA_PRIORITY_LOW;
hdma_tim5_ch4_trig.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tim5_ch4_trig);
/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one channel to perform all the requested DMAs. */
__HAL_LINKDMA(htim_ic, hdma[TIM_DMA_ID_CC1], hdma_tim5_ch4_trig);
}
}
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
// __DMA1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// /* DMA1_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}