OpenEdv-开源电子网

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

TIM2和TIM3输入捕获TIM3CH2不进中断

[复制链接]

5

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2019-4-19
在线时间
44 小时
发表于 2020-6-19 17:59:21 | 显示全部楼层 |阅读模式
4金钱
求救大佬们 帮忙找下问题   TIM2CH1输入捕获测量占空比没问题  然后用TIM3 CH2  同样捕获另一路  发现中断不工作   是我哪里出问题了,在线等。


//通道1
u8  TIM2CH1_CAPTURE_STA=0;        //输入捕获状态                                                   
u16        TIM2CH1_CAPTURE_VAL=0;          //输入捕获值
double duty1;

//通道2
u8  TIM3CH2_CAPTURE_STA=0;        //输入捕获状态                                                   
u16        TIM3CH2_CAPTURE_VAL;          //输入捕获值
double duty2;

u32 CH1_Time_High;          //捕获高电平的间隔时间
u32 CH1_Time_Cycle;          //捕获脉冲信号周期时间
u32 CH2_Time_High;          //捕获高电平的间隔时间
u32 CH2_Time_Cycle;           //捕获低电平的间隔时间

//////定时器2通道1输入捕获配置

void TIM2_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef TIM2_ICInitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);         //使能TIM2时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  //PA0、PA1 清除之前设置  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          //PA0 输入  
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_SetBits(GPIOA,GPIO_Pin_0);                                                           //PA0上拉(IO口外部有上拉电阻)
       
        //初始化定时器2 TIM2         
        TIM_TimeBaseStructure.TIM_Period = arr;                          //设定计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;                              //预分频器   
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;          //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;      //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);                  //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        //初始化TIM2通道1输入捕获参数
        TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1;                //CC1S=01         选择输入端 IC1映射到TI1上
  TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;           //上升沿捕获
  TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
  TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                 //配置输入分频,不分频
  TIM2_ICInitStructure.TIM_ICFilter = 0x00;                        //IC1F=0000 配置输入滤波器 不滤波
  TIM_ICInit(TIM2, &TIM2_ICInitStructure);
       
        //中断分组初始化
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;               //从优先级0级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                  //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);                                  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
       
  TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);   //允许更新中断 ,允许CC1IE捕获中断       
       
  TIM_Cmd(TIM2,ENABLE );         //使能定时器2

}



//定时器2中断服务程序         
void TIM2_IRQHandler(void)
{        
        //通道1               
                if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)        //判断更新中断源
                {            
                        if(TIM2CH1_CAPTURE_STA&0X40)                      //已经捕获到高电平了
                        {
                                if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)            //高电平太长了
                                {
                                        TIM2CH1_CAPTURE_STA|=0X80;                    //标记成功捕获了一次
                                        TIM2CH1_CAPTURE_VAL=0XFFFF;
                                }
                                else TIM2CH1_CAPTURE_STA++;
                        }                        
                }
          if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)     //捕获1发生捕获事件
                {       
                        if((TIM2CH1_CAPTURE_STA&0X40)==0X40)                          //捕获到一个下降沿               
                        {          
        TIM2CH1_CAPTURE_STA|=0X80;                               
                                TIM2CH1_CAPTURE_STA&=~(1<<6);                                //标记成功捕获到一次下降沿
                                TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);      //获取触发时计数器值
                                CH1_Time_High=(TIM2CH1_CAPTURE_STA&0X3F)*65536+TIM2CH1_CAPTURE_VAL;  //高电平时长
                               
                                if(CH1_Time_High>65535)                         //判断高电平时间是否超出脉冲信号周期(脉冲信号频率基本固定18-19HZ,此时占空比达到100%)
                                        CH1_Time_High=65535;                          //
                               
                           TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);          //通道1设置为上升沿捕获
                        }
                        else if((TIM2CH1_CAPTURE_STA&0X80)==0)                              //第一次捕获上升沿
                        {       
                          TIM2CH1_CAPTURE_STA=0;                          //清空
                          TIM2CH1_CAPTURE_VAL=0;        //清空
                           TIM_SetCounter(TIM2,0);       //计数器置零
                          TIM2CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿                       
                          TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //通道1设置为下降沿捕获                                  
                        }
      else
                  {
                          TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);      //获取触发时计数器值
                          CH1_Time_Cycle=(TIM2CH1_CAPTURE_STA&0X3F)*65536+TIM2CH1_CAPTURE_VAL;  //获取脉冲信号周期               
                          if(CH1_Time_Cycle>65535)                       //判断整个周期是否超出脉冲信号周期(脉冲信号频率基本固定18-19HZ,此时占空比达到100%)
                                 CH1_Time_Cycle=65535;                          //       
                                duty1=CH1_Time_High*1.0/CH1_Time_Cycle;
                          TIM2CH1_CAPTURE_VAL=0;        //清空
                           TIM_SetCounter(TIM2,0);       //计数器置零       
                                if(duty1==1)
                                        TIM2CH1_CAPTURE_STA=0;
                                else
          TIM2CH1_CAPTURE_STA|=0XC0;                //标记捕获到了上升沿                                 
                          TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //通道1设置为下降沿捕获                                 
                  }                         
                }       
   TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位

}
//////定时器3通道2输入捕获配置

void TIM3_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef TIM3_ICInitStructure;
               
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);         //使能TIM3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能GPIOB时钟
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;             //PB5 清除之前设置  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          //PB5 输入  
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_5);                                                             //PB5 上拉(IO口外部有上拉电阻)
       
        //初始化定时器3 TIM3         
        TIM_TimeBaseStructure.TIM_Period = arr;                          //设定计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler = psc;                              //预分频器   
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;          //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;      //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                  //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        //初始化TIM3通道2输入捕获参数
        TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;                //CC1S=01         选择输入端 IC2映射到TI2上
  TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;           //上升沿捕获
  TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI2上
  TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                 //配置输入分频,不分频
  TIM3_ICInitStructure.TIM_ICFilter = 0x00;                        //IC1F=0000 配置输入滤波器 不滤波
  TIM_ICInit(TIM3, &TIM3_ICInitStructure);
       
        //中断分组初始化
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                  //TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;        //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;               //从优先级0级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                  //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);                                  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
       
  TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC2,ENABLE);              //允许更新中断 ,允许CC1IE捕获中断       
       
  TIM_Cmd(TIM3,ENABLE);         //使能定时器3

}



//定时器3中断服务程序         
void TIM3_IRQHandler(void)
{        
        //通道2       
                if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)        //判断更新中断源
                {            
      if(TIM3CH2_CAPTURE_STA&0X40)                      //已经捕获到高电平了
                        {
                                if((TIM3CH2_CAPTURE_STA&0X3F)==0X3F)            //高电平太长了
                                {
                                        TIM3CH2_CAPTURE_STA|=0X80;                    //标记成功捕获了一次
                                        TIM3CH2_CAPTURE_VAL=0XFFFF;
                                }
                                else TIM3CH2_CAPTURE_STA++;
                        }                                
                }
//通道2               
          if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)     //捕获2发生捕获事件
                {       
                        if((TIM3CH2_CAPTURE_STA&0X40)==0X40)                          //捕获到一个下降沿               
                        {          
        TIM3CH2_CAPTURE_STA|=0X80;                               
                                TIM3CH2_CAPTURE_STA&=~(1<<6);                                //标记成功捕获到一次下降沿
                                TIM3CH2_CAPTURE_VAL=TIM_GetCapture1(TIM3);      //获取触发时计数器值
                                CH2_Time_High=(TIM3CH2_CAPTURE_STA&0X3F)*65536+TIM3CH2_CAPTURE_VAL;  //高电平时长
                               
                                if(CH2_Time_High>65535)                         //判断高电平时间是否超出脉冲信号周期(脉冲信号频率基本固定18-19HZ,此时占空比达到100%)
                                        CH2_Time_High=65535;                          //
                               
                           TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising);          //通道2设置为上升沿捕获
                        }
                        else if((TIM3CH2_CAPTURE_STA&0X80)==0)                              //第一次捕获上升沿
                        {       
                          TIM3CH2_CAPTURE_STA=0;                          //清空
                          TIM3CH2_CAPTURE_VAL=0;        //清空
                           TIM_SetCounter(TIM3,0);       //计数器置零
                          TIM3CH2_CAPTURE_STA|=0X40;                //标记捕获到了上升沿                       
                          TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); //通道2设置为下降沿捕获                                  
                        }
      else
                  {
                          TIM3CH2_CAPTURE_VAL=TIM_GetCapture1(TIM3);      //获取触发时计数器值
                          CH2_Time_Cycle=(TIM3CH2_CAPTURE_STA&0X3F)*65536+TIM3CH2_CAPTURE_VAL;  //获取脉冲信号周期
                          if(CH2_Time_Cycle>65535)                       //判断整个周期是否超出脉冲信号周期(脉冲信号频率基本固定18-19HZ,此时占空比达到100%)
                                 CH2_Time_Cycle=65535;                         //       
                          duty2=CH2_Time_High*1.0/CH2_Time_Cycle;        //计算占空比
                          TIM3CH2_CAPTURE_VAL=0;                         //清空
                           TIM_SetCounter(TIM3,0);                        //计数器置零       
        if(duty2==1)
                                 TIM3CH2_CAPTURE_STA=0;
                                else
                                 TIM3CH2_CAPTURE_STA|=0XC0;                //标记捕获到了上升沿                                 
                          TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); //通道2设置为下降沿捕获                                 
                  }                         
                }       
   TIM_ClearITPendingBit(TIM3,TIM_IT_Update|TIM_IT_CC2); //清除中断标志位

}

最佳答案

查看完整内容[请看2#楼]

非常谢谢了 TIM3CH2通道本应为PA7 硬件连接的是PB5 没开重映射
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2019-4-19
在线时间
44 小时
 楼主| 发表于 2020-6-19 17:59:22 | 显示全部楼层
Sunshinegeek 发表于 2020-6-20 09:00
不管怎么组合 TIM2CH1可以  TIM3CH2就是不行

非常谢谢了  TIM3CH2通道本应为PA7   硬件连接的是PB5   没开重映射
回复

使用道具 举报

6

主题

412

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2722
金钱
2722
注册时间
2019-8-14
在线时间
415 小时
发表于 2020-6-19 19:28:47 | 显示全部楼层
单独Tim3来仿真看看呗
回复

使用道具 举报

5

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2019-4-19
在线时间
44 小时
 楼主| 发表于 2020-6-20 09:00:16 | 显示全部楼层
EVahl 发表于 2020-6-19 19:28
单独Tim3来仿真看看呗

不管怎么组合 TIM2CH1可以  TIM3CH2就是不行
回复

使用道具 举报

5

主题

27

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
266
金钱
266
注册时间
2019-4-19
在线时间
44 小时
 楼主| 发表于 2020-6-20 10:14:46 | 显示全部楼层
EVahl 发表于 2020-6-19 19:28
单独Tim3来仿真看看呗

进不到下面的断点里

进不到下面的断点里
进不到下面的断点里 大概问题是出在哪里?

回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-16 06:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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