OpenEdv-开源电子网

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

怎样用定时器1精确判断外部脉冲增量

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
发表于 2014-4-24 11:32:24 | 显示全部楼层 |阅读模式
STM32F103单片机,我现在用定时器2计数功能计数外部光栅通过光电开关的脉冲个数,与此同时用定时器1判断脉冲个数每增加一个,就进行一步其他运算,程序如下:

时钟64M    PCLK1=32M  则 fTIM2=64M        PCLK2=64M  则fTIM1=64M
定时器初始化
__inline static void stm32_TimerSetup (void)
{
//TIM1
    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;                     // enable clock for TIM1     RCC_APB2ENR_TIM1EN  0x00000800


      TIM1->SC = 0;                                                       // set prescaler        
      TIM1->ARR = 0xffff;                                                 // set auto-reload

      TIM1->CR1 = 0x0004;                                              // set command register 1
      TIM1->CR2 = 0;                                                      // set command register 2

      TIM1->DIER = 0x0001;                                             // enable interrupt
      NVIC->ISER[0] |= (1 << (TIM1_UP_IRQChannel & 0x1F));  // enable interrupt 

    //TIM1->CR1 |= TIMX_CR1_CEN;                                      // enable timer
     // end TIM1 used

//TIM2
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;                      // enable clock for TIM2  计数光栅上升沿个数
 
      TIM2->SC = 0;                                                          // set prescaler
      TIM2->ARR = 0xffff;                                                    // set auto-reload     ARR=0xFFFF

      TIM2->SMCR  = __TIM2_SMCR;                                     // set slave mode control register SMCR=0x4070

      TIM2->CR1 = 0x0082;                                                 // set command register 1 CR1=0x0082 
      TIM2->CR2 = 0;                                                          // set command register 2
    
      TIM2->CNT = 0; //清零计数器的值  
     // end TIM2 used
  } 

void TIM1_UP_IRQHandler(void) //10us定时基数
{
  if ((TIM1->SR & 0x0001) != 0) //溢出中断标志
 {
     TIM1->SR  &= ~(1<<0); //清除溢出中断
     if((temp_line-temp_line_last)==1) //每增加一个脉冲
         leaf.leaf_area += (80 * leaf.line_interval); 
    temp_line_last = temp_line;
  }
}

main()
{
    stm32_Init();        //已包含定时器初始化
    LcdIni();
 
  TIM2->CR1 |= 0x0001;      //使能定时器2

   TIM1->CR1 |= 0x0001;      //使能定时器1

  while(1)
    {
      temp_line = TIM2->CNT;         //将计数的光电脉冲个数赋值给temp_line

       sprintf(s1, (char*)"%d%d%d%d", (UINT16)temp_line/1000,(UINT16)temp_line/100%10,(UINT16)temp_line/10%10,(UINT16)temp_line%10);
       display_string_8x16(2,8,s1);

       sprintf(s1, (char*)"A=%d%d.%d%dcm2", (UINT16)leaf.leaf_area/1000,(UINT16)leaf.leaf_area/100%10,(UINT16)leaf.leaf_area/10%10,(UINT16)leaf.leaf_area%10);      
       display_string_8x16(5,2,s1);

   }
}

运行程序发现,光电开关的脉冲个数都能记录准确,但是当光栅转的稍微快点,定时器1的速度就跟不上了,不能及时判断脉冲个数的增量,高手给看看有什么办法再提高定时器1的定时中断时间,或者有其他办法能及时判断脉冲个数增量的办法。另外我看了半天资料也没弄清楚STM32f103定时时间是怎么计算的,一个版本一个说法,我通过跑硬件发现当 TIM1->ARR = 0xffff时,定时速度最快,但不太清楚定时时间到底是多少,高手给扫扫盲吧,谢谢啦
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-4-24 12:41:36 | 显示全部楼层
最好的资料就是官网给出的资料了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-10 03:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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