OpenEdv-开源电子网

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

STM32读取编码器脉冲计数

[复制链接]

6

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2014-5-14
在线时间
1 小时
发表于 2015-6-2 22:23:15 | 显示全部楼层 |阅读模式
      最近想用STM32f103RBT6来读取AB两向的编码器脉冲,搜了一些资料发现,有用外部中断弄的,还有用定时器本身的口来做的,看了原子的开发板没有相关的例子,不知如何下手,感觉STM32的定时器太复杂了,求高人指点
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2015-6-2 22:54:43 | 显示全部楼层
/********************************************************************************************
函 数 名: TIM2_IRQHandler:  定时器2中断函数
调    用: 无
参    数: 无
返 回 值: 无  
说    明: 完成光栅ABZ信号的采集,并进得4倍频的处理记录  
          定时器采集数据时间计算方法
          如需要440K的采样频率,定时器时钟设为24MZ
          T = 65536 - 24000000/440000;
          T = 65482;    
********************************************************************************************/
void TIM2_IRQHandler(void)
     {  
     u8 k,Cal;   
     if(TIM2->SR & 0x0001)   //检查是否是溢出中断以经发生过 
       { 
       TIM2->SR &= ~(1<<0);  //清除中断标志       
       Cal = (GPIOC->IDR >>1)&0x03;//取得当前光电编码器输入状态值           
       if(Cal != ShuChuZhuangTai)       
         {
         k = (ShuChuZhuangTai << 2 )+ Cal;//得到4倍频编码输入状态值
         switch(k)
               {
      case 0x07:{WeiZhiJiShuQi++;BIANHUASHUDU = 0;}break;
      case 0x0E:{WeiZhiJiShuQi++;BIANHUASHUDU = 0;}break;
      case 0x08:{WeiZhiJiShuQi++;BIANHUASHUDU = 0;}break;
               case 0x01:{WeiZhiJiShuQi++;BIANHUASHUDU = 0;}break;
      case 0x0D:{WeiZhiJiShuQi--;BIANHUASHUDU = 0;}break;
      case 0x04:{WeiZhiJiShuQi--;BIANHUASHUDU = 0;}break;
               case 0x02:{WeiZhiJiShuQi--;BIANHUASHUDU = 0;}break;
               case 0x0B:{WeiZhiJiShuQi--;BIANHUASHUDU = 0;}break;
               }
         ShuChuZhuangTai = Cal; //输入状态存副本   
         } 
       }     
     } 
回复 支持 反对

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2015-6-2 22:55:50 | 显示全部楼层
回复【2楼】likunxue:
---------------------------------
这时采用定时中断的方式,
回复 支持 反对

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2015-6-2 22:57:07 | 显示全部楼层
/*******************************************************************************************
函 数 名: 定时器3编码器模式初始化函数
调    用: Encoder_Init()
参    数: 无
反 回 值: 无(PA6,PA7接编码器 A相与B相输了端口,两路方波相差90度
********************************************************************************************/     
void Encoder_Init(void)
     {     
     RCC->APB1ENR |= 1<<1;          //TIM3时钟使能     
     RCC->APB1RSTR |= 1<<1;         //复位TIM3定时器,使之进入初始状态 
     RCC->APB1RSTR &= ~(1<<1);           
     RCC->APB2ENR |= 1<<2;          //使能PORTA时钟     
     GPIOA->CRL &= 0x00FFFFFF;      //PA6,PA7
     GPIOA->CRL |= 0x44000000;      //浮空输入      
     TIM3->DIER|=1<<0;              //允许更新中断
     TIM3->SC = 0x0;               //预分频器
     TIM3->ARR = ENCODER_TIM_PERIOD;//设定计数器自动重装值           
     TIM3->CR1 &=~(3<<8);           //选择时钟分频:不分频(在输入捕获中止参数无效)
     TIM3->CR1 &=~(3<<5);           //选择计数模式:中央对齐模式(向上或向下计数)
     TIM3->CCMR1 |= 1<<0;           //CC1S='01' IC1FP1映射到TI1
     TIM3->CCMR1 |= 1<<8;           //CC2S='01' IC2FP2映射到TI2
     TIM3->CCER &= ~(1<<1);         //CC1P='0' IC1FP1不反相,IC1FP1=TI1
     TIM3->CCER &= ~(1<<5);         //CC2P='0' IC2FP2不反相,IC2FP2=TI2
     TIM3->CCMR1 |= 3<<4;           //IC1F='1000' 输入捕获1滤波器(可能影响采集响应速度)
     TIM3->SMCR |= 3<<0;            //SMS='011' 所有的输入均在上升沿和下降沿有效(四倍频的输出)
     TIM3->CNT = COUNTER_RESET;     //计数器的初值
     CONSTER_DAT = COUNTER_RESET;   //清零中断计数累加器的值为初始值
     MY_NVIC_Init(0,0,TIM3_IRQn,4); //抢占0,子优先级0,组4 设定时器3更新中断为最高级别中断  
     TIM3->CR1 |= 0x01;             //CEN=1,使能定时器
     }
/*******************************************************************************************
函 数 名: 定时器3中断函数
调    用: 无
参    数: 无
反 回 值: 无(这里在编码器模式中CPU唯于需要处理的函数)
********************************************************************************************/  
void TIM3_IRQHandler(void)
     {
     u16 CNT_DAT;       
     if(TIM3->SR&0x0001)//溢出中断
       {     
       CNT_DAT = TIM3 ->CNT;  
       TIM3->SR&=~(1<<0);//清除中断标志位        
       if(CNT_DAT == ENCODER_TIM_PERIOD)CONSTER_DAT += (ENCODER_TIM_PERIOD + 1);
       else CONSTER_DAT -= ENCODER_TIM_PERIOD;       
       LED1 = ~ LED1;    
       }      
     }    
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 01:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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