STM32F103高級定時器作輸入捕獲(以TIM1通道4爲例)

畢業設計需要使用比較多的定時器,但手上的F103C8T6核心板定時器資源比較少,所以被迫使用高級定時器1(一直都是用通用定時器,畢竟以前玩F429的時候管腳資源充足,就沒有去學習高級定時器的用法,以爲完全一樣的用法,但是移植程序過程還是發現好些需要注意的地方)。下面列出程序中與通用定時器有差別的地方。

用到的定時器是TIM1通道4,原型是作爲超聲波捕獲,單獨拿出配置定時器輸入捕獲函數和中斷服務函數來說明,程序都寫了註釋,沒有一一說明的地方可以直接看註釋。

  1. 高級定時器TIM1和GPIOA時鐘來源都是APB2
    在這裏插入圖片描述
    在這裏插入圖片描述
    由上面兩圖可知,需要使能的是TIM1時鐘和GPIOA時鐘:
    //使能TIM1和GPIOA時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//初始化TIME時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//初始化GPIOA時鐘

在這裏插入圖片描述
2. GPIOA中的PA11配置爲輸入模式,PA12設置爲輸出模式

    //配置PA11
    GPIOA_Initstructure.GPIO_Pin=GPIO_Pin_11;//PA11
    GPIOA_Initstructure.GPIO_Mode=GPIO_Mode_IPD;//輸入
    GPIO_ResetBits(GPIOA,GPIO_Pin_11); //PA11 下拉
    GPIO_Init(GPIOA,&GPIOA_Initstructure);
    
    //配置PA12
    GPIOA_Initstructure.GPIO_Pin=GPIO_Pin_12;//PA12
    GPIOA_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;//輸出		     
    GPIOA_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIOA_Initstructure);

關於GPIO口的八種模式原子論壇有帖子說的很詳細,以前看過的,有興趣可以去搜索。

  1. 初始化TIM1、置 TIM1 的輸入比較參數、
    //初始化 TIM1, 設置 TIM1 的 ARR 和 PSC
    TIM1_CH4_Handler.TIM_Prescaler=psc;//預分頻係數
    TIM1_CH4_Handler.TIM_Period=arr;//自動重裝載值
    TIM1_CH4_Handler.TIM_CounterMode=TIM_CounterMode_Up;//向上計數模式
    TIM1_CH4_Handler.TIM_ClockDivision=TIM_CKD_DIV1;//預分頻係數爲1
    TIM1_CH4_Handler.TIM_RepetitionCounter=0;//設置重複溢出次數,就是多少次溢出後進入中斷,一般爲0,只有高級定時器纔有用
    TIM_TimeBaseInit(TIM1,&TIM1_CH4_Handler);
    
    //設置 TIM1 的輸入比較參數,開啓輸入捕獲
    TIM1_IC_Handler.TIM_Channel=TIM_Channel_4;//TIM1通道4
    TIM1_IC_Handler.TIM_ICFilter=0x00;//輸入濾波器長度爲0
    TIM1_IC_Handler.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕獲
    TIM1_IC_Handler.TIM_ICPrescaler=TIM_ICPSC_DIV1;//預分頻係數,不分頻
    TIM1_IC_Handler.TIM_ICSelection=TIM_ICSelection_DirectTI; //映射到 TI1 上
    TIM_ICInit(TIM1,&TIM1_IC_Handler);

TIM1_CH4_Handler.TIM_RepetitionCounter=0;//設置重複溢出次數,就是多少次溢出後進入中斷,一般爲0,只有高級定時器纔有用到

  1. 使能捕獲和更新中斷、設置中斷分組、使能定時器
    //使能捕獲和更新中斷(設置 TIM1 的 DIER 寄存器)
    TIM_ITConfig( TIM1,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允許更新中斷和捕獲中斷
    
    //設置中斷分組
    NVIC_Initstructure.NVIC_IRQChannel=TIM1_CC_IRQn;//定時器1
    NVIC_Initstructure.NVIC_IRQChannelCmd=ENABLE;//使能TIM1
    NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority=2;//搶佔優先級2
    NVIC_Initstructure.NVIC_IRQChannelSubPriority=0;//子優先級0
    NVIC_Init(&NVIC_Initstructure);
   
    TIM_CtrlPWMOutputs(TIM1,ENABLE);	//主輸出使能
   
    //使能定時器(設置 TIM1 的 CR1 寄存器)
    TIM_Cmd(TIM1,ENABLE);//使能定時器1

選擇NVIC_IRQChannel中的TIM1_CC_IRQn,即TIM1捕獲比較中斷。在這裏插入圖片描述

  1. 定時器1中斷服務函數
//定時器1中斷服務程序
void TIM1_CC_IRQHandler(void)
{
    if((TIM1CH4_CAPTURE_STA&0X80)==0)//還未成功捕獲
    {
        if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
        {
            if(TIM1CH4_CAPTURE_STA&0X40)//已經捕獲到高電平了
            {
                if((TIM1CH4_CAPTURE_STA&0X3F)==0X3F)//高電平太長了
                {
                    TIM1CH4_CAPTURE_STA|=0X80;//標記成功捕獲了一次
                    TIM1CH4_CAPTURE_VAL=0XFFFF;
                }else TIM1CH4_CAPTURE_STA++;
            }
        }
        if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)//捕獲 1 發生捕獲事件
        {
            if(TIM1CH4_CAPTURE_STA&0X40) //捕獲到一個下降沿
            {
                TIM1CH4_CAPTURE_STA|=0X80; //標記成功捕獲到一次上升沿
                TIM1CH4_CAPTURE_VAL=TIM_GetCapture4(TIM1);
                TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Rising);
                //CC1P=0 設置爲上升沿捕獲
            }else //還未開始,第一次捕獲上升沿
            {
                TIM1CH4_CAPTURE_STA=0; //清空
                TIM1CH4_CAPTURE_VAL=0;
                TIM_SetCounter(TIM1,0);
                TIM1CH4_CAPTURE_STA|=0X40; //標記捕獲到了上升沿
                TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Falling);
                //CC1P=1 設置爲下降沿捕獲
            }
        }
    }
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC4|TIM_IT_Update); //清除中斷標誌位
}

定時器中斷函數服務名字選擇:void TIM1_CC_IRQHandler(void);
在這裏插入圖片描述

以上,就是使用TIM1做輸入捕獲的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章