最近玩32闆發現網上有關TIM定時器的四路通道捕獲高電平的内容很少,是以在此給出一個庫函數版本的,希望對大家有幫助。
void TIM3_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM5時鐘使能
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTA時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//複用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//複用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PA0
// GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; //GPIOA0
// GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//複用功能
// GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
// GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //推挽複用輸出
// GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
// GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //PA0複用位定時器5
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3);
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定時器分頻
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseStructure.TIM_Period=arr; //自動重裝載值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
//初始化TIM5輸入捕獲參數
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 選擇輸入端 IC1映射到TI1上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;//CC1S=01 選擇輸入端 IC1映射到TI1上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC1S=01 選擇輸入端 IC1映射到TI1上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01 選擇輸入端 IC1映射到TI1上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//允許更新中斷 ,允許CC1IE捕獲中斷
TIM_ITConfig(TIM3,TIM_IT_CC1,ENABLE);
TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);
TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE);
TIM_ITConfig(TIM3,TIM_IT_CC4,ENABLE);
TIM_Cmd(TIM3,ENABLE ); //使能定時器5
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的參數初始化VIC寄存器、
}
//捕獲狀态
//[7]:0,沒有成功的捕獲;1,成功捕獲到一次.
//[6]:0,還沒捕獲到低電平;1,已經捕獲到低電平了.
//[5:0]:捕獲低電平後溢出的次數(對于32位定時器來說,1us計數器加1,溢出時間:4294秒)
u8 TIM3CH1_CAPTURE_STA=0; //輸入捕獲狀态
u32 TIM3CH1_CAPTURE_VAL; //輸入捕獲值(TIM2/TIM5是32位)
u8 TIM3CH2_CAPTURE_STA=0; //輸入捕獲狀态
u32 TIM3CH2_CAPTURE_VAL; //輸入捕獲值(TIM2/TIM5是32位)
u8 TIM3CH3_CAPTURE_STA=0; //輸入捕獲狀态
u32 TIM3CH3_CAPTURE_VAL; //輸入捕獲值(TIM2/TIM5是32位)
u8 TIM3CH4_CAPTURE_STA=0; //輸入捕獲狀态
u32 TIM3CH4_CAPTURE_VAL; //輸入捕獲值(TIM2/TIM5是32位)
//定時器5中斷服務程式
void TIM3_IRQHandler(void)
{
if((TIM3CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
{
if(TIM3CH1_CAPTURE_STA&0X40)//已經捕獲到高電平了
{
if((TIM3CH1_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
{
TIM3CH1_CAPTURE_STA|=0X80; //标記成功捕獲了一次
TIM3CH1_CAPTURE_VAL=0XFFFFFFFF;
}else TIM3CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)//捕獲1發生捕獲事件
{
if(TIM3CH1_CAPTURE_STA&0X40) //捕獲到一個下降沿
{
TIM3CH1_CAPTURE_STA|=0X80; //标記成功捕獲到一次高電平脈寬
TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);//擷取目前的捕獲值.
TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
}else //還未開始,第一次捕獲上升沿
{
TIM3CH1_CAPTURE_STA=0; //清空
TIM3CH1_CAPTURE_VAL=0;
TIM3CH1_CAPTURE_STA|=0X40; //标記捕獲到了上升沿
TIM_Cmd(TIM3,DISABLE ); //關閉定時器5
TIM_SetCounter(TIM3,0);
TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 設定為下降沿捕獲
TIM_Cmd(TIM3,ENABLE ); //使能定時器5
}
}
}
if((TIM3CH2_CAPTURE_STA&0X80)==0)//還未成功捕獲
{
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=0XFFFFFFFF;
}else TIM3CH2_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕獲1發生捕獲事件
{
if(TIM3CH2_CAPTURE_STA&0X40) //捕獲到一個下降沿
{
TIM3CH2_CAPTURE_STA|=0X80; //标記成功捕獲到一次高電平脈寬
TIM3CH2_CAPTURE_VAL=TIM_GetCapture2(TIM3);//擷取目前的捕獲值.
TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
}else //還未開始,第一次捕獲上升沿
{
TIM3CH2_CAPTURE_STA=0; //清空
TIM3CH2_CAPTURE_VAL=0;
TIM3CH2_CAPTURE_STA|=0X40; //标記捕獲到了上升沿
TIM_Cmd(TIM3,DISABLE ); //關閉定時器5
TIM_SetCounter(TIM3,0);
TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 設定為下降沿捕獲
TIM_Cmd(TIM3,ENABLE ); //使能定時器5
}
}
}
if((TIM3CH3_CAPTURE_STA&0X80)==0)//還未成功捕獲
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
{
if(TIM3CH3_CAPTURE_STA&0X40)//已經捕獲到高電平了
{
if((TIM3CH3_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
{
TIM3CH3_CAPTURE_STA|=0X80; //标記成功捕獲了一次
TIM3CH3_CAPTURE_VAL=0XFFFFFFFF;
}else TIM3CH3_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)//捕獲1發生捕獲事件
{
if(TIM3CH3_CAPTURE_STA&0X40) //捕獲到一個下降沿
{
TIM3CH3_CAPTURE_STA|=0X80; //标記成功捕獲到一次高電平脈寬
TIM3CH3_CAPTURE_VAL=TIM_GetCapture3(TIM3);//擷取目前的捕獲值.
TIM_OC3PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
}else //還未開始,第一次捕獲上升沿
{
TIM3CH3_CAPTURE_STA=0; //清空
TIM3CH3_CAPTURE_VAL=0;
TIM3CH3_CAPTURE_STA|=0X40; //标記捕獲到了上升沿
TIM_Cmd(TIM3,DISABLE ); //關閉定時器5
TIM_SetCounter(TIM3,0);
TIM_OC3PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 設定為下降沿捕獲
TIM_Cmd(TIM3,ENABLE ); //使能定時器5
}
}
}
if((TIM3CH4_CAPTURE_STA&0X80)==0)//還未成功捕獲
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//溢出
{
if(TIM3CH4_CAPTURE_STA&0X40)//已經捕獲到高電平了
{
if((TIM3CH4_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
{
TIM3CH4_CAPTURE_STA|=0X80; //标記成功捕獲了一次
TIM3CH4_CAPTURE_VAL=0XFFFFFFFF;
}else TIM3CH4_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)//捕獲1發生捕獲事件
{
if(TIM3CH4_CAPTURE_STA&0X40) //捕獲到一個下降沿
{
TIM3CH4_CAPTURE_STA|=0X80; //标記成功捕獲到一次高電平脈寬
TIM3CH4_CAPTURE_VAL=TIM_GetCapture4(TIM3);//擷取目前的捕獲值.
TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 設定為上升沿捕獲
}else //還未開始,第一次捕獲上升沿
{
TIM3CH4_CAPTURE_STA=0; //清空
TIM3CH4_CAPTURE_VAL=0;
TIM3CH4_CAPTURE_STA|=0X40; //标記捕獲到了上升沿
TIM_Cmd(TIM3,DISABLE ); //關閉定時器5
TIM_SetCounter(TIM3,0);
TIM_OC4PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 設定為下降沿捕獲
TIM_Cmd(TIM3,ENABLE ); //使能定時器5
}
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4); //清除中斷标志位
STM32F4中的TIMx定時器的功能十分強大,可以同時輸出四路PWM波,也可以同時四路采取高電平,及四路捕獲,如果在使用超音波傳感器時,可以使用,這樣的用法可以大大減少定時器的使用,雖然F4定時器很多,但是這種方法可以供大家參考參考。
在TIM_ICInit函數中,TIM_Channel的選擇是對應的,是以在配置TIM_ICInit時不能用或“|”的邏輯符号。