OpenEdv-开源电子网

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

定时器 输入捕获,测外部输入脉冲的数量,数值不对啊?程序问题在哪??

[复制链接]

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
发表于 2015-7-2 11:33:07 | 显示全部楼层 |阅读模式
5金钱

如题,外部输出脉冲到stm32,占空比50%; 想用单片机定时器输入捕获 脉冲的数量; 测的结果不对啊??

问题出在哪里ne ??   用的原子的例程改的;


程序如下:

//定时器5通道1输入捕获配置
//arr:自动重装值
//psc:时钟预分频数
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->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<<10;  //IC2PS=00  配置输入分频,不分频

 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; //输入捕获值

//定时器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 设置为下降沿捕获
   }     
  }                    
  }
 TIM5->SR=0;//清除中断标志位     
}




主函数::

extern u8  TIM5CH1_CAPTURE_STA;  //输入捕获状态          
extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值
int main(void)
{   
 u32 temp=0;
 u32 num=0;  
  Stm32_Clock_Init(9);  //系统时钟设置
 uart_init(72,9600);    //串口初始化为9600
 delay_init(72);        //延时初始化 
  TIM3_PWM_Init(899,0);   //不分频。PWM频率=72000/(899+1)=80Khz
  TIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数
    while(1)
 {
    
   delay_ms(10);
  LED0_PWM_VAL++;
  if(LED0_PWM_VAL==300)LED0_PWM_VAL=0;    
   if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平

  { 

  num=num+1;    //计数加一
   temp=TIM5CH1_CAPTURE_STA&0X3F;
   temp*=65536;     //溢出时间总和
   temp+=TIM5CH1_CAPTURE_VAL;  //得到总的高电平时间
   printf("NUM:%d \r\n",num); //打印总的脉冲数量
    TIM5CH1_CAPTURE_STA=0;   //开启下一次捕获
  }
 }
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-2 21:23:03 | 显示全部楼层
低频的时候,准确么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
 楼主| 发表于 2015-7-3 20:13:47 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
低频相对还好一些,我这个使用霍尔流量计给stm32输入信号,可能硬件上也要做些处理》??

跟传感器也有关系;;  原来用的一种霍尔流量计是高频的,测试有些问题;  现在用的相对还好
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-3 21:18:59 | 显示全部楼层
回复【3楼】laoqier:
---------------------------------
计算脉冲个数,推荐用外部计数器模式
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
 楼主| 发表于 2015-7-4 22:06:34 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
你是指用外部时钟模式吗?   我用外部时钟计数模式测得很有问题,测得的脉冲数不对,少了很多;我在上面的程序加了以下的配置函数,还需要配置其他的么?原子哥??

// TIM5->CCMR1|=7<<3;   // 外部时钟模式 SMS=111;
// TIM5->CCMR1|=5<<7;   // TI1触发  TS=101;
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-5 22:39:48 | 显示全部楼层
回复【5楼】laoqier:
---------------------------------
检查你的其他代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
 楼主| 发表于 2015-7-6 21:57:12 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
原子哥啊,我对定时器输入捕获的程序不是很理解啊::
在main函数里 

  int main(void)
 {   
  u32 temp=0; 
  u32 num=0;  
   Stm32_Clock_Init(9);  //系统时钟设置
 uart_init(72,9600);    //串口初始化为9600
  delay_init(72);        //延时初始化 
   TIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 
    while(1)
  {
      
    delay_ms(10);   
    if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平 
  {  
  num=num+1;    //计数加一
   printf("NUM:%d \r\n",num); //打印总的脉冲数量
    TIM5CH1_CAPTURE_STA=0;   //开启下一次捕获
  }
  }
 } 
  我这样写 ,能不能够达到对捕获的脉冲个数进行计数的功能啊?程序是用你的改编的;

现在的问题是可以计数的,但是如果端口一直是高电平,他就会一直计数,,  设置的上升沿捕获,为什么在外部一直为高电平时他还会计数呢??求教啊
回复

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
 楼主| 发表于 2015-7-6 22:23:17 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
虽然是设置了上升沿捕获,但是计数累加num,是在捕获到高电平时累加,如果持续为高,就一直在加,应该是这个问题;;

但是我应该怎么计数 才是正确的呢???  >_<
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-6 22:30:31 | 显示全部楼层
回复【8楼】laoqier:
---------------------------------
你代码没改对。
你可以下载我们例程,测试下。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

7

主题

32

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2015-4-16
在线时间
13 小时
 楼主| 发表于 2015-7-7 12:35:09 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
我这个就是下载的您的例程 输入捕获修改的,,因为你的程序里也没有计算多少个脉冲的部分吧;;
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-7 22:55:38 | 显示全部楼层
回复【11楼】laoqier:
---------------------------------
我们例程是用来统计脉冲宽度的,不是用来统计脉冲个数的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

26

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-3-27
在线时间
17 小时
发表于 2018-5-16 21:00:12 | 显示全部楼层
正点原子 发表于 2015-7-7 22:55
回复【11楼】laoqier:
---------------------------------
我们例程是用来统计脉冲宽度的,不是用来统计脉 ...

统计脉冲个数需要改哪个
回复

使用道具 举报

3

主题

26

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-3-27
在线时间
17 小时
发表于 2018-5-16 21:01:11 | 显示全部楼层
正点原子 发表于 2015-7-7 22:55
回复【11楼】laoqier:
---------------------------------
我们例程是用来统计脉冲宽度的,不是用来统计脉 ...

统计脉冲个数具体要改动哪个变量     感谢
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-5-17 00:59:35 | 显示全部楼层
abcdefg123abc 发表于 2018-5-16 21:01
统计脉冲个数具体要改动哪个变量     感谢

要自己改代码,不是一个变量的问题
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

26

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-3-27
在线时间
17 小时
发表于 2018-5-17 12:11:00 | 显示全部楼层
正点原子 发表于 2018-5-17 00:59
要自己改代码,不是一个变量的问题

我是菜鸟,能具体指点一下改哪些吗
回复

使用道具 举报

3

主题

26

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-3-27
在线时间
17 小时
发表于 2018-5-17 14:49:34 | 显示全部楼层
正点原子 发表于 2018-5-17 00:59
要自己改代码,不是一个变量的问题

能不能具体说一下改动的内容,比较急
回复

使用道具 举报

3

主题

26

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2018-3-27
在线时间
17 小时
发表于 2018-5-17 15:24:58 | 显示全部楼层
正点原子 发表于 2015-7-7 22:55
回复【11楼】laoqier:
---------------------------------
我们例程是用来统计脉冲宽度的,不是用来统计脉 ...


void TIM3_CH2_Excnt_Init(u16 arr,u16 psc)
{   
    RCC->APB1ENR|=1<<1;    //TIM3 ????  
    RCC->APB2ENR|=1<<2;        //??PORTA??   

    GPIOA->CRL&=0X0FFFFFFF;      //PA7 ??????   
    GPIOA->CRL|=0X80000000;      //PA7 ??   
    GPIOA->ODR|=1<<7;          //PA7 ??

    TIM3->ARR=arr;    //??????????   
    TIM3->PSC=psc;    //????  

    TIM3->CCMR1|=1<<8;  //CC2S=01  ????? IC2???TI2?
    TIM3->CCMR1|=0<<12;     //IC2F=0000 ??????? ???

    TIM3->CCER|=1<<5;   //CC1P=0   ?????
    TIM3->SMCR|=6<<4;   //????:?????????2(TI2FP2)
    TIM3->SMCR|=7<<0;   //??????1
    TIM3->CR1|=1<<0;    //?????,CEN=1
}

int main(void)
{   
    u32 oldcnt=0;   
    Stm32_Clock_Init(9);     //??????
    uart_init(72,9600);      //??????9600
    delay_init(72);          //?????  
    TIM3_CH2_Excnt_Init(0X0F,0);  //????,???0xffff
    while(1)
    {
        delay_ms(1000);
        if(oldcnt!=TIM3->CNT)
        {
            oldcnt=TIM3->CNT;
            printf("cnt:%d\r\n",oldcnt);
           
                                }  
    }
}
原子哥我说的就是这个程序,怎么吧测量脉冲宽度改为脉冲个数
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-17 13:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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