寄存器版,STM32F429正交编码器

2019-07-20 03:45发布

最近在搞STM32F429控制电机,用的增量编码器,使用TIMx(1-8)对编码器的值进行采集,终于调试成功了,将配置代码和大家分享一下!
用的TIM8的CH1和CH2通道(CH3和CH4通道不可以),其他几个定时器(TIM3和TIM5等的CH1和CH2都测试过,可以的)
#define Encoder_Val TIM8->CNT

void TIM8_Encoder_Init(void)//TIM8_Encoder_Init(u16 arr,u16 psc)
{
RCC->APB2ENR|=1<<1; //TIM8时钟使能
RCC->AHB1ENR|=1<<2;//使能PORTC时钟  
GPIO_Set(GPIOC,PIN6,GPIO_MODE_AF,GPIO_OTYPE_OD,GPIO_SPEED_100M,GPIO_PUPD_PU);//复用功能,上拉输出
GPIO_AF_Set(GPIOC,6,3); //PC6,AF3
GPIO_Set(GPIOC,PIN7,GPIO_MODE_AF,GPIO_OTYPE_OD,GPIO_SPEED_100M,GPIO_PUPD_PU);//复用功能,上拉输出
GPIO_AF_Set(GPIOC,7,3);//PC7,AF3


TIM8->CCMR1&=0xFCFC;  // CC1S=1;CC2S=1;
TIM8->CCMR1|=1<<0;
TIM8->CCMR1|=1<<8;


TIM8->CCER&=0xFF55; //CC1P=0;CC2P=0;
TIM8->CCER|=0<<0;
TIM8->CCER|=0<<4;
TIM8->SMCR&=0xFFF8; //SMS=011; 这里需不需要使能呢?
TIM8->SMCR|=1<<0;

TIM8->CR1|=0<<7;     //ARPE使能
MY_NVIC_Init(1,3,TIM8_UP_TIM13_IRQn,2);//0 2 2
TIM8->CR1|=1<<0;     //使能定时器8
TIM8->CNT=1000;
}

然后读Encoder_Val的值就可以啦
也可以定义#define Direction 0x0001&(TIM8->CR1>>4)去判断电机的转向,0反转    1正转
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
燕少博
1楼-- · 2019-07-20 04:35
 精彩回答 2  元偷偷看……
walker168
2楼-- · 2019-07-20 07:34
编码器接口,CH3和CH4 真的不可以。F7也是这样。曾经中过招,代码检查无数遍,死调一天,就是没任何反应,最后换成CH1 CH2, 效果立竿见影。
jdwang1000
3楼-- · 2019-07-20 12:12
我也曾經調過F103C8T6的Time3,Time4编码器接口並試著使用CH3和CH4,結果真的是徒勞無功,

而且一個定時器只能使用一個編碼器若要做二輪平衡車項目就得使用二個定時器

順便借樓貼一下我目前平衡車項目使用的編碼器代碼(該注釋的都非常清楚)

// http://www.amobbs.com/thread-5526150-1-1.html?_dsign=df1f7cc2
// http://www.openedv.com/thread-8274-1-1.html
// 設定 TIME3 复用功能部分重映像编码器模式  TIM3_REMAP[11:10] = 10:部分重映像 CH1->PB4, CH2->PB5
// 設定 TIME4 复用功能    重映像编码器模式  TIM4_REMAP[12] = 0    :  無重映像 CH1->PB6, CH2->PB7
// 啟用TIM3 ENCODER 就無法再使用 Tim3_Pwm
// 基本上 CH3,CH4 是不需配置-->因為再怎麼試也無法讀出 Encoder 訊號
// CH_3和CH_4当然不行了,编码器模式只在T1和T2,或者其中之一计数。80樓
void Time3_Time4_Encoder_Init(u16 arr, u16 psc)
{   
    // 6.3.7 APB2外设时钟使能寄存器(RCC_APB2ENR)
    RCC->APB2ENR|=1<<0;                 // AFIO时钟使能     不想做重映射時可註釋掉      
        RCC->APB2ENR|=1<<3;                 // 使能PORTB时钟   

    // 6.3.8 APB1外设时钟使能寄存器(RCC_APB1ENR)       
    RCC->APB1ENR|=1<<1;                 // TIM3时钟使能
    RCC->APB1ENR|=1<<2;                 // TIM4时钟使能

    // 8.4.2 复用重映射和调试I/O配置寄存器(AFIO_MAPR)
    AFIO->MAPR &= 0xFFFFF3FF;           // [11:10] 位清0
    AFIO->MAPR |= 0x00000800;           // TIM3_REMAP[11:10]:定时器3的重映像 TIM3_REMAP[11:10] = 10:部分重映像 CH1->PB4, CH2->PB5
                                        // 00:没有重映像(CH1/PA6,CH2/PA7,CH3/PB0,CH4/PB1);
                                        // 10:部分映像(CH1/PB4,CH2/PB5,CH3/PB0,CH4/PB1);
                                        // 11:完全映像(CH1/PC6,CH2/PC7,CH3/PC8,CH4/PC9)。
    //  AFIO->MAPR &= ~(1<<12);         // TIM4_REMAP[12]:   定时器4的重映像 TIM3_REMAP[12] = 0: 無重映像 CH1->PB6, CH2->PB7


    // 8.2.1 端口配置低寄存器(GPIOx_CRL) (x=A..E)   
        GPIOB->CRL&=0X0000FFFF;             // PB4,PB5 電機A編碼器(TIM3 REMAP=10, CH1->PB4,CH2->PB5), PB6,PB7 電機B編碼器(TIM4 REMAP=0 CH1->PB6,CH2->PB7)
        GPIOB->CRL|=0X44440000;             // PB4,PB5-->電機A編碼器, PB6,PB7-->電機B編碼器, 浮空输入

    // 14.4.1 控制寄存器1(TIMx_CR1)
        TIM3->CR1 &=~(3<<8);                // 选择时钟分频:不分频
        TIM3->CR1 &=~(3<<5);                // CMS[6:5]:选择中央对齐模式 (Center-aligned mode selection)
        TIM4->CR1 &=~(3<<8);                // 选择时钟分频:不分频
        TIM4->CR1 &=~(3<<5);                       // CMS[6:5]:选择中央对齐模式 (Center-aligned mode selection)
                                        // 00:边沿对齐模式。计数器依据方向位(DIR)向上或向下计数。
                                        // 01:中央对齐模式1。计数器交替地向上和向下计数。
                                        // 10:中央对齐模式2。计数器交替地向上和向下计数。
                                        // 11:中央对齐模式3。计数器交替地向上和向下计数。       

        // 14.4.3 从模式控制寄存器(TIMx_SMCR) 若使用光電碼盤因解析度高可選擇上升沿或下降沿擇一即可甚或使用一個捕获/比较通道即可不需使用二個通道
        TIM3->SMCR |= 3<<0;                        // 011:编码器模式3 – 根据另一个信号的输入电平,计数器在TI1FP1和TI2FP2的边沿向上/下计数。   
        TIM4->SMCR |= 3<<0;

        // 14.4.4 DMA/中断使能寄存器(TIMx_DIER)    这两个东东要同时设置才可以使用中断(編碼器無須中斷程序)   
//        TIM3->DIER|=1<<0;                   // UIE:允许更新中断 (Update interrupt enable)   
//        TIM3->DIER|=1<<6;                   // 允许触发中断
//        MY_NVIC_Init(1,3,TIM3_IRQn,2);

    // 14.4.7 捕获/比较模式寄存器1(TIMx_CCMR1)
        TIM3->CCMR1 |= 1<<0;                // CC1S[1:0]:捕获/比较1选择 (Capture/Compare 1 selection) 01:CC1通道被配置为输入,IC1映射在TI1上
        TIM3->CCMR1 |= 1<<8;                // CC2S[1:0]:捕获/比较2选择 (Capture/Compare 2 selection) 01:CC2通道被配置为输入,IC2映射在TI2上
        TIM3->CCMR1 |= 3<<4;                // IC1F='1000' 输入捕获1滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8
        TIM3->CCMR1 |= 3<<12;               // IC2F='1000' 输入捕获2滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8  
       
        TIM4->CCMR1 |= 1<<0;                // CC1S[1:0]:捕获/比较1选择 (Capture/Compare 1 selection) 01:CC1通道被配置为输入,IC1映射在TI1上
        TIM4->CCMR1 |= 1<<8;                // CC2S[1:0]:捕获/比较2选择 (Capture/Compare 2 selection) 01:CC2通道被配置为输入,IC2映射在TI2上
        TIM4->CCMR1 |= 3<<4;                // IC1F='1000' 输入捕获1滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8
        TIM4->CCMR1 |= 3<<12;               // IC2F='1000' 输入捕获2滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8  


    // 14.4.8 捕获/比较模式寄存器2(TIMx_CCMR2)
//        TIM3->CCMR2 |= 1<<0;                // CC3S[1:0]:捕获/比较3选择 (Capture/Compare 3 selection) 01:CC3通道被配置为输入,IC3映射在TI3上
//        TIM3->CCMR2 |= 1<<8;                // CC4S[1:0]:捕获/比较4选择 (Capture/Compare 4 selection) 01:CC4通道被配置为输入,IC4映射在TI4上
//        TIM3->CCMR2 |= 3<<4;                // IC3F='1000' 输入捕获3滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8
//        TIM3->CCMR2 |= 3<<12;               // IC4F='1000' 输入捕获4滤波器, 0011:采样频率fSAMPLING=fCK_INT,N=8  

    // 14.4.9 捕获/比较使能寄存器(TIMx_CCER)
        TIM3->CCER &= ~(1<<1);                    // CC1P='0'         IC1不反相
        TIM3->CCER &= ~(1<<5);                    // CC2P='0'         IC2不反相   
        TIM4->CCER &= ~(1<<1);                    // CC1P='0'         IC1不反相
        TIM4->CCER &= ~(1<<5);                    // CC2P='0'         IC2不反相      
//        TIM3->CCER &= ~(1<<9);                    // CC3P='0'         IC1不反相
//        TIM3->CCER &= ~(1<<13);            // CC4P='0'         IC2不反相         

    // 14.4.10 计数器(TIMx_CNT)
    TIM3->CNT = COUNTER_RESET;          // CNT[15:0]:计数器的值 (Counter value)   
    TIM4->CNT = COUNTER_RESET;

    // 14.4.11 预分频器(TIMx_PSC)
    TIM3->PSC = psc;                    // PSC[15:0]:预分频器的值 (Prescaler value)
    TIM4->PSC = psc;

    // 14.4.12 自动重装载寄存器(TIMx_ARR)
    TIM3->ARR = arr;                    // ARR[15:0]: 自动重装载的值 (Auto reload value) 65000
    TIM4->ARR = arr;

    // 14.4.1 控制寄存器1(TIMx_CR1)
    TIM3->CR1 |= 0x01;                  // CEN=1,使能定时器
    TIM4->CR1 |= 0x01;
}

燕少博
4楼-- · 2019-07-20 17:06
 精彩回答 2  元偷偷看……
燕少博
5楼-- · 2019-07-20 19:40
jdwang1000 发表于 2017-3-11 17:19
我也曾經調過F103C8T6的Time3,Time4编码器接口並試著使用CH3和CH4,結果真的是徒勞無功,

而且一個定時器 ...

感谢分享,希望对以后用到的人能有所帮助!不过真心发现寄存器版的相关帖子太少!
mangoball
6楼-- · 2019-07-20 22:59
 精彩回答 2  元偷偷看……

一周热门 更多>