OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9463|回复: 5

请教有关定时器捕获模式测脉宽的问题

[复制链接]

2

主题

5

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-23
在线时间
0 小时
发表于 2013-3-23 16:27:25 | 显示全部楼层 |阅读模式

           #include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"  
#include "delay.h" 
//#include "led.h"
//#include "key.h"
//#include "exti.h"
//#include "wdg.h"
#include "timer.h"   
//Mini STM32开发板范例代码7
//定时器中断 实验
//正点原子@ALIENTEK
//2010.6.1 
  
u16   IC2Value;
u16   DutyCycle;
u16   Frequency;

void PWM_Init(u16 arr,u16 psc);
void Capture_Init(u16 arr,u16 psc);
int  main(void)
{
  Stm32_Clock_Init(9); //系统时钟设置
  delay_init(72);//延时函数初始化 
  uart_init(72,9600);
  PWM_Init(1500,72-1);  //不分频。PWM频率=72000/1440=5Khz
  Capture_Init(2000,72-1); 
  while(1)
  {
   printf("suqingxiao\r\n");
  delay_ms(100);
  }
}

//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void PWM_Init(u16 arr,u16 psc)
{        
 //此部分需手动修改 IO口设置 
 RCC->APB2ENR|=1<<0;    // 
 RCC->APB1ENR|=1<<2;       //TIM4 时钟使能
 RCC->APB2ENR|=1<<3;    //使能PORTB时钟
  
 GPIOB->CRL&=0XF0FFFFFF;//PB6 输出 
 GPIOB->CRL|=0X0B000000;//复用功能输出      
 GPIOB->ODR|=1<<6;//PB6 上拉  
 
 TIM4->ARR=arr;//设定计数器自动重装值  
 TIM4->SC=psc;//预分频器不分频 

 TIM4->CCMR1|=7<<4;  //CH1 PWM2模式     
 TIM4->CCMR1|=1<<3; //CH1 预装载使能      
 TIM4->CCER|=1<<0;  //OC1  输出使能     
 TIM4->CR1=0x0080;  //ARPE使能  

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

 TIM4->CCR1   = 500;  //占空比初值 =  1440*50% = 720                                      
}


void Capture_Init(u16 arr,u16 psc)
{
 //此部分需手动修改 IO口设置 
 RCC->APB2ENR|=1<<0;    // 
 RCC->APB1ENR|=1<<0;       //TIM2 时钟使能
 RCC->APB2ENR|=1<<2;    //使能PORTA时钟
   
  TIM2->ARR=arr;  //设定计数器自动重装值//刚好1ms   
 TIM2->SC=psc;  //预分频器,

 GPIOA->CRL&=0XFFFFFFF0;//PA0 输入 
 GPIOA->CRL|=0X00000004;//复用功能输入      
 GPIOA->ODR|=1<<0;//PA0 上拉
  
 TIM2->SMCR|=0x00D4;
 //TIM2->SMCR|= 1<<5; //MSM=1 主/从模式
 //TIM2->SMCR|= 5<<4; //TS=101 触发选择
 //TIM2->SMCR|= 4<<0; //SMS=100 复位模式

 TIM2->CCMR1|=1<<0;//CC1S=01 选择输入端 
 TIM2->CCMR1|=3<<4; //IC1F=0011配置输入滤波器
 TIM2->CCER|=0<<1; //CC1P=0 选择有交转换边沿
 TIM2->CCMR1|=0<<2; //IC1PS=00 配置输入分频
 TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中

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

//定时器2中断服务程序 
void TIM2_IRQHandler(void)
{                 
 IC2Value = TIM2->CCR1;//读取CCR1也可以清CC1IF标志位
 printf("IC2Value = %d\r\n",1000000/IC2Value);                    
 TIM2->SR&=~(1<<1);//清除中断标志位     
}


 


 


 

结果一直是:

IC2Value = 666

原子师傅能帮忙分析一下么

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-23
在线时间
0 小时
 楼主| 发表于 2013-3-23 16:29:16 | 显示全部楼层
             IC2Value应该会一直变的呀
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2013-3-23 16:34:13 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2013-3-23
在线时间
0 小时
 楼主| 发表于 2013-3-23 16:37:55 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
谢谢您
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-3-17
在线时间
0 小时
发表于 2014-3-17 09:50:19 | 显示全部楼层
原子哥,我用了你的那个程序,但是就是进不了中断,我在中断中设置了一个输出引脚,但是测它的电平,发现总是为零,不知是怎么回事,请你帮帮我
void TIM5_Cap_Init(u16 arr,u16 psc)
{  
RCC->APB1ENR|=1<<3;    //TIM5 时钟使能 
RCC->APB2ENR|=1<<2;     //使能PORTA时钟  
 
GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置                                                              
GPIOA->CRL|=0X00000008; //PA0 输入                                                                       GPIOA->CRL|=0X00000004 这里有程序说是4
GPIOA->ODR|=0<<0; //PA0 下拉
  
  TIM5->ARR=arr;   //设定计数器自动重装值   
TIM5->SC=psc;   //预分频器 

TIM5->CCMR1|=1<<0; //CC1S=01  选择输入端 IC1映射到TI1上
  TIM5->CCMR1|=0<<4;  //IC1F=0000 配置输入滤波器 不滤波
  TIM5->CCMR1|=0<<2;  //IC1PS=00  配置输入分频,不分频                                             这里修改了一下
  TIM5->CCMR1|=0<<3;
 
  TIM5->CCER|=0<<1;  //CC1P=0 上升沿捕获
  TIM5->CCER|=1<<0;  //CC1E=1  允许捕获计数器的值到捕获寄存器中

TIM5->DIER|=1<<1;    //允许捕获中断
  TIM5->DIER|=1<<0;    //允许更新中断                                                                   这句是什么意思,更新中断是什么意思
TIM5->CR1|=0x01;     //使能定时器2
MY_NVIC_Init(2,0,TIM5_IRQChannel,2);//抢占2,子优先级0,组2    
}

//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获高电平后溢出的次数
u8  TIM5CH1_CAPTURE_STA=0; //输入捕获状态     
u16 TIM5CH1_CAPTURE_VAL; //输入捕获值
u8  flag=0;
//定时器5中断服务程序  
void TIM5_IRQHandler(void)
{      
u16 tsr;
tsr=TIM5->SR;
  if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{     
if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM5CH1_CAPTURE_VAL=0XFFFF;
}else TIM5CH1_CAPTURE_STA++;
}  
}
if(tsr&0x02)//捕获1发生捕获事件
{
if(TIM5CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
  TIM5CH1_CAPTURE_VAL=TIM5->CCR1; //获取当前的捕获值.
  TIM5->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获                
}else   //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA=0; //清空
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM5->CNT=0; //计数器清空
  TIM5->CCER|=1<<1;  //CC1P=1 设置为下降沿捕获
}     
}
}

if(flag==0)                                 //这个是我设置的,想检测它有没有变化,在led.c中使能了时钟和配置了它  flag也设好了
{
GPIOA->ODR|=1<<13;
flag=1;
}
else
{
GPIOA->ODR&=~(1<<13);
flag=0;
}
TIM5->SR=0;//清除中断标志位      
}
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2014-3-17
在线时间
0 小时
发表于 2014-3-17 09:59:27 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥,帮帮我解决我上面那个问题好吗,搞了好久没有解决
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-13 16:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表