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);//设置为下降沿捕获
}
}
}
}
一周热门 更多>