寄存器版读正交编码器的值,测试成功

寄存器版读正交编码器的值,测试成功


除了个别蛛丝错误,代码整体可以拿去用


encoder.c

#include "encoder.h"
//encoder.INPUT_B---PA6(TIM3_CH1)
//encoder.INPUT_A---PA7(TIM3_CH2)
u16 OldCNT=0;
int CNTFlowFlag=0;
void TIM_EncoderInterfaceConfig( uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
//定时器3中断服务程序         
void TIM3_IRQHandler(void)
{                                                                  
        if(TIM3->SR&0X0001)//溢出中断
        {
                CNTFlowFlag=1;
        }                                   
        TIM3->SR&=~(1<<0);//清除中断标志位            
}
void Encoder_Configuration(void)
{
        RCC->APB1ENR|=1<<1;           //TIM3 时钟使能
        RCC->AHB1ENR|=1<<0;           //使能PORTA时钟        
        GPIO_Set(GPIOA,PIN6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//复用功能,下拉
        GPIO_Set(GPIOA,PIN7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);//复用功能,下拉
        GPIO_AF_Set(GPIOA,6,2);        //PA0,AF2
        GPIO_AF_Set(GPIOA,7,2);        //PA0,AF2
        TIM_EncoderInterfaceConfig(TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);
         
        TIM3->DIER|=1<<0;   //允许更新中断         
          MY_NVIC_Init(1,3,TIM3_IRQn,2);        //抢占1,子优先级3,组2        
    TIM3->CR1|=0x01;            //使能定时器3
         
}
void TIM_EncoderInterfaceConfig( uint16_t TIM_EncoderMode, uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
{
  uint16_t tmpsmcr = 0;
  uint16_t tmpccmr1 = 0;
  uint16_t tmpccer = 0;   
  /* Get the TIMx SMCR register value */
  tmpsmcr = TIM3->SMCR;
  /* Get the TIMx CCMR1 register value */
  tmpccmr1 = TIM3->CCMR1;
  /* Get the TIMx CCER register value */
  tmpccer = TIM3->CCER;
  /* Set the encoder Mode
    SMS:从模式选择 (Slave mode selection),011:编码器模式 3––计数器在 TI1FP1 和 TI2FP2 的边沿计数,计数的方向取决于另外一
  个信号的电平。
  */
  tmpsmcr &= (uint16_t)(~((uint16_t)TIM_SMCR_SMS));
  tmpsmcr |= TIM_EncoderMode;
  /* Select the Capture Compare 1 and the Capture Compare 2 as input
    CC2S[1:0]:01:CC2 通道配置为输入,IC2 映射到 TI2 上
    CC1S[1:0]:01:CC1 通道配置为输入,IC1 映射到 TI1 上。
        */
  tmpccmr1 &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCMR1_CC1S)) & (uint16_t)(~((uint16_t)TIM_CCMR1_CC2S)));
  tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
  /* Set the TI1 and the TI2 Polarities
  CC1 通道配置为输入:CC1NP/CC1P 位可针对触发或捕获操作选择 TI1FP1 和 TI2FP1 的极性。
  00:非反相/上升沿触发
  TIxFP1 未反相 (在门控模式或编码器模式下执行触发操作)。
  01:反相/下降沿触发
  TIxFP1 反相 (在门控模式或编码器模式下执行触发操作)。
  */
  tmpccer &= (uint16_t)(((uint16_t)~((uint16_t)TIM_CCER_CC1P)) & ((uint16_t)~((uint16_t)TIM_CCER_CC2P)));
  tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
  /* Write to TIMx SMCR */
  TIM3->SMCR = tmpsmcr;
  /* Write to TIMx CCMR1 */
  TIM3->CCMR1 = tmpccmr1;
  /* Write to TIMx CCER */
  TIM3->CCER = tmpccer;
}

int Encoder_Get_CNT(void)
{
        u16 NewCNT=0;
        int CNT;
        NewCNT=TIM3->CNT;
        CNT=NewCNT-OldCNT;
        if(CNTFlowFlag==1)
        {   
                if(NewCNT>30000)         CNT=(int)(NewCNT-(65536+OldCNT));
                if(NewCNT<30000)        CNT=(int)(NewCNT+65536-OldCNT);
                CNTFlowFlag=0;
        }               
        OldCNT=NewCNT;        
        return CNT;  
}


encoder.h
#ifndef __ENCODER_H
#define __ENCODER_H         
#include "sys.h"
#define TIM_EncoderMode_TI1                ((uint16_t)0x0001)
#define TIM_EncoderMode_TI2                ((uint16_t)0x0002)
#define TIM_EncoderMode_TI12               ((uint16_t)0x0003)
#define TIM_ICPolarity_Rising             ((uint16_t)0x0000)
#define TIM_ICPolarity_Falling            ((uint16_t)0x0002)
#define TIM_ICPolarity_BothEdge           ((uint16_t)0x000A)
void Encoder_Configuration(void);        
int Encoder_Get_CNT(void);
#endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值