0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32實(shí)現(xiàn)編碼器M法測(cè)速接線

麥辣雞腿堡 ? 來(lái)源:CSDN博客 ? 作者:駭客小狗 ? 2023-11-10 15:39 ? 次閱讀

接線

編碼器電機(jī)、電機(jī)驅(qū)動(dòng)(這里用的L298n)、STM32電源(可以是12V電池)的接線如下

圖片

3.3 代碼編寫(xiě)

encoder.h中的內(nèi)容

#ifndef _ENCODER_H_
#define _ENCODER_H_


#include "stm32f1xx.h"


//電機(jī)1的編碼器輸入引腳
#define MOTO1_ENCODER1_PORT GPIOA
#define MOTO1_ENCODER1_PIN  GPIO_PIN_0
#define MOTO1_ENCODER2_PORT GPIOA
#define MOTO1_ENCODER2_PIN  GPIO_PIN_1


//定時(shí)器號(hào)
#define ENCODER_TIM htim2
#define PWM_TIM     htim3
#define GAP_TIM     htim4


#define MOTOR_SPEED_RERATIO 45u    //電機(jī)減速比
#define PULSE_PRE_ROUND 11 //一圈多少個(gè)脈沖
#define RADIUS_OF_TYRE 34 //輪胎半徑,單位毫米
#define LINE_SPEED_C RADIUS_OF_TYRE * 2 * 3.14
#define RELOADVALUE __HAL_TIM_GetAutoreload(&ENCODER_TIM)    //獲取自動(dòng)裝載值,本例中為20000
#define COUNTERNUM __HAL_TIM_GetCounter(&ENCODER_TIM)        //獲取編碼器定時(shí)器中的計(jì)數(shù)值


typedef struct _Motor
{
    int32_t lastCount;   //上一次計(jì)數(shù)值
    int32_t totalCount;  //總計(jì)數(shù)值
    int16_t overflowNum; //溢出次數(shù)
    float speed;         //電機(jī)轉(zhuǎn)速
    uint8_t direct;      //旋轉(zhuǎn)方向
}Motor;


#endif

encoder.c中的內(nèi)容

#include "encoder.h"


Motor motor1;


void Motor_Init(void)
{
    HAL_TIM_Encoder_Start(&ENCODER_TIM, TIM_CHANNEL_ALL);      //開(kāi)啟編碼器定時(shí)器
    __HAL_TIM_ENABLE_IT(&ENCODER_TIM,TIM_IT_UPDATE);           //開(kāi)啟編碼器定時(shí)器更新中斷,防溢出處理
    HAL_TIM_Base_Start_IT(&GAP_TIM);                       //開(kāi)啟100ms定時(shí)器中斷
    HAL_TIM_PWM_Start(&PWM_TIM, TIM_CHANNEL_2);            //開(kāi)啟PWM
    HAL_TIM_PWM_Start(&PWM_TIM, TIM_CHANNEL_1);            //開(kāi)啟PWM
    __HAL_TIM_SET_COUNTER(&ENCODER_TIM, 10000);                //編碼器定時(shí)器初始值設(shè)定為10000
    motor1.lastCount = 0;                                   //結(jié)構(gòu)體內(nèi)容初始化
    motor1.totalCount = 0;
    motor1.overflowNum = 0;                                  
    motor1.speed = 0;
    motor1.direct = 0;
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時(shí)器回調(diào)函數(shù),用于計(jì)算速度
{
    if(htim- >Instance==ENCODER_TIM.Instance)//編碼器輸入定時(shí)器溢出中斷,用于防溢出                   
    {      
        if(COUNTERNUM < 10000) motor1.overflowNum++;       //如果是向上溢出
        else if(COUNTERNUM >= 10000) motor1.overflowNum--; //如果是向下溢出
        __HAL_TIM_SetCounter(&ENCODER_TIM, 10000);             //重新設(shè)定初始值
    }
    else if(htim- >Instance==GAP_TIM.Instance)//間隔定時(shí)器中斷,是時(shí)候計(jì)算速度了
    {
        motor1.direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);//如果向上計(jì)數(shù)(正轉(zhuǎn)),返回值為0,否則返回值為1
        motor1.totalCount = COUNTERNUM + motor1.overflowNum * RELOADVALUE;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
        motor1.speed = (float)(motor1.totalCount - motor1.totalCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 10;//算得每秒多少轉(zhuǎn)
        //motor1.speed = (float)(motor1.totalCount - motor1.totalCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 10 * LINE_SPEED_C//算得車輪線速度每秒多少毫米
        motor1.lastCount = motor1.totalCount; //記錄這一次的計(jì)數(shù)值
    }
}

使用時(shí)需要在main.c的循環(huán)之前調(diào)用Motor_Init函數(shù)進(jìn)行初始化。

如果發(fā)現(xiàn)無(wú)法進(jìn)入編碼器中斷導(dǎo)致totalCount經(jīng)常溢出歸零,可以嘗試換一種防溢出的方法,代碼如下

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時(shí)器回調(diào)函數(shù),用于計(jì)算速度
{  
    if(htim- >Instance==GAP_TIM.Instance)//間隔定時(shí)器中斷,是時(shí)候計(jì)算速度了
    {
        motor1.direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);//如果向上計(jì)數(shù)(正轉(zhuǎn)),返回值為0,否則返回值為1
        motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
        
        if(motor1.lastCount - motor1.totalCount > 19000) // 在計(jì)數(shù)值溢出時(shí)進(jìn)行防溢出處理
        {
            motor1.overflowNum++;
            motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
        }
        else if(motor1.totalCount - motor1.lastCount > 19000) // 在計(jì)數(shù)值溢出時(shí)進(jìn)行防溢出處理
        {
            motor1.overflowNum--;
            motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
        }
        
        motor1.speed = (float)(motor1.totalCount - motor1.lastCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 3000;//算得每秒多少轉(zhuǎn),除以4是因?yàn)?倍頻
        motor1.lastCount = motor1.totalCount; //記錄這一次的計(jì)數(shù)值
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編碼器
    +關(guān)注

    關(guān)注

    45

    文章

    3645

    瀏覽量

    134578
  • 驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    12

    文章

    1840

    瀏覽量

    85311
  • 電機(jī)
    +關(guān)注

    關(guān)注

    142

    文章

    9023

    瀏覽量

    145563
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10901

    瀏覽量

    356224
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    AB相編碼器-變M/T測(cè)速,10ms定時(shí),測(cè)6000轉(zhuǎn)伺服電機(jī)!

    本帖最后由 SXST_T 于 2017-9-13 12:11 編輯 適用所有線數(shù)編碼器,此方法主要解決M測(cè)低速分辨率不足,T測(cè)高速分辨率高,
    發(fā)表于 09-13 12:07

    編碼器測(cè)速的大致原理是什么?

    編碼器是什么?編碼器主要分為哪幾種?編碼器測(cè)速的大致原理是什么?
    發(fā)表于 06-30 07:48

    編碼器測(cè)速原理及STM32編碼器模式

    本問(wèn)講解了編碼器測(cè)速原理及STM32編碼器模式,文末有STM32編碼器模式例程。
    發(fā)表于 08-11 06:06

    MT測(cè)速單片機(jī)程序設(shè)計(jì)

    MT測(cè)速單片機(jī)程序設(shè)計(jì)M、T
    發(fā)表于 09-02 06:01

    增量式編碼器倍頻技術(shù)的M究竟是怎樣測(cè)速

    增量式編碼器輸出的脈沖波形信號(hào)形式常見(jiàn)的有哪幾種?增量式編碼器倍頻技術(shù)的M究竟是怎樣測(cè)速的?
    發(fā)表于 11-09 07:08

    STM32正交編碼器怎么進(jìn)行測(cè)速

    正交編碼解碼的原理是什么?STM32正交編碼器怎么進(jìn)行測(cè)速
    發(fā)表于 11-16 08:04

    增量式編碼器如何使用外部中斷實(shí)現(xiàn)測(cè)速?

    增量式編碼器如何使用外部中斷實(shí)現(xiàn)測(cè)速
    發(fā)表于 11-16 08:25

    如何實(shí)現(xiàn)STM32F103C8T6編碼器測(cè)速?

    如何實(shí)現(xiàn)STM32F103C8T6編碼器測(cè)速?
    發(fā)表于 12-13 07:21

    絕對(duì)式編碼器測(cè)速方法

    本文檔詳細(xì)介紹了絕對(duì)式編碼器測(cè)速度的方法
    發(fā)表于 08-29 14:22 ?41次下載

    編碼器測(cè)速方法的研究

    編碼器測(cè)速方法的研究
    發(fā)表于 03-17 09:06 ?24次下載

    測(cè)速編碼器工作原理

     測(cè)速編碼器一般與軸相聯(lián),測(cè)速編碼器的脈沖量是固定的,在軸旋轉(zhuǎn)的時(shí)候,測(cè)速編碼器就會(huì)輸出脈沖,P
    的頭像 發(fā)表于 11-07 09:36 ?2.1w次閱讀

    平衡小車—編碼器使用教程與測(cè)速原理

    文章目錄1.編碼器概述2.編碼器原理3.編碼器接線說(shuō)明4.編碼器軟件四倍頻技術(shù)5.單片機(jī)如何采集編碼器
    發(fā)表于 11-22 19:51 ?57次下載
    平衡小車—<b class='flag-5'>編碼器</b>使用教程與<b class='flag-5'>測(cè)速</b>原理

    STM32——編碼器測(cè)速原理及STM32編碼器模式

    本問(wèn)講解了編碼器測(cè)速原理及STM32編碼器模式,文末有STM32編碼器模式例程。
    發(fā)表于 11-26 11:36 ?271次下載
    <b class='flag-5'>STM32</b>——<b class='flag-5'>編碼器</b><b class='flag-5'>測(cè)速</b>原理及<b class='flag-5'>STM32</b><b class='flag-5'>編碼器</b>模式

    編碼器常用測(cè)速方法

    2.1 倍頻技術(shù) 編碼器會(huì)輸出兩路方波信號(hào),如果只在通道A的上升沿計(jì)數(shù),那就是1倍頻;通道A的上升、下降沿計(jì)數(shù),那就是2倍頻;如果在通道A、B的上升、下降沿計(jì)數(shù),那就是4倍頻。 使用倍頻可以最大程度
    的頭像 發(fā)表于 11-10 15:28 ?6056次閱讀
    <b class='flag-5'>編碼器</b>常用<b class='flag-5'>測(cè)速</b>方法

    編碼器M測(cè)速CubeMax配置

    為了進(jìn)行測(cè)速,我們一共需要3個(gè)定時(shí),作用分別是:①輸出PWM;②編碼器模式進(jìn)行脈沖計(jì)數(shù);③計(jì)時(shí),確定每次測(cè)速的時(shí)間間隔。 其中,用于定時(shí)的定時(shí)
    的頭像 發(fā)表于 11-10 15:31 ?1210次閱讀
    <b class='flag-5'>編碼器</b><b class='flag-5'>M</b><b class='flag-5'>法</b><b class='flag-5'>測(cè)速</b>CubeMax配置