求助多路脉宽信号捕获,通道冲突

2019-07-20 08:26发布

F407的单片机捕获6个脉宽信号,但最多捕获5路信号,到第六个的时候出现数据异常,现在只能屏蔽掉一路信号的配置了,不知道问题出在哪里?
static void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构体定义
RCC_AHB1PeriphClockCmd (CH1_GPIO_CLK |
             CH2_GPIO_CLK |
             CH3_GPIO_CLK |
             CH4_GPIO_CLK |
             CH5_GPIO_CLK |
             CH6_GPIO_CLK ,ENABLE); //开启时钟
/*引脚通用配置*/
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;  //设置引脚模式为复用模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //设置引脚的输出类型为推挽输出
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN; //设置引脚为下拉模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速率为50MHz
/*CH1引脚*/  
GPIO_InitStructure.GPIO_Pin   = CH1_PIN; //选择要控制的GPIO引脚  
GPIO_Init(CH1_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH1_GPIO_PORT,CH1_PINSOURCE,CH1_AF); //定时器复用引脚连接  
/*CH2引脚*/
GPIO_InitStructure.GPIO_Pin = CH2_PIN; //选择要控制的GPIO引脚
GPIO_Init(CH2_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH2_GPIO_PORT,CH2_PINSOURCE,CH2_AF); //定时器复用引脚连接
/*CH3引脚*/
GPIO_InitStructure.GPIO_Pin = CH3_PIN; //选择要控制的GPIO引脚
GPIO_Init(CH3_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH3_GPIO_PORT,CH3_PINSOURCE,CH3_AF); //定时器复用引脚连接
/*CH4引脚*/
GPIO_InitStructure.GPIO_Pin = CH4_PIN; //选择要控制的GPIO引脚
GPIO_Init(CH4_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH4_GPIO_PORT,CH4_PINSOURCE,CH4_AF); //定时器复用引脚连接
/*CH5引脚*/
GPIO_InitStructure.GPIO_Pin = CH5_PIN; //选择要控制的GPIO引脚
GPIO_Init(CH5_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH5_GPIO_PORT,CH5_PINSOURCE,CH5_AF); //定时器复用引脚连接
/*CH6引脚*/
GPIO_InitStructure.GPIO_Pin = CH6_PIN; //选择要控制的GPIO引脚
GPIO_Init(CH6_GPIO_PORT , &GPIO_InitStructure); //初始化GPIO
GPIO_PinAFConfig(CH6_GPIO_PORT,CH6_PINSOURCE,CH6_AF); //定时器复用引脚连接
}

/**
  * @brief  通用定时器中断优先级配置
  * @param  无
  * @retval 无
  */
static void TIMx_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //结构体定义
/* CH12中断 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断组为0
NVIC_InitStructure.NVIC_IRQChannel = CH12_TIM_IRQn; // 设置中断来源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 设置子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* CH3456中断 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 设置中断组为0
NVIC_InitStructure.NVIC_IRQChannel = CH3456_TIM_IRQn; // 设置中断来源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4; // 设置子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  输入模式配置
  * @param  无
  * @retval 无
  */
static void TIM_INPUT_Config(void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;
  RCC_APB1PeriphClockCmd(CH12_TIM_CLK  |
             CH3456_TIM_CLK ,ENABLE); // 开启TIM时钟

/* 定时器初始化通用配置 */
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF-1;  //当定时器从0计数到0xFFFF,为一个定时周期
  TIM_TimeBaseStructure.TIM_Prescaler = 84-1; // 通用定时器时钟源TIMxCLK = HCLK/2=84MHz
                        // 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=1MHz
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;  // 计数方式
/* CH12定时器初始化 */
TIM_TimeBaseInit(CH12_TIM, &TIM_TimeBaseStructure); // 初始化定时器
/* CH3456定时器初始化 */
TIM_TimeBaseInit(CH3456_TIM, &TIM_TimeBaseStructure); // 初始化定时器

/* 输入捕获通用配置 */
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //TIxFPx边沿触发
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //设置时钟分割:TDTS = Tck_tim
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入预分频/不分频
  TIM_ICInitStructure.TIM_ICFilter = 0x0;  //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF/不滤波
/* CH1输入捕获配置 */
  TIM_ICInitStructure.TIM_Channel = CH1_IC_CHANNEL; //通道选择
  TIM_ICInit(CH12_TIM, &TIM_ICInitStructure);
TIM_ITConfig(CH12_TIM ,CH1_IT_CC ,ENABLE);
/* CH2输入捕获配置 */
TIM_ICInitStructure.TIM_Channel = CH2_IC_CHANNEL;//通道选择
TIM_ICInit(CH12_TIM, &TIM_ICInitStructure);
TIM_ITConfig(CH12_TIM ,CH2_IT_CC ,ENABLE);
/* CH3输入捕获配置 */
TIM_ICInitStructure.TIM_Channel = CH3_IC_CHANNEL;//通道选择
TIM_ICInit(CH3456_TIM, &TIM_ICInitStructure);
TIM_ITConfig(CH3456_TIM ,CH3_IT_CC ,ENABLE);
// /* CH4输入捕获配置 */
// TIM_ICInitStructure.TIM_Channel = CH4_IC_CHANNEL;//通道选择
// TIM_ICInit(CH3456_TIM, &TIM_ICInitStructure);
// TIM_ITConfig(CH3456_TIM ,CH4_IT_CC ,ENABLE);
/* CH5输入捕获配置 */
TIM_ICInitStructure.TIM_Channel = CH5_IC_CHANNEL;//通道选择
TIM_ICInit(CH3456_TIM, &TIM_ICInitStructure);
TIM_ITConfig(CH3456_TIM ,CH5_IT_CC ,ENABLE);
/* CH6输入捕获配置 */
TIM_ICInitStructure.TIM_Channel = CH6_IC_CHANNEL;//通道选择
TIM_ICInit(CH3456_TIM, &TIM_ICInitStructure);
TIM_ITConfig(CH3456_TIM ,CH6_IT_CC ,ENABLE);
              
TIM_Cmd(CH12_TIM, ENABLE);  //使能定时器
TIM_Cmd(CH3456_TIM, ENABLE);  //使能定时器
}

/**
  * @brief  初始控制定时器定时
  * @param  无
  * @retval 无
  */
void RC6GS_Init(void)
{
GPIO_Config();
TIMx_NVIC_Configuration();
TIM_INPUT_Config();
}

uint8_t   CH1_CAPTURE_STA = 0; //通道1输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH1_CAPTURE_UPVAL;
uint16_t  CH1_CAPTURE_DOWNVAL;
uint32_t  CH1_TempValue;
uint16_t  CH1_PulseWidth; //输出高电平时间
uint8_t   CH2_CAPTURE_STA = 0; //通道2输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH2_CAPTURE_UPVAL;
uint16_t  CH2_CAPTURE_DOWNVAL;
uint32_t  CH2_TempValue;
uint16_t  CH2_PulseWidth; //输出高电平时间
uint8_t   CH3_CAPTURE_STA = 0; //通道3输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH3_CAPTURE_UPVAL;
uint16_t  CH3_CAPTURE_DOWNVAL;
uint32_t  CH3_TempValue;
uint16_t  CH3_PulseWidth; //输出高电平时间
uint8_t  CH4_CAPTURE_STA = 0; //通道4输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH4_CAPTURE_UPVAL;
uint16_t  CH4_CAPTURE_DOWNVAL;
uint32_t  CH4_TempValue;
uint16_t  CH4_PulseWidth; //输出高电平时间
uint8_t  CH5_CAPTURE_STA = 0; //通道4输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH5_CAPTURE_UPVAL;
uint16_t  CH5_CAPTURE_DOWNVAL;
uint32_t  CH5_TempValue;
uint16_t  CH5_PulseWidth; //输出高电平时间
uint8_t  CH6_CAPTURE_STA = 0; //通道4输入捕获标志,高两位做捕获标志,低6位做溢出标志  
uint16_t  CH6_CAPTURE_UPVAL;
uint16_t  CH6_CAPTURE_DOWNVAL;
uint32_t  CH6_TempValue;
uint16_t  CH6_PulseWidth; //输出高电平时间
/**
  * @brief  中断服务,读取CH1~CH2的脉宽
  * @param  无
  * @retval 无
  */
void CH12_TIM_IRQHandler(void)
{
/* CH1高电平捕获时间 */
if ((CH1_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{
  if (TIM_GetITStatus(CH12_TIM, CH1_IT_CC) != RESET)   //捕获1发生捕获事件
  {
   TIM_ClearITPendingBit(CH12_TIM, CH1_IT_CC);   //清除中断标志位
   if (CH1_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH1_CAPTURE_DOWNVAL = TIM_GetCapture1(CH12_TIM);//记录下此时的定时器计数值
    if (CH1_CAPTURE_DOWNVAL < CH1_CAPTURE_UPVAL)
    {
     CH1_TempValue = 65535;
    }
    else
     CH1_TempValue = 0;
    CH1_PulseWidth = CH1_CAPTURE_DOWNVAL - CH1_CAPTURE_UPVAL + CH1_TempValue;  //得到总的高电平的时间
    CH1_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC1PolarityConfig(CH12_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH1_CAPTURE_UPVAL = TIM_GetCapture1(CH12_TIM);  //获取上升沿数据
    CH1_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC1PolarityConfig(CH12_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}
/* CH2高电平捕获时间 */
if ((CH2_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{   
  if (TIM_GetITStatus(CH12_TIM, CH2_IT_CC) != RESET)   //捕获2发生捕获事件
  {
   TIM_ClearITPendingBit(CH12_TIM, CH2_IT_CC);   //清除中断标志位
   if (CH2_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH2_CAPTURE_DOWNVAL = TIM_GetCapture2(CH12_TIM);//记录下此时的定时器计数值
    if (CH2_CAPTURE_DOWNVAL < CH2_CAPTURE_UPVAL)
    {
     CH2_TempValue = 65535;
    }
    else
     CH2_TempValue = 0;
    CH2_PulseWidth = CH2_CAPTURE_DOWNVAL - CH2_CAPTURE_UPVAL + CH2_TempValue;  //得到总的高电平的时间
    CH2_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC2PolarityConfig(CH12_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH2_CAPTURE_UPVAL = TIM_GetCapture2(CH12_TIM);  //获取上升沿数据
    CH2_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC2PolarityConfig(CH12_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}
}
/**
  * @brief  中断服务,读取CH3~CH6的脉宽
  * @param  无
  * @retval 无
  */
void CH3456_TIM_IRQHandler(void)
{
/* CH3高电平捕获时间 */
if ((CH3_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{
  if (TIM_GetITStatus(CH3456_TIM, CH3_IT_CC) != RESET)   //捕获1发生捕获事件
  {
   TIM_ClearITPendingBit(CH3456_TIM, CH3_IT_CC);   //清除中断标志位
   if (CH3_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH3_CAPTURE_DOWNVAL = TIM_GetCapture1(CH3456_TIM);//记录下此时的定时器计数值
    if (CH3_CAPTURE_DOWNVAL < CH3_CAPTURE_UPVAL)
    {
     CH3_TempValue = 65535;
    }
    else
     CH3_TempValue = 0;
    CH3_PulseWidth = CH3_CAPTURE_DOWNVAL - CH3_CAPTURE_UPVAL + CH3_TempValue;  //得到总的高电平的时间
    CH3_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC1PolarityConfig(CH3456_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH3_CAPTURE_UPVAL = TIM_GetCapture1(CH3456_TIM);  //获取上升沿数据
    CH3_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC1PolarityConfig(CH3456_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}

/* CH4高电平捕获时间 */
if ((CH4_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{   
  if (TIM_GetITStatus(CH3456_TIM, CH4_IT_CC) != RESET)   //捕获2发生捕获事件
  {
   TIM_ClearITPendingBit(CH3456_TIM, CH4_IT_CC);   //清除中断标志位
   if (CH4_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH4_CAPTURE_DOWNVAL = TIM_GetCapture2(CH3456_TIM);//记录下此时的定时器计数值
    if (CH4_CAPTURE_DOWNVAL < CH4_CAPTURE_UPVAL)
    {
     CH4_TempValue = 65535;
    }
    else
     CH4_TempValue = 0;
    CH4_PulseWidth = CH4_CAPTURE_DOWNVAL - CH4_CAPTURE_UPVAL + CH4_TempValue;  //得到总的高电平的时间
    CH4_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC2PolarityConfig(CH3456_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH4_CAPTURE_UPVAL = TIM_GetCapture2(CH3456_TIM);  //获取上升沿数据
    CH4_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC2PolarityConfig(CH3456_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}

/* CH5高电平捕获时间 */
if ((CH5_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{   
  if (TIM_GetITStatus(CH3456_TIM, CH5_IT_CC) != RESET)   //捕获3发生捕获事件
  {
   TIM_ClearITPendingBit(CH3456_TIM, CH5_IT_CC);   //清除中断标志位
   if (CH5_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH5_CAPTURE_DOWNVAL = TIM_GetCapture3(CH3456_TIM);//记录下此时的定时器计数值
    if (CH5_CAPTURE_DOWNVAL < CH5_CAPTURE_UPVAL)
    {
     CH5_TempValue = 65535;
    }
    else
     CH5_TempValue = 0;
    CH5_PulseWidth = CH5_CAPTURE_DOWNVAL - CH5_CAPTURE_UPVAL + CH5_TempValue;  //得到总的高电平的时间
    CH5_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC3PolarityConfig(CH3456_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH5_CAPTURE_UPVAL = TIM_GetCapture3(CH3456_TIM);  //获取上升沿数据
    CH5_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC3PolarityConfig(CH3456_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}
/* CH6高电平捕获时间 */
if ((CH6_CAPTURE_STA & 0X80) == 0)   //还未成功捕获
{   
  if (TIM_GetITStatus(CH3456_TIM, CH6_IT_CC) != RESET)   //捕获4发生捕获事件
  {
   TIM_ClearITPendingBit(CH3456_TIM, CH6_IT_CC);   //清除中断标志位
   if (CH6_CAPTURE_STA & 0X40)  //捕获到一个下降沿
   {
    CH6_CAPTURE_DOWNVAL = TIM_GetCapture4(CH3456_TIM);//记录下此时的定时器计数值
    if (CH6_CAPTURE_DOWNVAL < CH6_CAPTURE_UPVAL)
    {
     CH6_TempValue = 65535;
    }
    else
     CH6_TempValue = 0;
    CH6_PulseWidth = CH6_CAPTURE_DOWNVAL - CH6_CAPTURE_UPVAL + CH6_TempValue;  //得到总的高电平的时间
    CH6_CAPTURE_STA = 0;  //捕获标志位清零
    TIM_OC4PolarityConfig(CH3456_TIM, TIM_ICPolarity_Rising); //设置为上升沿捕获   
   }
   else //发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
   {
    CH6_CAPTURE_UPVAL = TIM_GetCapture4(CH3456_TIM);  //获取上升沿数据
    CH6_CAPTURE_STA |= 0X40;  //标记已捕获到上升沿
    TIM_OC4PolarityConfig(CH3456_TIM, TIM_ICPolarity_Falling);//设置为下降沿捕获
   }
  }
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
Julien
1楼-- · 2019-07-20 11:33
问题解决了,是中断开启的太早了
Seri。
2楼-- · 2019-07-20 14:33
 精彩回答 2  元偷偷看……
Julien
3楼-- · 2019-07-20 18:56
 精彩回答 2  元偷偷看……

一周热门 更多>