OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1620|回复: 1

输入捕获+DMA会有异常

[复制链接]

5

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2018-1-15
在线时间
22 小时
发表于 2018-10-30 22:02:07 | 显示全部楼层 |阅读模式
20金钱


目前思路为:将定时器设定为上升沿捕获,取两次上升沿的值捕获的值透过DMA直接传输给,再将两次内存相减得到周期。
同时对TIM3CH1 与 TIM4CH2 进行相同操作,但一段时间后就会出现数据溢出的情形如图所示。


[mw_shl_code=c,true]#include "timer.h"
#include "delay.h"
#include "math.h"
TIM_HandleTypeDef TIM3_Handler;
TIM_HandleTypeDef TIM4_Handler;
DMA_HandleTypeDef TIM3_capture_handler;
DMA_HandleTypeDef TIM4_capture_handler;
                       
u32        TIM3CH1_CAPTURE_VAL[2];
u32 TIM3CH1_COPY_VALUE[2];
int TIM3_Capture_value;
int TIM3_temp;
       
u32        TIM4CH2_CAPTURE_VAL[2];
u32 TIM4CH2_COPY_VALUE[2];
int TIM4_Capture_value;
int TIM4_temp;

void TIM3_CH1_Cap_Init(u32 arr,u16 psc)
{
        TIM_IC_InitTypeDef TIM3_CH1Config;
        TIM3_Handler.Instance = TIM3;
        TIM3_Handler.Init.Prescaler = psc;
        TIM3_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
        TIM3_Handler.Init.Period = arr;
        TIM3_Handler.Init.ClockDivision= TIM_CLOCKDIVISION_DIV1;
        HAL_TIM_IC_Init(&TIM3_Handler);
       
        TIM3_CH1Config.ICPolarity = TIM_ICPOLARITY_RISING; //¤W¤é½t®·àò
        TIM3_CH1Config.ICSelection = TIM_ICSELECTION_DIRECTTI;
        TIM3_CH1Config.ICPrescaler = TIM_ICPSC_DIV1;
        TIM3_CH1Config.ICFilter = 5;
        HAL_TIM_IC_ConfigChannel(&TIM3_Handler,&TIM3_CH1Config,TIM_CHANNEL_1);
       
        HAL_TIM_IC_Start_DMA(&TIM3_Handler,TIM_CHANNEL_1,(uint32_t*)&TIM3CH1_CAPTURE_VAL,2);
        //HAL_TIM_IC_Start_IT(&TIM3_Handler,TIM_CHANNEL_1);
        __HAL_TIM_ENABLE_DMA(&TIM3_Handler, TIM_DMA_CC1);
        //HAL_TIM_DMABurst_ReadStart
       
}


void TIM4_CH2_Cap_Init(u32 arr,u16 psc)
{
        TIM_IC_InitTypeDef TIM4_CH1Config;
        TIM4_Handler.Instance = TIM4;
        TIM4_Handler.Init.Prescaler = psc;
        TIM4_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
        TIM4_Handler.Init.Period = arr;
        TIM4_Handler.Init.ClockDivision= TIM_CLOCKDIVISION_DIV1;
        HAL_TIM_IC_Init(&TIM4_Handler);
       
        TIM4_CH1Config.ICPolarity = TIM_ICPOLARITY_RISING; //¤W¤é½t®·àò
        TIM4_CH1Config.ICSelection = TIM_ICSELECTION_DIRECTTI;
        TIM4_CH1Config.ICPrescaler = TIM_ICPSC_DIV1;
        TIM4_CH1Config.ICFilter = 5;
        HAL_TIM_IC_ConfigChannel(&TIM4_Handler,&TIM4_CH1Config,TIM_CHANNEL_2);
       
        HAL_TIM_IC_Start_DMA(&TIM4_Handler,TIM_CHANNEL_2,(uint32_t*)&TIM4CH2_CAPTURE_VAL,2);
        //HAL_TIM_IC_Start_IT(&TIM3_Handler,TIM_CHANNEL_1);
        __HAL_TIM_ENABLE_DMA(&TIM4_Handler, TIM_DMA_CC2);
        //HAL_TIM_DMABurst_ReadStart
       
}
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
        GPIO_InitTypeDef GPIO_Initure;
        if(htim->Instance==TIM3)
                {
                        __HAL_RCC_GPIOA_CLK_ENABLE();                       
                        __HAL_RCC_TIM3_CLK_ENABLE();                       
                        __HAL_RCC_DMA1_CLK_ENABLE();
                        GPIO_Initure.Pin=GPIO_PIN_6;                        //PA6
                        GPIO_Initure.Mode=GPIO_MODE_AF_PP;       
                        GPIO_Initure.Pull=GPIO_PULLUP;               
                        GPIO_Initure.Speed=GPIO_SPEED_HIGH;               
                        GPIO_Initure.Alternate=GPIO_AF2_TIM3;       
                        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                        
                       
                        TIM3_capture_handler.Instance=DMA1_Stream4;                        
                        TIM3_capture_handler.Init.Channel=DMA_CHANNEL_5;                     
                        TIM3_capture_handler.Init.Direction=DMA_PERIPH_TO_MEMORY;           
                        TIM3_capture_handler.Init.PeriphInc=DMA_PINC_DISABLE;               
                        TIM3_capture_handler.Init.MemInc=DMA_MINC_ENABLE;                     
                        TIM3_capture_handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;   
                        TIM3_capture_handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;     
                        TIM3_capture_handler.Init.Mode=DMA_CIRCULAR;//DMA_NORMAL;                  
                        TIM3_capture_handler.Init.Priority=DMA_PRIORITY_HIGH;               
                        TIM3_capture_handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
                        //hdma_adc.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL;      
                        TIM3_capture_handler.Init.MemBurst=DMA_MBURST_SINGLE;            
                        TIM3_capture_handler.Init.PeriphBurst=DMA_PBURST_SINGLE;            
                        HAL_DMA_DeInit(&TIM3_capture_handler);   
                        HAL_DMA_Init(&TIM3_capture_handler);
                        __HAL_LINKDMA(htim,hdma[TIM_DMA_ID_CC1],TIM3_capture_handler);   

                        HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);               
                        HAL_NVIC_SetPriority(DMA1_Stream4_IRQn,0,0);               
       
                }
                        if(htim->Instance==TIM4)
                {
                        __HAL_RCC_GPIOB_CLK_ENABLE();               
                        __HAL_RCC_TIM4_CLK_ENABLE();               
                        __HAL_RCC_DMA1_CLK_ENABLE();
                        GPIO_Initure.Pin=GPIO_PIN_7;
                        GPIO_Initure.Mode=GPIO_MODE_AF_PP;               
                        GPIO_Initure.Pull=GPIO_PULLUP;                       
                        GPIO_Initure.Speed=GPIO_SPEED_HIGH;               
                        GPIO_Initure.Alternate=GPIO_AF2_TIM4;
                        HAL_GPIO_Init(GPIOB,&GPIO_Initure);                
               
                        TIM4_capture_handler.Instance=DMA1_Stream3;                        
                        TIM4_capture_handler.Init.Channel=DMA_CHANNEL_2;                     
                        TIM4_capture_handler.Init.Direction=DMA_PERIPH_TO_MEMORY;           
                        TIM4_capture_handler.Init.PeriphInc=DMA_PINC_DISABLE;               
                        TIM4_capture_handler.Init.MemInc=DMA_MINC_ENABLE;                     
                        TIM4_capture_handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;   
                        TIM4_capture_handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;     
                        TIM4_capture_handler.Init.Mode=DMA_CIRCULAR;//DMA_NORMAL;                  
                        TIM4_capture_handler.Init.Priority=DMA_PRIORITY_HIGH;               
                        TIM4_capture_handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
                        //hdma_adc.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL;      
                        TIM4_capture_handler.Init.MemBurst=DMA_MBURST_SINGLE;            
                        TIM4_capture_handler.Init.PeriphBurst=DMA_PBURST_SINGLE;            
                        HAL_DMA_DeInit(&TIM4_capture_handler);   
                        HAL_DMA_Init(&TIM4_capture_handler);
                        __HAL_LINKDMA(htim,hdma[TIM_DMA_ID_CC2],TIM4_capture_handler);   

                        HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);               
                        HAL_NVIC_SetPriority(DMA1_Stream3_IRQn,0,0);               
       
                }
}
void DMA1_Stream4_IRQHandler(void)
{
        if(__HAL_TIM_GET_FLAG(&TIM3_Handler,TIM_FLAG_CC1)!=RESET)
        {
        HAL_TIM_IC_Stop_DMA(&TIM3_Handler,TIM_CHANNEL_1);                                        // Stops the DMA Transfer.       
  HAL_DMA_IRQHandler(&TIM3_capture_handler);
        }
}
void DMA1_Stream3_IRQHandler(void)
{
        if(__HAL_TIM_GET_FLAG(&TIM4_Handler,TIM_FLAG_CC2)!=RESET)
        {
                HAL_TIM_IC_Stop_DMA(&TIM4_Handler,TIM_CHANNEL_2);
                HAL_DMA_IRQHandler(&TIM4_capture_handler);
        }
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
      if(htim == &TIM3_Handler)           // Checks whitch Timer
                {
                        TIM3_Capture_value=0;
                        SCB_DisableDCache();
                        __HAL_TIM_CLEAR_FLAG(htim,TIM_FLAG_CC1);       // Clears the  flag.
                        TIM3_Capture_value=TIM3CH1_CAPTURE_VAL[1]-TIM3CH1_CAPTURE_VAL[0];
                        //printf("TIM3= %d\t %d\n",TIM3CH1_CAPTURE_VAL[1],TIM3CH1_CAPTURE_VAL[0]);
                        //printf("TIM3= %d\t %d\n",TIM3CH1_CAPTURE_VAL[1],TIM3CH1_CAPTURE_VAL[0]);
                        SCB_EnableDCache();
                        __HAL_TIM_SET_COUNTER(&TIM3_Handler,0);
                        HAL_TIM_IC_Start_DMA(&TIM3_Handler,TIM_CHANNEL_1,(uint32_t*)&TIM3CH1_CAPTURE_VAL,2);
                }
                                       
      if(htim == &TIM4_Handler)           // Checks whitch Timer
                {
                        TIM4_Capture_value=0;
                        SCB_DisableDCache();
                        __HAL_TIM_CLEAR_FLAG(htim,TIM_FLAG_CC2);       // Clears the  flag.
                        TIM4_Capture_value=TIM4CH2_CAPTURE_VAL[1]-TIM4CH2_CAPTURE_VAL[0];
                        //printf("TIM4= %d\t %d\n",TIM4CH2_CAPTURE_VAL[1],TIM4CH2_CAPTURE_VAL[0]);
                        SCB_EnableDCache();
                        __HAL_TIM_SET_COUNTER(&TIM4_Handler,0);
                        HAL_TIM_IC_Start_DMA(&TIM4_Handler,TIM_CHANNEL_2,(uint32_t*)&TIM4CH2_CAPTURE_VAL,2);
                }
}[/mw_shl_code]
代码如下,请各位大佬指点

数值溢出

数值溢出
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-10-31 01:05:50 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 14:28

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表