OpenEdv-开源电子网

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

定时器输入捕获求助

[复制链接]

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
发表于 2012-12-9 20:24:47 | 显示全部楼层 |阅读模式

想用定时器捕获脉宽长度,根据库函数捉摸了几天,代码如下
#include "sys.h"
#include "usart.h"  
#include "delay.h" 
#include "timer.h"
//extern u16 TIM4CH1_CAPTURE_VAL; //输入捕获值
int main(void)
{     
  Stm32_Clock_Init(9);  //系统时钟设置
 uart_init(72,9600);    //串口初始化为9600
 delay_init(72);        //延时初始化 
  TIM4_Cap_Init(0XFFFF,72); //以1Mhz的频率计数
}


void TIM4_Cap_Init(u16 arr,u16 psc)
  {
 RCC->APB1ENR|=1<<2;    //TIM4 时钟使能
 RCC->APB2ENR|=1<<3;     //使能PORTB时钟
 RCC->APB2ENR|=1<<0; 
 
 GPIOB->CRL&=0XF0FFFFFF; //PB6 清除之前设置 
 GPIOB->CRL|=0X08000000; //PB6 输入  
 GPIOB->ODR|=1<<6;  //PB6 上拉
  
  TIM4->ARR=arr;    //设定计数器自动重装值  
 TIM4->SC=psc;    //预分频器
 TIM4->CR1&=~(1<<8);    
 TIM4->CR1&=~(1<<9);  //时钟分割CKD=00
 TIM4->CR1&=~(1<<4);     //计数器向上计数
 TIM4->CCMR1|=1<<0;  //CC1S=01  选择输入端 IC1映射到TI1上
  TIM4->CCMR1&=~(1<<4);   //IC1F=0000 配置输入滤波器 不滤波
 TIM4->CCMR1&=~(1<<5);
 TIM4->CCMR1&=~(1<<6);
 TIM4->CCMR1&=~(1<<7);
  TIM4->CCMR1&=~(1<<2);  //IC1PS=00  配置输入分频,不分频
 TIM4->CCMR1&=~(1<<3);

 TIM4->CCER|=1<<1;   //CC1P=0 下降沿捕获
 TIM4->CCER|=1<<0;   //CC1E=1  允许捕获计数器的值到捕获寄存器中

 TIM4->DIER|=1<<1;    //允许捕获中断    
 //TIM4->DIER|=1<<0;    //允许更新中断
    //TIM4->DIER|=1<<6;       //使能中断 
 TIM4->CR1|=0x01;     //使能定时器4
 MY_NVIC_Init(1,3,TIM4_IRQChannel,2);//抢占2,子优先级0,组2
  }
 
          
u16 TIM4CH1_CAPTURE_VAL; //输入捕获值
//定时器5中断服务程序 
void TIM4_IRQHandler(void)
{      
 TIM4CH1_CAPTURE_VAL=TIM4->CCR1;
 printf("TIM4CH1_CAPTURE_VAL = %d\r\n",TIM4CH1_CAPTURE_VAL);
 TIM4->SR&=~(1<<1);//清除中断标志位     
}
void SystemInit (void){}
结果打印出来的数据竟然是这样的


各位大侠有时间给看看,都要疯了,对照了手册上的14.3.5章节的“输入捕获模式”感觉寄存器设置没有什么错误,可为什么打印出来的结果会是这样。

 


 

 

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-10 10:02:10 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我的思路就是想要捕获PWM波高电平的时间,就是只捕获脉宽
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-10 11:35:06 | 显示全部楼层
你这样代码有问题的。
参考战舰板的例程。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-11 10:32:19 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我明白了,貌似只设一个边沿的话,测出来的还是周期,我之所以会出现这样的乱码,是因为我用两块板实验,一个产生PWM,一个捕获,没有共地。对了,原子哥,战舰输入捕获的例程中捕获状态标志位TIM5CH1_CAPTURE_STA为什么是如下设置,想不明白。
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获高电平后溢出的次数
u8  TIM5CH1_CAPTURE_STA=0; //输入捕获状态
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-11 10:43:04 | 显示全部楼层
回复【5楼】sunky@feeling:
---------------------------------
因为我要捕获高电平脉宽,而输入捕获某个时刻,只能处于一种模式(上升沿捕获/下降沿捕获),所以必须在捕获一个上升沿以后,设置为下降沿捕获,这样才能成功捉到一个高电平啊!
剩下的,如果高电平时间很长,也就是上升沿出现后,长时间没出现下降沿,那么定时器就可能溢出,那就得做溢出处理,所以,剩余的位数,用作溢出计数。这样,整个就比较完美了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-11 17:08:41 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
谢谢原子大哥,我明白了,我想把战舰版上的实验10输入捕获改成4个通道同时捕获,你看能实现不?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-11 22:18:23 | 显示全部楼层
可以的.
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-12 16:08:50 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
我看了捕获的例程,在单通道里面每次在设置下降沿之前都(TIM4->CNT=0;)把计数器清零了,如果设置成多路捕获的话,在1通道捕获时其他通道还没有捕获完成计数器就清零了,这样其它的通道就不正确了。怎么办?
if(tsr&0x02)//捕获1发生捕获事件
{
if(TIM4CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM4CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    TIM4CH1_CAPTURE_VAL=TIM5->CCR1; //获取当前的捕获值.
  TIM4->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM4CH1_CAPTURE_STA=0; //清空
TIM4CH1_CAPTURE_VAL=0;
TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM4->CNT=0; //计数器清空
  TIM4->CCER|=1<<1;  //CC1P=1 设置为下降沿捕获
}     
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-12 16:49:02 | 显示全部楼层
回复【9楼】sunky@feeling:
---------------------------------
那你就得多加几个变量,记录下开始捕获的时刻,CNT的值,然后减一下就是了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-12 19:26:34 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
恩,我试试,谢谢
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-17 11:28:08 | 显示全部楼层
回复【11楼】sunky@feeling:
---------------------------------
原子哥,经过几天的思考,我还是有些事情没有想明白:也就是我在中断函数里面,如果设置两个变量(对于1通道):
u16 this_time_ch1=0;
u16 last_time_ch1=0;
u8 ch1_value;
在上升沿捕获的时候
this_time_ch1=TIM4->CNT;
在下降沿的时候
last_time_ch1=TIM4->CNT;
然后1通道捕获的脉宽就是
ch1_value=last_time_ch1-this_time_ch1;
这样就不在去读TIM4->CCR1中的值了吗?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-17 12:06:25 | 显示全部楼层
当然还是要读啊
读了CCR1的值,还需要读CNT。两者结合。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-17 15:05:38 | 显示全部楼层
回复【13楼】正点原子:
---------------------------------
原子哥,不是当以检测到ICx上的边沿的的时候,计数器的值就被直接拷贝到CCR中去了吗,如果我在检测到上升沿是读一下CCR,然后在在下降沿的时候再读一下CCR,这样的话不就可以不去读CNT 中的值了吗,将两个CCR的读数一减就是脉宽了是不是?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-17 15:39:20 | 显示全部楼层
是这么说,但是如果溢出呢?
比如捕获到上升沿以后,下降沿迟迟不到,导致CNT溢出,此时就必须做标记。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-18 09:40:32 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
我捕获的波形是已知的,4路周期已知的PWM波形,占空比是变化的,我主要是捕获其高电平的时间长度,所以是不是不用考虑CNT的溢出吧。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-18 10:21:59 | 显示全部楼层
那如果能确保不会溢出,那可以不做溢出处理。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-18 15:29:45 | 显示全部楼层
回复【17楼】正点原子:
---------------------------------
谢谢原子哥指点。
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-18 16:44:05 | 显示全部楼层
回复【18楼】sunky@feeling:
---------------------------------
原子哥,不好意思,在你百忙之中打扰你,小弟实在表示歉意,由于周围没有老师可问,实在没有办法才一直揪着你问问题,希望你谅解,这是我根据战舰版捕获的里程改的4通道捕获的代码的中断服务程序,前面寄存器的配置没有多大问题,在此就没有贴上来,你看看这样能实现不,谢谢原子哥,最后再一次抱歉打扰你。
#include "timer.h"
#include "usart.h"
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获高电平后溢出的次数
u8  TIM4CH1_CAPTURE_STA=0; //输入捕获状态
u8  TIM4CH2_CAPTURE_STA=0;
u8  TIM4CH3_CAPTURE_STA=0;
u8  TIM4CH4_CAPTURE_STA=0;     

u16 TIM4CH1_CAPTURE_VAL; //高电平值捕获值
u16 TIM4CH2_CAPTURE_VAL;
u16 TIM4CH3_CAPTURE_VAL;
u16 TIM4CH4_CAPTURE_VAL;

u16 TIM4CH1_U_CAPTURE_VAL; //上升沿捕获当前值
u16 TIM4CH2_U_CAPTURE_VAL;
u16 TIM4CH3_U_CAPTURE_VAL;
u16 TIM4CH4_U_CAPTURE_VAL;

u16 TIM4CH1_D_CAPTURE_VAL; //下降沿捕获当前值
u16 TIM4CH2_D_CAPTURE_VAL;
u16 TIM4CH3_D_CAPTURE_VAL;
u16 TIM4CH4_D_CAPTURE_VAL; 
//定时器4中断服务程序  
void TIM4_IRQHandler(void)
{      
u16 tsr;
tsr=TIM4->SR;
  if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{     
if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM4CH1_CAPTURE_VAL=0XFFFF;
}else TIM4CH1_CAPTURE_STA++;
}  
}
if(tsr&0x02)//捕获1发生捕获事件
{
if(TIM4CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM4CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    TIM4CH1_D_CAPTURE_VAL=TIM4->CCR1; //获取当前下降沿的捕获值
TIM4CH1_CAPTURE_VAL=TIM4CH1_D_CAPTURE_VAL-TIM4CH1_U_CAPTURE_VAL;  //获取高电平时间
  TIM4->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM4CH1_CAPTURE_STA=0; //清空
TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM4CH1_U_CAPTURE_VAL=TIM4->CCR1; //获取当前上升沿的值
  TIM4->CCER|=1<<1;  //CC1P=1 设置为下降沿捕获
}     
}               
  }

  
  if((TIM4CH2_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{     
if(TIM4CH2_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM4CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM4CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM4CH2_CAPTURE_VAL=0XFFFF;
}else TIM4CH2_CAPTURE_STA++;
}  
}
if(tsr&0x04)//捕获2发生捕获事件
{
if(TIM4CH2_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM4CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    TIM4CH2_D_CAPTURE_VAL=TIM4->CCR2; //获取当前下降沿的捕获值
TIM4CH2_CAPTURE_VAL=TIM4CH2_D_CAPTURE_VAL-TIM4CH2_U_CAPTURE_VAL;  //获取高电平时间
  TIM4->CCER&=~(1<<5); //CC2P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM4CH2_CAPTURE_STA=0; //清空
TIM4CH2_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM4CH2_U_CAPTURE_VAL=TIM4->CCR2; //获取当前上升沿的捕获值
  TIM4->CCER|=1<<5;  //CC2P=1 设置为下降沿捕获
}     
}               
  }

  
  if((TIM4CH3_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{     
if(TIM4CH3_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM4CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM4CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM4CH3_CAPTURE_VAL=0XFFFF;
}else TIM4CH3_CAPTURE_STA++;
}  
}
if(tsr&0x08)//捕获3发生捕获事件
{
if(TIM4CH3_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM4CH3_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    TIM4CH3_D_CAPTURE_VAL=TIM4->CCR3; //获取当前下降沿的捕获值
TIM4CH3_CAPTURE_VAL=TIM4CH3_D_CAPTURE_VAL-TIM4CH3_U_CAPTURE_VAL;  //获取高电平时间
  TIM4->CCER&=~(1<<9); //CC3P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM4CH3_CAPTURE_STA=0; //清空
TIM4CH3_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM4CH3_U_CAPTURE_VAL=TIM4->CCR3; //获取当前上降沿的捕获值
  TIM4->CCER|=1<<9;  //CC3P=1 设置为下降沿捕获
}     
}               
  }

  
  if((TIM4CH4_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(tsr&0X01)//溢出
{     
if(TIM4CH4_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM4CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM4CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次
TIM4CH4_CAPTURE_VAL=0XFFFF;
}else TIM4CH4_CAPTURE_STA++;
}  
}
if(tsr&0x10)//捕获4发生捕获事件
{
if(TIM4CH4_CAPTURE_STA&0X40) //捕获到一个下降沿 
{   
TIM4CH4_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    TIM4CH4_D_CAPTURE_VAL=TIM4->CCR4; //获取当前下降沿的捕获值
TIM4CH4_CAPTURE_VAL=TIM4CH4_D_CAPTURE_VAL-TIM4CH4_U_CAPTURE_VAL;  //获取高电平时间
  TIM4->CCER&=~(1<<13); //CC4P=0 设置为上升沿捕获
}else   //还未开始,第一次捕获上升沿
{
TIM4CH4_CAPTURE_STA=0; //清空
TIM4CH4_CAPTURE_STA|=0X40; //标记捕获到了上升沿
  TIM4CH4_U_CAPTURE_VAL=TIM4->CCR4; //获取当前上升沿的捕获值
  TIM4->CCER|=1<<13;  //CC4P=1 设置为下降沿捕获
}     
}               
  }

TIM4->SR=0;//清除中断标志位
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-12-18 21:50:31 | 显示全部楼层



你这代码有问题的,上面是我画的一个简图。
以一个通道为例,CCRx为某个通道的输入捕获值寄存器,CCRx1和CCRx2代表2个不同时刻的捕获值。
1,假设CCRx1是上升沿的捕获值,CCRx2是随后的下降沿捕获值。那么高电平脉宽就是:ARR-CCRx1+CCRx2.
2,假设CCRx1是下降沿捕获值,CCRx2是上升沿捕获的值,那么高电平脉宽就是:ARR-CCRx2+CCRx1.
以上是假设两次捕获之间的时间,不超过CNT的一次溢出时间,当然你前面提到,你的高电平脉宽不会超过1次CNT的溢出时间。那么只要考虑上面两种情况就可以了。
如果要考虑溢出,情况就会复杂一点,请自行分析。




我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
 楼主| 发表于 2012-12-19 10:33:24 | 显示全部楼层
回复【20楼】正点原子:
---------------------------------
原子哥,我弄出来了,我没有设捕获标志位,而是像下面这样弄的
        u16 tsr;
tsr=TIM4->SR;
if(tsr&0x02)//捕获1发生捕获事件
   {
     TIM4->SR&=~(1<<1); //清出中断标志位
 if(PB6_IN)  //输入脚电平
   {
     TIM4->CCER|=1<<1;//当前为上升沿,设置下次采样为下降沿
 TIM4CH1_U_CAPTURE_VAL=TIM4->CCR1;
   }
 else
   {
     TIM4->CCER&=~(1<<1);//当前为下降沿,设置下次采样为上升沿
 TIM4CH1_D_CAPTURE_VAL=TIM4->CCR1;
 if(TIM4CH1_D_CAPTURE_VAL>TIM4CH1_U_CAPTURE_VAL)
    {
  TIM4CH1_CAPTURE_VAL=(TIM4CH1_D_CAPTURE_VAL-TIM4CH1_U_CAPTURE_VAL);
                                           }
 else
    {
  TIM4CH1_CAPTURE_VAL=((0xffff-TIM4CH1_U_CAPTURE_VAL)+TIM4CH1_D_CAPTURE_VAL);
    }
 temp1=TIM4CH1_CAPTURE_VAL;
   }
程序用jink仿真结果正常,但就是用串口打印不出结果,谢谢原子哥的指点,太感谢了。
回复 支持 反对

使用道具 举报

14

主题

168

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
497
金钱
497
注册时间
2013-4-1
在线时间
25 小时
发表于 2013-7-18 15:15:22 | 显示全部楼层
回复【21楼】sunky@feeling:
---------------------------------
哥们,你的程序弄好了吗?正好我在学习多通道捕获,几个定时器的通道工作回了,但是一个定时器的多通道还不会,搞了几天了!不知道你的源码能分享一下吗?
回复 支持 反对

使用道具 举报

14

主题

168

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
497
金钱
497
注册时间
2013-4-1
在线时间
25 小时
发表于 2013-7-18 17:32:39 | 显示全部楼层
回复【21楼】sunky@feeling:
---------------------------------
就是不用考虑溢出不设置标志变量,那主函数里面如何判断已经捕获了呢?如何再次开启下一次的捕获?
回复 支持 反对

使用道具 举报

8

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2014-5-15
在线时间
8 小时
发表于 2014-6-5 15:55:48 | 显示全部楼层
回复【20楼】正点原子:
---------------------------------
原子哥,我在做那个输入捕获试验时,设置计数器TIM2_Cap_Init(0XFFFF,7); //以1MHZ的频率计数,我是默认用系统内部时钟的,为什么改变这个psc预分频值的时候,最后

if(TIM2CH1_CAPTURE_STA&0X80)
{
temp=TIM2CH1_CAPTURE_STA&0X3F;
temp*=65536; //溢出时间总和
temp+=TIM2CH1_CAPTURE_VAL; //得到总的低电平时间
// printf("周期:%d us\r\n",temp); //打印总的低电平时间
TIM2CH1_CAPTURE_STA=0; //开启下一次捕获
LED=1;
}

这里的temp根本不变呢?就好像计数器的计数频率没有改变一样,这是为什么,可能是哪里配置错误了么?

这是我按照教程配置的TIM2时钟捕获

//定时器2通道1输入捕获配置
//arr:自动重装值
//psc:时钟预分频数
void TIM2_Cap_Init(u16 arr,u16 psc)  //刚开始配置成捕获低电平脉宽
{
RCC->APB1ENR|=1<<0;//TIM2时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0XFFFFFFF0; //初始化PA0;
GPIOA->CRL|=0X00000008; //配置PA0为输入
GPIOA->ODR|=1<<0; //PA0上拉输入  因为是下降沿捕获
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->SC=psc; //预分频器
TIM2->CCMR1|=1<<0; //CC1S=01 选择输入端IC1映射到TI1上
TIM2->CCMR1&=0XFF0F; //IC1F=0000 配置输入滤波器 不滤波
TIM2->CCMR1&=0XFFF3; //IC1PS=00 配置输入分频,不分频
TIM2->CCER|=1<<1; //CC1P=1  下降沿捕获
TIM2->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中
TIM2->DIER|=1<<1; //允许捕获中断
TIM2->DIER|=1<<0; //允许更新中断
TIM2->CR1|=0x01; //使能定时器2
MY_NVIC_Init(2,0,TIM2_IRQn,2); //抢占2,子优先级0,组2
}

新手菜鸟,还望原子哥帮忙解答一下
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-6 00:51:38 | 显示全部楼层
回复【24楼】whut-showming:
---------------------------------
具体代码在哪里改的?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2014-5-15
在线时间
8 小时
发表于 2014-6-6 09:07:25 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
哦,就是根据原子那个开发指南的第十五个实验——输入捕获,改的。因为我用的是STM32F103C8没有TIM5定时器,就全部改为TIM2了,其他的没怎么改。
回复 支持 反对

使用道具 举报

8

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2014-5-15
在线时间
8 小时
发表于 2014-6-6 09:09:48 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
回复【25楼】正点原子:
---------------------------------
哦,对了,原子哥,我昨天找了一个帖子,上面说:按照ST手册说明(见前面引用说明,原文参考英文版页313/679,页/524中文),STM32各定时器不但对外计数有预分频功能,对外捕获也有预分频功能(Ti1~4输入口)。对外计数预分频功能正常,而捕获预分频无效(怎么设置都是一分频),这就是我要说的。大家可以测试ST提供的一个捕获例子,见目录内的..TIMPWM_Input内的例子,此例给的是一分频,可以将分频因子修改测试,见前面所述。
这是帖子的网址:http://bbs.ic37.com/bbsview-32048.htm  你看是不是这样呢?
回复 支持 反对

使用道具 举报

8

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
157
金钱
157
注册时间
2014-5-15
在线时间
8 小时
发表于 2014-6-6 14:30:45 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
原子大哥,再请教一个问题,STM32的输入捕获,一定要把那个捕获端口配置为上下拉模式吗?配置成浮空输入行吗?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-6 23:15:15 | 显示全部楼层
回复【28楼】whut-showming:
---------------------------------
应该是可以的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

10

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
122
金钱
122
注册时间
2014-11-15
在线时间
17 小时
发表于 2014-11-20 15:52:08 | 显示全部楼层
回复【28楼】whut-showming:
---------------------------------
哥们,能把原子哥关于捕获的例程发给我吗,我邮箱1054113158@QQ.COM,谢谢了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-28 21:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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