初级会员
- 积分
- 124
- 金钱
- 124
- 注册时间
- 2019-5-30
- 在线时间
- 29 小时
|
5金钱
从例程里的单通道输入捕获改过来的一个定时器实现四路同时输入捕获,为什么只可以每个通道单独工作,不可以同时工作?
跪求各位大佬帮忙看看是什么问题,或者又没有相关的例程分享一下。
(由于32位定时器的溢出时间为4294秒,所以就忽略了溢出的情况)
TIM_HandleTypeDef TIM5_Handler; //定时器5句柄
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8 TIM5CH1_CAPTURE_STA[4]={0}; //输入捕获状态
u32 TIM5CH1_CAPTURE_VAL[4]={0}; //输入捕获值(TIM2/TIM5是32位)
u32 TIM5CH_CAPTURE_UP[4]={0};//捕获上升沿的值
u32 TIM5CH_CAPTURE_DOWN[4]={0};//捕获下降沿的值
//定时器5输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
void TIM5_Cap_Init(u32 arr,u16 psc)//定时器5通道1输入捕获初始化
{
__HAL_RCC_TIM5_CLK_ENABLE(); //使能TIM5时钟
TIM_IC_InitTypeDef TIM5_CH1Config; //定时器5通道1句柄
TIM_IC_InitTypeDef TIM5_CH2Config; //定时器5通道2句柄
TIM_IC_InitTypeDef TIM5_CH3Config; //定时器5通道3句柄
TIM_IC_InitTypeDef TIM5_CH4Config; //定时器5通道4句柄
//时基配置
TIM5_Handler.Instance=TIM5; //通用定时器5
TIM5_Handler.Init.Prescaler=psc; //分频系数
TIM5_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器
TIM5_Handler.Init.Period=arr; //自动装载值
TIM5_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频银子
HAL_TIM_IC_Init(&TIM5_Handler);//初始化输入捕获时基参数
//通道1配置
TIM5_CH1Config.ICPolarity=TIM_ICPOLARITY_RISING; //上升沿捕获
TIM5_CH1Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//直接映射到TI1上
TIM5_CH1Config.ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_CH1Config.ICFilter=0; //配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);//配置TIM5通道1
//通道2配置
TIM5_CH2Config.ICPolarity=TIM_ICPOLARITY_RISING; //上升沿捕获
TIM5_CH2Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//直接映射到TI1上
TIM5_CH2Config.ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_CH2Config.ICFilter=0; //配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH2Config,TIM_CHANNEL_2);//配置TIM5通道2
//通道3配置
TIM5_CH3Config.ICPolarity=TIM_ICPOLARITY_RISING; //上升沿捕获
TIM5_CH3Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//直接映射到TI1上
TIM5_CH3Config.ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_CH3Config.ICFilter=0; //配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH3Config,TIM_CHANNEL_3);//配置TIM5通道3
//通道4配置
TIM5_CH4Config.ICPolarity=TIM_ICPOLARITY_RISING; //上升沿捕获
TIM5_CH4Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//直接映射到TI1上
TIM5_CH4Config.ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_CH4Config.ICFilter=0; //配置输入滤波器,不滤波
HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH4Config,TIM_CHANNEL_4);//配置TIM5通道4
HAL_NVIC_SetPriority(TIM5_IRQn,2,0); //设置中断优先级,抢占优先级2,子优先级0
HAL_NVIC_EnableIRQ(TIM5_IRQn); //开启ITM5中断通道
HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1); //开启TIM5的捕获通道1,并且开启捕获中断
HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_2); //开启TIM5的捕获通道2,并且开启捕获中断
HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_3); //开启TIM5的捕获通道3,并且开启捕获中断
HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_4); //开启TIM5的捕获通道4,并且开启捕获中断
}
//定时器5底层驱动,时钟使能,引脚配置
//此函数会被HAL_TIM_IC_Init()调用
//htim:定时器5句柄
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM5)//定时器5
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_3; //PA0、PA3
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF2_TIM5; //PA0复用为TIM5通道1
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_11|GPIO_PIN_12; //PH11、PH12
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
}
}
//定时器5中断服务函数
void TIM5_IRQHandler(void)
{
HAL_TIM_IRQHandler(&TIM5_Handler);//定时器共用处理函数
}
//定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
{
if(htim->Instance==TIM5) //定时器5
{
//通道1
if((TIM5CH1_CAPTURE_STA[0]&0X80)==0)//还未成功捕获
{
if(TIM5CH1_CAPTURE_STA[0]&0X40) //捕获到一个下降沿
{
TIM5CH1_CAPTURE_STA[0]|=0X80; //标记成功捕获到一次高电平脉宽
TIM5CH_CAPTURE_DOWN[0]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);//获取当前的捕获值.
TIM5CH1_CAPTURE_VAL[0]=TIM5CH_CAPTURE_DOWN[0]-TIM5CH_CAPTURE_UP[0];
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA[0]=0; //清空
TIM5CH1_CAPTURE_VAL[0]=0;
TIM5CH_CAPTURE_DOWN[0]=0;
TIM5CH1_CAPTURE_STA[0]|=0X40; //标记捕获到了上升沿
TIM5CH_CAPTURE_UP[0]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);//获取当前的捕获值.
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
}
}
//通道2
if((TIM5CH1_CAPTURE_STA[1]&0X80)==0)//还未成功捕获
{
if(TIM5CH1_CAPTURE_STA[1]&0X40) //捕获到一个下降沿
{
TIM5CH1_CAPTURE_STA[1]|=0X80; //标记成功捕获到一次高电平脉宽
TIM5CH_CAPTURE_DOWN[1]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_2);//获取当前的捕获值.
TIM5CH1_CAPTURE_VAL[1]=TIM5CH_CAPTURE_DOWN[1]-TIM5CH_CAPTURE_UP[1];
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_2); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA[1]=0; //清空
TIM5CH1_CAPTURE_VAL[1]=0;
TIM5CH_CAPTURE_DOWN[1]=0;
TIM5CH1_CAPTURE_STA[1]|=0X40; //标记捕获到了上升沿
TIM5CH_CAPTURE_UP[1]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_2);//获取当前的捕获值.
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_2); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
}
}
//通道3
if((TIM5CH1_CAPTURE_STA[2]&0X80)==0)//还未成功捕获
{
if(TIM5CH1_CAPTURE_STA[2]&0X40) //捕获到一个下降沿
{
TIM5CH1_CAPTURE_STA[2]|=0X80; //标记成功捕获到一次高电平脉宽
TIM5CH_CAPTURE_DOWN[2]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_3);//获取当前的捕获值.
TIM5CH1_CAPTURE_VAL[2]=TIM5CH_CAPTURE_DOWN[2]-TIM5CH_CAPTURE_UP[2];
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_3); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_3,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA[2]=0; //清空
TIM5CH1_CAPTURE_VAL[2]=0;
TIM5CH_CAPTURE_DOWN[2]=0;
TIM5CH1_CAPTURE_STA[2]|=0X40; //标记捕获到了上升沿
TIM5CH_CAPTURE_UP[2]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_3);//获取当前的捕获值.
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_3); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_3,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
}
}
//通道4
if((TIM5CH1_CAPTURE_STA[3]&0X80)==0)//还未成功捕获
{
if(TIM5CH1_CAPTURE_STA[3]&0X40) //捕获到一个下降沿
{
TIM5CH1_CAPTURE_STA[3]|=0X80; //标记成功捕获到一次高电平脉宽
TIM5CH_CAPTURE_DOWN[3]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_4);//获取当前的捕获值.
TIM5CH1_CAPTURE_VAL[3]=TIM5CH_CAPTURE_DOWN[3]-TIM5CH_CAPTURE_UP[3];
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_4); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_4,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA[3]=0; //清空
TIM5CH1_CAPTURE_VAL[3]=0;
TIM5CH_CAPTURE_DOWN[3]=0;
TIM5CH1_CAPTURE_STA[3]|=0X40; //标记捕获到了上升沿
TIM5CH_CAPTURE_UP[3]=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_4);//获取当前的捕获值.
TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_4); //一定要先清除原来的设置!!
TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_4,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
}
}
TIM5->SR=0;//清除中断标志位
}
}
|
|