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

2019-07-20 00:59发布

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



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
16条回答
lee409984507
1楼-- · 2019-07-21 11:02
 精彩回答 2  元偷偷看……
那么虚幻
2楼-- · 2019-07-21 12:29
565454492@qq.com 谢谢楼主
Strawberry94
3楼-- · 2019-07-21 16:16
 精彩回答 2  元偷偷看……
ioxfing
4楼-- · 2019-07-21 17:27
1813298696@qq.com能不能发一下 谢谢楼主

一周热门 更多>