RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解定時(shí)器的輸入捕獲功能

嵌入式應(yīng)用開發(fā) ? 來源:嵌入式應(yīng)用開發(fā) ? 作者:嵌入式應(yīng)用開發(fā) ? 2022-05-06 09:38 ? 次閱讀

輸入捕獲就是用定時(shí)器檢測引腳上的電平時(shí)間,可以檢測高電平時(shí)間和低電平時(shí)間,然后可以算引腳上信號的頻率和占空比。

基本思路就是利用定時(shí)器的輸入捕獲功能。

定時(shí)器捕獲到高電平或低電平就會進(jìn)入捕獲中斷

例如:

我們要捕獲高電平時(shí)間

0 設(shè)置定時(shí)器計(jì)數(shù)頻率和裝載值,一般設(shè)置1MHz,65535

1 設(shè)置定時(shí)器捕獲為高電平捕獲

2 進(jìn)入捕獲中斷后,獲取CNT計(jì)數(shù)值或CCRx值,定時(shí)器捕獲到電平后會把CNT的值保存到CCRx。

設(shè)置成低電平捕獲。

3 再次進(jìn)入捕獲中斷,獲取CNT計(jì)數(shù)值-上次的CNT值=總高電平時(shí)間。

設(shè)置成高電平捕獲。

4 重復(fù)2-3即可完成下一次捕獲。當(dāng)然還要考慮溢出的情況,代碼里有處理。

下面我寫的一個(gè)實(shí)例:

1 定時(shí)器1 PA8產(chǎn)生PWM信號,可改變占空比,檢測高電平時(shí)間

2 捕獲定時(shí)器是定時(shí)器2,初始化如上例。

3 仿真改變PA8占空比,查看捕獲出的高電平時(shí)間。

實(shí)測:

查看源圖像

duty=1000就是高電平維持1000us,

捕獲時(shí)間也是對應(yīng)的1000us,一點(diǎn)誤差都沒有。

代碼如下:

//高電平標(biāo)志
u8  gao_flag=0;
//高電平時(shí)間
u32 gao_timer=0;
//捕獲成功標(biāo)志
u8  buhuo_flag=0;
//溢出次數(shù)
u8  yichu_c=0;

//定時(shí)器 5 中斷服務(wù)程序
extern "C" void TIM2_IRQHandler(void)
{
 if((TIM2CH1_CAPTURE_STA&0X80)==0)//還未成功捕獲
  {

  
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //這個(gè)是溢出中斷
  {
   //如果已經(jīng)得到高電平了,CNT溢出了
   if(gao_flag==1)
   {
    
    yichu_c++;  //溢出加1
    
  
   }
   
  }
  
  
 if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕獲 1 發(fā)生捕獲事件
 {
    if(0==gao_flag&&buhuo_flag==0) //說明之前沒有捕獲到高電平
   {
    gao_timer=TIM2->CCR1;  //獲取高電平時(shí)間

    yichu_c=0;       //溢出清零
    
    gao_flag=1;   //高電平標(biāo)志
    
    TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //改成下降沿捕獲
   }
   //再一次進(jìn)入捕獲中斷說明是捕獲到下降沿了
   else
   {
    if(buhuo_flag==0)   //判斷是否捕獲成功了,如果捕獲成功了就不在捕獲了
    {
    
     gao_timer=TIM2->CCR1-gao_timer;  //獲取捕獲到的高電平時(shí)間
     gao_timer+=yichu_c*65536;       //加上溢出時(shí)間

     TIM2->CNT=0;         //計(jì)數(shù)清零
     
     gao_flag=0;                   //高電平標(biāo)志清零
     
     buhuo_flag=1;              //標(biāo)志捕獲成功了
     
     TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //改成上沿捕獲
     
     
    }
    
   }

 }
}
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中斷標(biāo)志位
}

void TIM1_PWM_Init(u16 arr,u16 psc)
{
 GPIO_InitTypeDef     GPIO_InitStrue;
   TIM_OCInitTypeDef     TIM_OCInitStrue;
   TIM_TimeBaseInitTypeDef     TIM_TimeBaseInitStrue;
   
   
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);        //使能TIM3和相關(guān)GPIO時(shí)鐘
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// 使能GPIOB時(shí)鐘(LED在BP5引腳),使能AFIO時(shí)鐘(定時(shí)器3通道2需要重映射到BP5引腳)
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
   
   GPIO_InitStrue.GPIO_Pin=GPIO_Pin_8;     // TIM_CH2
   GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;    // 復(fù)用推挽
   GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;    //設(shè)置最大輸出速度
   GPIO_Init(GPIOA,&GPIO_InitStrue);                //GPIO端口初始化設(shè)置
   
 //TIM1->CCMR1&=0xF7F7; //關(guān)閉事件更新值
 //TIM1->CCMR1|=0x808; //開啟事件更新值

   TIM_TimeBaseInitStrue.TIM_Period=50000;    //設(shè)置自動重裝載值
   TIM_TimeBaseInitStrue.TIM_Prescaler=71;        //預(yù)分頻系數(shù)
   TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;    //計(jì)數(shù)器向上溢出
   TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1;        //時(shí)鐘的分頻因子,起到了一點(diǎn)點(diǎn)的延時(shí)作用,一般設(shè)為TIM_CKD_DIV1
   TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStrue);        //TIM3初始化設(shè)置(設(shè)置PWM的周期)
   
   TIM_OCInitStrue.TIM_OCMode=TIM_OCMode_PWM2;        // PWM模式2:CNT>CCR時(shí)輸出有效
   TIM_OCInitStrue.TIM_OCPolarity=TIM_OCPolarity_Low;// 設(shè)置極性-有效為高電平
   TIM_OCInitStrue.TIM_OutputState=TIM_OutputState_Enable;// 輸出使能
 
 TIM_OCInitStrue.TIM_Pulse=100;
 
   TIM_OC1Init(TIM1,&TIM_OCInitStrue);        //TIM3的通道2PWM 模式設(shè)置

   TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);        //使能預(yù)裝載寄存器
   
   TIM_Cmd(TIM1,ENABLE);        //使能TIM3
 TIM_CtrlPWMOutputs(TIM1, ENABLE);  
 
 TIM1->CCMR1&=0xF7F7; //關(guān)閉事件更新值
 
}

void capture_init(u16 arr,u16 psc)
{
TIM_OCInitTypeDef TIM2_OCInitStructure;
TIM_ICInitTypeDef TIM2_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能 TIM2 時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 時(shí)鐘

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前設(shè)置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉

//初始化定時(shí)器 2 TIM2
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)定計(jì)數(shù)器自動重裝值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //預(yù)分頻器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計(jì)數(shù)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化 TIMx 的時(shí)間基數(shù)單位

//初始化 TIM2 輸入捕獲參數(shù)

TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //選擇輸入端 IC1 映射到 TI1 上
TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上
TIM2_ICInitStructure.TIM_ICPrescaler = TIM_CKD_DIV1; //配置輸入分頻,不分頻
TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置輸入濾波器 不濾波
TIM_ICInit(TIM2, &TIM2_ICInitStructure);




//中斷分組初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2 中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優(yōu)先級 2 級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //從優(yōu)先級 0 級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化外設(shè) NVIC 寄存器
TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);



TIM_Cmd(TIM2,ENABLE );  //使能定時(shí)器3

}

u16 duty=1000;

int main(void)

{


  
  serial_init(115200); //串口初始化為 9600
  
  TIM1_PWM_Init(1000,71); //

PAout(1)=1;

  capture_init(0XFFFF,72-1); //以 1Mhz 的頻率計(jì)數(shù)

printf("initrn");



 while(1)
  {
  
  //測試位運(yùn)算和邏輯運(yùn)算的速度

  
 PAout(1)=1;

  
  
  
  TIM1->CCR1=duty;
  
   delay_ms(10);
  

 if(buhuo_flag==1)
 {
  printf("HIGH1:%d us rn",gao_timer); //打印總的高點(diǎn)平時(shí)間
 
  buhuo_flag=0;  //重新捕獲
  
  
 }
 
 PAout(1)=0;
   delay_ms(10);

  }

 
}

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5336

    瀏覽量

    120230
  • 電平
    +關(guān)注

    關(guān)注

    5

    文章

    360

    瀏覽量

    39883
  • 定時(shí)器
    +關(guān)注

    關(guān)注

    23

    文章

    3246

    瀏覽量

    114715
收藏 人收藏

    評論

    相關(guān)推薦

    詳解STM32定時(shí)器捕獲功能

    STM32的定時(shí)器是支持信號輸入捕獲的,何為輸入捕獲?主要做什么應(yīng)用?
    的頭像 發(fā)表于 01-12 17:24 ?8426次閱讀
    <b class='flag-5'>詳解</b>STM32<b class='flag-5'>定時(shí)器</b><b class='flag-5'>捕獲</b><b class='flag-5'>功能</b>

    STM32定時(shí)器(三)輸入捕獲

    STM32的定時(shí)器是支持信號輸入捕獲的,何為輸入捕獲?主要做什么應(yīng)用?
    的頭像 發(fā)表于 07-21 14:58 ?4322次閱讀
    STM32<b class='flag-5'>定時(shí)器</b>(三)<b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>

    STM32 --通用定時(shí)器輸入捕獲功能 精選資料推薦

    問題:開始的時(shí)候沒有搞清楚 定時(shí)器時(shí)基 于 定時(shí)器溢出中斷導(dǎo)致在計(jì)算的時(shí)候一直有問題。開始并沒有懷疑是配置有問題,因?yàn)橹敖佑|過定時(shí)器輸入捕獲
    發(fā)表于 08-19 06:34

    從應(yīng)用方面詳解STM32的定時(shí)器輸入捕獲模式

    從應(yīng)用來說STM32的定時(shí)器輸入捕獲模式前言原理輸入捕獲初始化程序中斷函數(shù)和處理函數(shù)前言我們知道,STM32的
    發(fā)表于 01-06 07:37

    stm32定時(shí)器輸入捕獲

    不同頻率、不同占空比的方波信號、PWM信號,同時(shí)做為輸入捕獲功能時(shí),可以測量脈沖寬度、實(shí)現(xiàn)電容按鍵檢測等等。 一、輸入捕獲概念
    發(fā)表于 10-13 09:13 ?2.4w次閱讀
    stm32<b class='flag-5'>定時(shí)器</b><b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>

    基于STM32定時(shí)器輸入捕獲解析

    輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。STM32的定時(shí)器,除了TIM6和TIM7,其他定時(shí)器都有輸入
    發(fā)表于 09-04 11:00 ?6010次閱讀

    stm32 定時(shí)器 捕獲

    輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。STM32的定時(shí)器,除了TIM6和TIM7,其他定時(shí)器都有輸入
    發(fā)表于 09-08 17:07 ?2375次閱讀

    基于STM32定時(shí)器捕獲測量脈寬的應(yīng)用示例

    來實(shí)現(xiàn)脈寬測量,我們可以選用一個(gè)通道、也可以使用兩個(gè)通道。使用1個(gè)通道時(shí),只需使用定時(shí)器基本的輸入捕獲功能結(jié)合中斷或DMA即可實(shí)現(xiàn);若使用兩個(gè)通道時(shí)可以將
    的頭像 發(fā)表于 01-02 18:17 ?1.3w次閱讀
    基于STM32<b class='flag-5'>定時(shí)器</b><b class='flag-5'>捕獲</b>測量脈寬的應(yīng)用示例

    華大HC32-(05)-定時(shí)器輸入捕獲

    華大HC32-(05)-定時(shí)器輸入捕獲
    發(fā)表于 11-23 18:06 ?28次下載
    華大HC32-(05)-<b class='flag-5'>定時(shí)器</b><b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>

    stm32定時(shí)器輸入捕獲配置步驟及實(shí)例筆記

    輸入捕獲的一般配置步驟:初始化定時(shí)器和通道對應(yīng)IO的時(shí)鐘。初始化IO口,模式為輸入:GPIO_Init(); GPIO_InitStructure.GPIO_Mode = GPIO_M
    發(fā)表于 11-23 18:21 ?42次下載
    stm32<b class='flag-5'>定時(shí)器</b><b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>配置步驟及實(shí)例筆記

    STM32CubeMX——定時(shí)器輸入捕獲

    通用定時(shí)器在基本定時(shí)器的基礎(chǔ)上增加了一個(gè)外部引腳,可以實(shí)現(xiàn)輸入捕獲與輸出比較等功能。高級定時(shí)器T
    發(fā)表于 12-02 14:06 ?9次下載
    STM32CubeMX——<b class='flag-5'>定時(shí)器</b><b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>

    STM32定時(shí)器輸入捕獲實(shí)驗(yàn)

    概述輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。STM32 的定時(shí)器,除了 TIM6 和 TIM7,其他定時(shí)器都有輸入
    發(fā)表于 12-14 18:58 ?20次下載
    STM32<b class='flag-5'>定時(shí)器</b><b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>實(shí)驗(yàn)

    通用定時(shí)器輸入捕獲實(shí)驗(yàn)

    文章目錄通用定時(shí)器輸入捕獲實(shí)驗(yàn)(寄存版本)1、作用2、過程3、圖解4、測試方法5、代碼通用定時(shí)器
    發(fā)表于 01-12 19:53 ?9次下載
    通用<b class='flag-5'>定時(shí)器</b>的<b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>實(shí)驗(yàn)

    使用通用定時(shí)器輸入捕獲實(shí)例

    本文將介紹通過使用通用定時(shí)器輸入捕獲功能來記錄按鍵按下的時(shí)間,并通過串口調(diào)試工具打印出按鍵按下的時(shí)間。
    的頭像 發(fā)表于 05-01 09:02 ?1066次閱讀
    使用通用<b class='flag-5'>定時(shí)器</b>的<b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>實(shí)例

    CW32定時(shí)器操作講解——輸入捕獲

    CW32定時(shí)器操作講解——輸入捕獲
    的頭像 發(fā)表于 09-27 16:06 ?973次閱讀
    CW32<b class='flag-5'>定時(shí)器</b>操作講解——<b class='flag-5'>輸入</b><b class='flag-5'>捕獲</b>
    RM新时代网站-首页