首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

分享:定时器和外部中断完成输入捕获功能,并计算频率和占空比。

分享:定时器和外部中断完成输入捕获功能,并计算频率和占空比。

其实这样的功能只要用一个定时器就可以完成了,不过为了更深地了解定时器输入捕获的功能,我自己设置了用定时器分开定时,外部中断读取信号的方法。只供参考学习。

程序说明:1、定时器2用于产生PWM信号 PA2

               2、定时器3用于定时计算PWM信号的频率和占空比

             3、串口发送数值      

这里声明一下,如果你要捕获的PWM信号不在ARR,PSC计算的范围内,请自己先计算再使用本程序。

#include "stm32f10x_lib.h"
#include "sys.h"
#include "delay.h" //延时子函数
#include "usart.h"
#include "led.h"

#define Input1 PBin(0)// PB0

u16 Counter1;
u16 Counter2;
void EXTIX_Init(void);
void Timer2_Init(u16 arr,u16 psc); //定时器2用于产生PWM信号 PA2
void Timer3_Init(u16 arr,u16 psc);//定时器3用于定时计算PWM信号的频率和占空比  ,这里7200-1=10K

int  main(void)
{
   Stm32_Clock_Init(9); //系统时钟设置
   delay_init(72);//延时函数初始化
   uart_init(72,9600);
   LED_Init();
   EXTIX_Init();//外部中断初始化PB0
   Timer2_Init(6000,720-1); //定时器2用于产生PWM信号 PA2
   Timer3_Init(6000,7200-1); //定时器3用于定时计算PWM信号的频率和占空比  ,这里7200-1=10K
   while(1)
   {
  printf("counter1 = %d \r\n",(Counter1*100)/Counter2); //计算出占空比
     printf("counter2 = %d \r\n",10000/Counter2);//计算出频率

   }
}

/*外部中断用于PWM输入口*/
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<3;     //使能PORTB时钟

GPIOB->CRL&=0XFFFFFFF0;//PB0设置成输入   
GPIOB->CRL|=0X00000008;        
GPIOB->ODR|=1<<0;    //PB0上拉

Ex_NVIC_Config(GPIO_B,0,3);//上升下降沿触发

MY_NVIC_Init(2,1,EXTI0_IRQChannel,2);//抢占2,子优先级1,组2   
}

//外部中断15~10服务程序
void EXTI0_IRQHandler(void)
{      
   if(Input1 ==0)//先是上升沿触发中断
{  
    Counter1 = TIM3->CNT;//读取高电平时间   
}
if(Input1 ==1)//第二次中断是下降沿
{
    Counter2 = TIM3->CNT;//读取总时间
    delay_us(5);//这里要延时一点点再清计算器
    TIM3->CNT = 0;//请计数器   
}
EXTI->PR=1<<0;     //清除LINE0上的中断标志位  
}

/*定时器2用于产生PWM信号*/
void Timer2_Init(u16 arr,u16 psc) //定时器2用于adc采样
{
//此部分需手动修改 IO口设置
RCC->APB1ENR|=1<<0;       //TIM2 时钟使能  
RCC->APB2ENR|=1<<0;    //   
RCC->APB2ENR|=1<<2;    //使能PORTA时钟


GPIOA->CRL&=0XFFFFF0FF;//PA2输出  
GPIOA->CRL|=0X00000B00;//复用功能输出      
GPIOA->ODR|=1<<2;//PA2 上拉

TIM2->ARR=arr;//设定计数器自动重装值   
TIM2->PSC=psc;//预分频器不分频


//PWM
TIM2->CCMR2|=7<<4;  //CH3 PWM2模式      
TIM2->CCMR2|=1<<3; //CH3 预装载使能   
TIM2->CCER|=1<<8;  //OC3  输出使能      
TIM2->CR1=0x0080;   //ARPE使能

//TIM2->CR1|=0x01;    //使能定时器 3

TIM2->CR1|=1<<0; //使能定时器 2
TIM2->CCR3   = 3000;  //占空比初值 =  1440*50% = 720

}
/*定时器3用于产后PWM信号*/
void Timer3_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1;//TIM2时钟使能   
  TIM3->ARR=arr;  //设定计数器自动重装值//刚好1ms   
TIM3->PSC=psc;  //预分频器,

TIM3->DIER|=1<<0;   //允许更新中断   
TIM3->DIER|=1<<6;   //允许触发中断   
TIM3->CR1|=0x01;    //使能定时器3
   MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2         
}

//定时器3中断服务程序  
void TIM3_IRQHandler(void)
{                  
if(TIM3->SR&0X0001)//溢出中断
{
  LED0=~LED0;               
}      
TIM3->SR&=~(1<<0);//清除中断标志位      
}
继承事业,薪火相传
返回列表