STM32F407学习笔记 通用定时器输入捕获部分

//通用定时器输入捕获部分
//输入捕获的用途:
        捕获按键时长、超声波测距模块、红外接收

//输入捕获的作用:
    监测外部输入信号的脉冲宽度
    
//监测高电平信号:
    测量测量上升沿发生的CNT值,加载到CCR寄存器中;再检测下降沿发生时CNT的值,加载到CCR寄存器中;
    两个值相减,就能获得高电平触发的时间;
    1Mhz ----- 数一个数1us
    
//通用定时器输入捕获部分框图及原理:


    1.外部信号先进行滤波处理
    2.信号进入边沿检测器
    3.TI1FP1信号进入预分频器(不建议分频,最好默认一)
    4.当通道检测到上升沿或者下降沿时,产生捕获捕获事件(标志位置一)

//在计算按按键按下所产生的高电平的时间时,必须考虑周期溢出的情况(因为人按下按键到松手的时间一般在100ms左右)
//定时器周期限制,一般来说ARR为16位,最多只能数65536个数,频率若为1Mhz,那么一个周期为65.536ms

//怎么知道周期溢出?
    1.可以用轮询的方式(占用CPU)
    2.采用更新中断(一般采用这种方式好)
    
//总结:
    我们在配置好通用定时器的输入捕获的功能的同时,还需要打开捕获中断与更新中断
    


//输入捕获滤波器的原理:
    与打点计数器类似:
        打点频率越慢,打点个数越多,滤波的效果越好//总的来说我们要让频率慢,打点的个数尽量多
        可以根据外界过来信号的具体情况,来选择是否使用滤波功能
    1.配置时钟分频:决定打点的周期    CR1寄存器
    2.配置滤波器  ---  CCMRx


//TIMx 捕获/比较模式寄存器 1 (TIMx_CCMR1)
    输入捕获部分:
     ICxPSC:输入捕获x 预分频器 (Input capture 1 prescaler) 
    此位域定义 CC1 输入 (IC1) 的预分频比。 
    只要 CC1E=0(TIMx_CCER 寄存器),预分频器便立即复位。 
    00:无预分频器,捕获输入上每检测到一个边沿便执行捕获 
    01:每发生 2 个事件便执行一次捕获 
    10:每发生 4 个事件便执行一次捕获 
    11:每发生 8 个事件便执行一次捕获

    CCxS:捕获/比较 x 选择 (Capture/Compare 1 selection) 
    此位域定义通道方向(输入/输出)以及所使用的输入。 
    00:CC1 通道配置为输出 
    01:CC1 通道配置为输入,IC1 映射到 TI1 上 
    10:CC1 通道配置为输入,IC1 映射到 TI2 上 
    11:CC1 通道配置为输入,IC1 映射到 TRC 上。此模式仅在通过 TS 位(TIMx_SMCR 寄存 器)选择内部触发输入时有效


//TIMx 捕获/比较使能寄存器 (TIMx_CCER)
    CCxNP:捕获/比较 x 输出极性 
    CCx 通道配置为输入: 
    此位与 CCxP 配合使用,用以定义 TIxFP1/TIxFP1 的极性。请参见 CCxP 说明

    CC1 通道配置为输入: 
    CCxNP/CCxP 位可针对触发或捕获操作选择 TIxFP1 和 TIxFP1 的极性。 
    00:上升沿触发捕获
    01:下降沿触发 捕获
    10:保留,不使用此配置
    11:上升沿和下降沿均触发捕获


//总结:CCxNP与CCxP,只有CCxP决定捕获边沿,所以可以将CCxNP保持为零

    CCxE:捕获/比较 x 输出使能
    CCx 通道配置为输入: 
    此位决定了是否可以实际将计数器值捕获到输入捕获/比较寄存器 1 (TIMx_CCRx) 中。 
    0:禁止捕获 
    1:使能捕获 


//捕获按键按下所产生高电平时间长短的思路与例程:
/*
函数功能:TIM5输入捕获通道1初始化
返回值:void
形参:void
函数说明:

*/

void TIM_CaptureInit(void)
{
    u16 pri;
    //①打开时钟GPIOA、TIM5
    RCC->AHB1ENR |= 1 << 0;
    RCC->APB1ENR |= 1 << 3;
        
    //②PA0配置为复用模式
    GPIOA->MODER &=~ (3 << 0);
    GPIOA->MODER |= 2 << 0;
    
    //③PA0与TIM2/TIM5复用关系
    GPIOA->AFR[0] |= 2 << 0;
    
    //④时基单元    PSC:84         ARR:65536
    TIM5->PSC = 84 - 1;
    TIM5->ARR = 65536 - 1;
    TIM5->EGR |= 1 << 0;
    TIM5->SR &=~ (1 << 0);
    
    //⑤配置输入捕获通道
    TIM5->CR1 |= 2 << 8; //配置滤波    CR1:时钟分频    CCMRx滤波器配置
    
    TIM5->CCMR1 |= 0xf << 4;
    TIM5->CCMR1 |= 1 << 0;//CCMRx    
    
    TIM5->CCER &=~ (1 << 3);
    TIM5->CCER &=~ (1 << 1);
    TIM5->CCER |= 1 << 0;//CCER   ---  上升沿

    //⑥使能CC1捕获/比较中断、更新中断
    TIM5->DIER |= 1 << 1;
    TIM5->DIER |= 1 << 0;
    
    //⑦配置NVIC
    pri = NVIC_EncodePriority (5,2,2);
    NVIC_SetPriority(TIM5_IRQn,pri);
    NVIC_EnableIRQ(TIM5_IRQn);
    
    //⑧使能定时器
    TIM5->CR1 |= 1 << 0;
}

u16 n;
u16 CNT1,CNT2;
u32 T;
/*TIM2中断服务函数*/
void TIM5_IRQHandler(void)
{
    if(TIM5->SR & 1 << 0)//判断更新中断标志位置一
    {
        //清除更新标志位
        TIM5->SR &=~ (1 << 0);
        
        //n++;
        n++;
    }
    
    if(TIM5->SR & 1 << 1)//判断输入捕获通道1标志位置一
    {
        //清除输入捕获通道1标志位
        TIM5->SR &=~ (1 << 1);
        
        if(GPIOA->IDR & 1 << 0)//IDR接收到高电平,捕获上升沿,捕获高电平时间开始
        {
            //溢出次数清零 n =0;
            n = 0;
            
            //使用一个静态/全局变量接收CCR寄存器的值(CNT1)
            CNT1 = TIM5->CCR1;
            
            //切换为下降沿捕获  CC1P置一
            TIM5->CCER |= 1 << 1;
        }
        else if(!(GPIOA->IDR & 1 << 0))//IDR接收到低电平,捕获下降沿,高电平结束
        {
            //使用一个静态/全局变量接收CCR寄存器的值(CNT2)
            CNT2 = TIM5->CCR1;
            
            //套公式:T = 65536 * n -CNT1 + CNT2
            T = 65536 * n - CNT1 + CNT2;
            
            //使用串口打印看按键按下时间
            printf("%d\r\n",T);
            
            //切换为上升沿捕获   CC1P清零
            TIM5->CCER &=~ (1 << 1);
        }

    }

}


 

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值