stm32通过编码器控制小车行驶指定的距离

这篇具有很好参考价值的文章主要介绍了stm32通过编码器控制小车行驶指定的距离。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:概要

主控芯片为stm32f407,通过编码器计算行驶距离,pid闭环控制,程序源码中包含上一期的pid速度控制。使用本程序所需知道的条件:编码器一周几个脉冲,电机的减速比和车轮的直径。
(注:免费源码链接,请点赞关注私信)

二:效果演示

视频介绍;行驶距离120厘米,换算编码器脉冲共3103个。

stm32行驶指定距离

三:程序代码

1:固定距离行驶pid.c

#include "./BSP/PID/pid.h"
#include "./SYSTEM/sys/sys.h"
#include "./BSP/LCD/lcd.h"
#include "./SYSTEM/usart/usart.h"

extern TIM_HandleTypeDef g_timx_pwm_chy_handle;     /* 定时器x句柄 */
extern TIM_HandleTypeDef g_timx_cnt_chy_handle;        /* 定时器x句柄 */
extern TIM_HandleTypeDef g_tim3_cnt_chy_handle;        /* 定时器x句柄 */


TIM_HandleTypeDef g_timx_handler;       /* 定时器参数句柄 */
//uint8_t Point=120;                    /* 设定目标转速 */
//#define SetPointL Point*528/3000      /* 转速转化为 20ms 编码器脉冲数量 */
//uint16_t Moto;

  /*3.1416 * 车轮的直径 /车轮一圈产生的编码脉冲  */  
#define Extent   ( 3.1416*6.5/528 )                    /* 一个编码器脉冲行走的距离  0.038675cm  一圈20.4204cm*/
//uint16_t Destina= 120/Extent;                        /* 行走距离脉冲数 */


PID zspeed,zpos;
Error value,vpos;

void PID_init(void)    /* 初始化 P I D */
{
    /* 速度PID  */
    zspeed.P=20;
    zspeed.I=2.5;
    zspeed.D=0;
    
    value.Current_Error=0;//当前误差
    value.Last_Error=0;//上一次误差
    value.Previous_Error=0;//上上次误差
    
    /* 位置PID */
    zpos.P=20;
    zpos.I=2.5;
    zpos.D=0;
    
    vpos.Current_Error=0;//当前误差
    vpos.Last_Error=0;//上一次误差
    vpos.Previous_Error=0;//上上次误差
    
}

/*! 
 *  @brief      增量式PID
 *  @since      v1.0
 *  *sptr :误差参数
 *  *pid:  PID参数
 *  NowPlace:实际值
 *  Point:   期望值
 */

// 增量式PID电机控制


uint32_t PID_Increase(Error *sptr, PID *pid, uint32_t NowPlace, uint32_t Point)
{
 
	uint32_t iError,	//当前误差
		Increase;	//最后得出的实际增量
 
	iError = Point - NowPlace;	// 计算当前误差
 
	Increase =  pid->P * (iError - sptr->Last_Error)   //比例P
			  + pid->I * iError      //积分I
			  + pid->D * (iError - 2 * sptr->Last_Error + sptr->Previous_Error);  //微分D
	
	sptr->Previous_Error = sptr->Last_Error;	// 更新前次误差
	sptr->Last_Error = iError;		  	// 更新上次误差
	
	return Increase;	// 返回增量
}

/*! 
 *  @brief      位置式PID
 *  @since      v1.0
 *  *sptr :误差参数
 *  *pid:  PID参数
 *  NowPlace:当前位置
 *  Point:   预期位置  
 */
 
// 位置式PID控制
float PID_Realize(Error *sptr,PID *pid, uint32_t NowPlace, float Point)
{
 
	uint32_t iError,	// 当前误差
		 Realize;   //实际输出	
 
	iError = Point - NowPlace;	// 计算当前误差
	sptr->Current_Error += pid->I * iError;	// 误差积分
      
    sptr->Current_Error = sptr->Current_Error > pid->limit?pid->limit:sptr->Current_Error;//积分限幅
      sptr->Current_Error = sptr->Current_Error <-pid->limit?-pid->limit:sptr->Current_Error;
	
    Realize = pid->P * iError       //比例P
            + sptr->Current_Error   //积分I
			+ pid->D * (iError - sptr->Last_Error);  //微分D
	sptr->Last_Error = iError;		  	// 更新上次误差
	return Realize;	// 返回实际值
}


//行使固定位置PID
void Destina_PID(float JULI)
{
    uint16_t Destina= JULI/Extent; 
    uint32_t count = 0,Destination=0,Increase=0;
    __HAL_TIM_DISABLE(&g_tim3_cnt_chy_handle);          /* 关闭编码器定时器 */
    __HAL_TIM_SET_COUNTER(&g_tim3_cnt_chy_handle, 0);   /* 计数器清零 */
    __HAL_TIM_ENABLE(&g_tim3_cnt_chy_handle);           /* 开启编码器定时器 */
    do
    {   
        //__HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_1 ,500);  /* 控制小车电机的运行pwm占空比 */

        count=__HAL_TIM_GET_COUNTER(&g_tim3_cnt_chy_handle);       /* 获取当前编码器脉冲计数值 */

        lcd_show_num(50,100,count,6,16,RED);

        Destination=(count)*Extent;                                /* 计算当前行走的距离 */

        lcd_show_num(50,80,Destination,3,16,RED);

        Increase=PID_Increase( &vpos , &zpos , count , Destina );  /* 计数得到增量式PID的增量数值 */
        lcd_show_num(50,60,Increase,3,16,RED);

        if(Increase<2)
        {
            __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_1 ,0);
        } 

       printf("%d\r\n",Destination);

    }while(count<=Destina-2);     /* 防止惯性的影响 */
    
    __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_1 ,0);/* 停止电机运行 */
    //HAL_NVIC_DisableIRQ(BTIM_TIMX_INT_IRQn);   /* 关闭中断 */
}

2:pid.h

#ifndef __PID_H
#define	__PID_H
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/sys/sys.h"

void btim_timx_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */


typedef struct 
{ 
  float P,I,D,limit;
}PID;

typedef struct
{
  float Current_Error;//当前误差
  float Last_Error;//上一次误差
  float Previous_Error;//上上次误差
}Error;


void gtim_timx_int_init(uint16_t arr, uint16_t psc);

uint32_t PID_Increase(Error *sptr, PID *pid, uint32_t NowPlace, uint32_t Point);
float PID_Realize(Error *sptr,PID *pid, uint32_t NowPlace, float Point);
void PID_init(void);
//void Speed_PID(uint8_t Point);
void Destina_PID(float JULI);
#endif

3:定时器编码器模式

#include "./BSP/TIMER/gtim.h"
#include "./BSP/LED/led.h"
#include "./SYSTEM/usart/usart.h"

TIM_HandleTypeDef g_timx_cnt_chy_handle;        /* 定时器x句柄 */

/*********************************以下是通用定时器PWM输出实验程序*************************************/

TIM_HandleTypeDef g_timx_pwm_chy_handle;     /* 定时器x句柄 */

/**
 * @brief       通用定时器TIMX 通道Y PWM输出 初始化函数(使用PWM模式1)
 * @note
 *              通用定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
 *              通用定时器的时钟为APB1时钟的2倍, 而APB1为42M, 所以定时器时钟 = 84Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值。
 * @param       psc: 预分频系数
 * @retval      无
 */
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc)
{
        GPIO_InitTypeDef gpio_init_struct;
        GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE();                            /* 开启通道y的CPIO时钟 */
        GTIM_TIMX_PWM_CHY_CLK_ENABLE();                                 /* 使能定时器时钟 */

        gpio_init_struct.Pin = GTIM_TIMX_PWM_CHY_GPIO_PIN;              /* 通道y的CPIO口 */
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;                        /* 复用推完输出 */
        gpio_init_struct.Pull = GPIO_PULLUP;                            /* 上拉 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;                  /* 高速 */
        gpio_init_struct.Alternate = GTIM_TIMX_PWM_CHY_GPIO_AF;         /* IO口REMAP设置, 是否必要查看头文件配置的说明! */
        HAL_GPIO_Init(GTIM_TIMX_PWM_CHY_GPIO_PORT, &gpio_init_struct);
    TIM_OC_InitTypeDef timx_oc_pwm_chy = {0};                       /* 定时器输出句柄 */
    
    g_timx_pwm_chy_handle.Instance = GTIM_TIMX_PWM;                 /* 定时器x */
    g_timx_pwm_chy_handle.Init.Prescaler = psc;                     /* 预分频系数 */
    g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 递增计数模式 */
    g_timx_pwm_chy_handle.Init.Period = arr;                        /* 自动重装载值 */
    HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);                       /* 初始化PWM */

    timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;                       /* 模式选择PWM1 */
    timx_oc_pwm_chy.Pulse = 500 ;                                /* 设置比较值,此值用来确定占空比 */

    timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH;                                        /* 输出比较极性为高 */
    HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, GTIM_TIMX_PWM_CHY); /* 配置TIMx通道y */
    HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY);                           /* 开启对应PWM通道 */
}


/*********************************以下是通用定时器脉冲计数  速度  实验程序*************************************/

uint32_t g_timxchy_cnt_ofcnt = 0 ;              /* 计数溢出次数 */

void gtim_timx_cnt_chy_init(uint16_t psc)
{
    GPIO_InitTypeDef gpio_init_struct;
    TIM_SlaveConfigTypeDef tim_slave_config = {0};
    GTIM_TIMX_CNT_CHY_CLK_ENABLE();                                        /* 使能TIMx时钟 */
    GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE();                                   /* 开启GPIOA时钟 */
    
    g_timx_cnt_chy_handle.Instance = GTIM_TIMX_CNT;                        /* 定时器x */
    g_timx_cnt_chy_handle.Init.Prescaler = psc;                            /* 预分频系数 */
    g_timx_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;           /* 递增计数模式 */
    g_timx_cnt_chy_handle.Init.Period = 65535;                             /* 自动重装载值 */
    HAL_TIM_IC_Init(&g_timx_cnt_chy_handle);

    gpio_init_struct.Pin = GTIM_TIMX_CNT_CHY_GPIO_PIN;                     /* 输入捕获的GPIO口 */
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                               /* 复用推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                                 /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;                    /* 高速 */
    gpio_init_struct.Alternate = GTIM_TIMX_CNT_CHY_GPIO_AF;                /* 复用为捕获TIMx的通道 */
    HAL_GPIO_Init(GTIM_TIMX_CNT_CHY_GPIO_PORT, &gpio_init_struct);

    /* 从模式:外部触发模式1 */
    tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;                  /* 从模式:外部触发模式1 */
    tim_slave_config.InputTrigger = TIM_TS_TI1FP1;                         /* 输入触发:选择 TI1FP1(TIMX_CH1) 作为输入源 */
    tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_FALLING;         /* 触发极性:上升沿 */
    tim_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;         /* 触发预分频:无 */
    tim_slave_config.TriggerFilter = 0x0;                                  /* 滤波:本例中不需要任何滤波 */
    HAL_TIM_SlaveConfigSynchronization(&g_timx_cnt_chy_handle, &tim_slave_config);

    HAL_NVIC_SetPriority(GTIM_TIMX_CNT_IRQn, 1, 3);                        /* 设置中断优先级,抢占优先级1,子优先级3 */
    HAL_NVIC_EnableIRQ(GTIM_TIMX_CNT_IRQn);                                /* 开启ITMx中断 */

    __HAL_TIM_ENABLE_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE);            /* 使能更新中断 */
    HAL_TIM_IC_Start(&g_timx_cnt_chy_handle, GTIM_TIMX_CNT_CHY1);           /* 开始捕获TIMx的通道y */
}

/**
 * @brief       通用定时器TIMX 通道Y 获取当前计数值 
 * @param       无
 * @retval      当前计数值
 */
uint32_t gtim_timx_cnt_chy_get_count(void)
{
    uint32_t count = 0;
    //count = g_timxchy_cnt_ofcnt * 65535;                    /* 计算溢出次数对应的计数值 */
    count += __HAL_TIM_GET_COUNTER(&g_timx_cnt_chy_handle); /* 加上当前CNT的值 */
//    printf("gtim_timx count %d \r\n", count);
    return count;
}

/**
 * @brief       通用定时器TIMX 通道Y 重启计数器
 * @param       无
 * @retval      当前计数值
 */
void gtim_timx_cnt_chy_restart(void)
{
    __HAL_TIM_DISABLE(&g_timx_cnt_chy_handle);          /* 关闭定时器TIMX */
    g_timxchy_cnt_ofcnt = 0;                            /* 累加器清零 */
    __HAL_TIM_SET_COUNTER(&g_timx_cnt_chy_handle, 0);   /* 计数器清零 */
    __HAL_TIM_ENABLE(&g_timx_cnt_chy_handle);           /* 使能定时器TIMX */
}

/**
 * @brief       通用定时器TIMX 脉冲计数 更新中断服务函数
 * @param       无
 * @retval      无
 */
void GTIM_TIMX_CNT_IRQHandler(void)
{
    /* 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式 */
    if(__HAL_TIM_GET_FLAG(&g_timx_cnt_chy_handle, TIM_FLAG_UPDATE) != RESET)
    {
        g_timxchy_cnt_ofcnt++;          /* 累计溢出次数 */
    }

    __HAL_TIM_CLEAR_IT(&g_timx_cnt_chy_handle, TIM_IT_UPDATE);
}


/*********************************以下是通用定时器脉冲计数    位置   实验程序*************************************/

TIM_HandleTypeDef g_tim3_cnt_chy_handle;        /* 定时器x句柄 */

uint32_t g_tim3chy_cnt_ofcnt = 0 ;              /* 计数溢出次数 */

void gtim_tim3_cnt_chy_init(uint16_t psc)
{
    GPIO_InitTypeDef gpio_init_struct;
    TIM_SlaveConfigTypeDef tim_slave_config = {0};
    GTIM_TIM3_CNT_CHY_CLK_ENABLE();                                        /* 使能TIMx时钟 */
    GTIM_TIM3_CNT_CHY_GPIO_CLK_ENABLE();                                   /* 开启GPIOA时钟 */
    
    g_tim3_cnt_chy_handle.Instance = GTIM_TIM3_CNT;                        /* 定时器x */
    g_tim3_cnt_chy_handle.Init.Prescaler = psc;                            /* 预分频系数 */
    g_tim3_cnt_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;           /* 递增计数模式 */
    g_tim3_cnt_chy_handle.Init.Period = 65535;                             /* 自动重装载值 */
    HAL_TIM_IC_Init(&g_tim3_cnt_chy_handle);

    gpio_init_struct.Pin = GTIM_TIM3_CNT_CHY_GPIO_PIN;                     /* 输入捕获的GPIO口 */
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;                               /* 复用推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                                 /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;                    /* 高速 */
    gpio_init_struct.Alternate = GTIM_TIM3_CNT_CHY_GPIO_AF;                /* 复用为捕获TIMx的通道 */
    HAL_GPIO_Init(GTIM_TIM3_CNT_CHY_GPIO_PORT, &gpio_init_struct);

    /* 从模式:外部触发模式1 */
    tim_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;                  /* 从模式:外部触发模式1 */
    tim_slave_config.InputTrigger = TIM_TS_TI2FP2;                         /* 输入触发:选择 TI1FP2(TIMX_CH2) 作为输入源 */
    tim_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_FALLING;         /* 触发极性:上升沿 */
    tim_slave_config.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;         /* 触发预分频:无 */
    tim_slave_config.TriggerFilter = 0x0;                                  /* 滤波:本例中不需要任何滤波 */
    HAL_TIM_SlaveConfigSynchronization(&g_tim3_cnt_chy_handle, &tim_slave_config);

    HAL_NVIC_SetPriority(GTIM_TIM3_CNT_IRQn, 2, 2);                        /* 设置中断优先级,抢占优先级1,子优先级3 */
    HAL_NVIC_EnableIRQ(GTIM_TIM3_CNT_IRQn);                                /* 开启ITMx中断 */

    __HAL_TIM_ENABLE_IT(&g_tim3_cnt_chy_handle, TIM_IT_UPDATE);            /* 使能更新中断 */
    HAL_TIM_IC_Start(&g_tim3_cnt_chy_handle, GTIM_TIM3_CNT_CHY2);           /* 开始捕获TIMx的通道y */
}


/**
 * @brief       通用定时器TIMX 脉冲计数 更新中断服务函数
 * @param       无
 * @retval      无
 */
void GTIM_TIM3_CNT_IRQHandler(void)
{
    /* 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式 */
    if(__HAL_TIM_GET_FLAG(&g_tim3_cnt_chy_handle, TIM_FLAG_UPDATE) != RESET)
    {
        g_tim3chy_cnt_ofcnt++;          /* 累计溢出次数 */
    }

    __HAL_TIM_CLEAR_IT(&g_tim3_cnt_chy_handle, TIM_IT_UPDATE);
}




/*(.h)*/
#ifndef __GTIM_H
#define __GTIM_H

#include "./SYSTEM/sys/sys.h"


/******************************************TIMX PWM输出定义 *****************************************************/

#define GTIM_TIMX_PWM_CHY_GPIO_PORT         GPIOF
#define GTIM_TIMX_PWM_CHY_GPIO_PIN          GPIO_PIN_9
#define GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0)  /* PF口时钟使能 */
#define GTIM_TIMX_PWM_CHY_GPIO_AF           GPIO_AF9_TIM14                               /* 端口复用到TIM14 */

#define GTIM_TIMX_PWM                       TIM14                                        /* TIM14 */
#define GTIM_TIMX_PWM_CHY                   TIM_CHANNEL_1                                /* 通道Y,  1<= Y <=4 */
#define GTIM_TIMX_PWM_CHY_CCRX              TIM14->CCR1                                  /* 通道Y的输出比较寄存器 */
#define GTIM_TIMX_PWM_CHY_CLK_ENABLE()      do{ __HAL_RCC_TIM14_CLK_ENABLE(); }while(0)  /* TIM14 时钟使能 */


/******************************************TIM2 速度 输入计数定义************************************************/

#define GTIM_TIMX_CNT_CHY_GPIO_PORT            GPIOA
#define GTIM_TIMX_CNT_CHY_GPIO_PIN             GPIO_PIN_0
#define GTIM_TIMX_CNT_CHY_GPIO_AF              GPIO_AF1_TIM2                                /* AF功能选择 */
#define GTIM_TIMX_CNT_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)  /* PA口时钟使能 */

#define GTIM_TIMX_CNT                          TIM2
#define GTIM_TIMX_CNT_IRQn                     TIM2_IRQn
#define GTIM_TIMX_CNT_IRQHandler               TIM2_IRQHandler
#define GTIM_TIMX_CNT_CHY1                      TIM_CHANNEL_1                                /* 通道Y,  1<= Y <=2 */

#define GTIM_TIMX_CNT_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM2_CLK_ENABLE(); }while(0)   /* TIM2 时钟使能 */


/*****************************************TIM3 位置 输入计数定义*************************************************/

#define GTIM_TIM3_CNT_CHY_GPIO_PORT            GPIOB
#define GTIM_TIM3_CNT_CHY_GPIO_PIN             GPIO_PIN_5
#define GTIM_TIM3_CNT_CHY_GPIO_AF              GPIO_AF2_TIM3                                /* AF功能选择 */
#define GTIM_TIM3_CNT_CHY_GPIO_CLK_ENABLE()    do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)  /* PA口时钟使能 */

#define GTIM_TIM3_CNT                          TIM3
#define GTIM_TIM3_CNT_IRQn                     TIM3_IRQn
#define GTIM_TIM3_CNT_IRQHandler               TIM3_IRQHandler
#define GTIM_TIM3_CNT_CHY2                     TIM_CHANNEL_2                                /* 通道Y,  1<= Y <=2 */

#define GTIM_TIM3_CNT_CHY_CLK_ENABLE()         do{ __HAL_RCC_TIM3_CLK_ENABLE(); }while(0)   /* TIM2 时钟使能 */

/****************************************************************************************************************/

void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc);    /* 通用定时器 PWM初始化函数 */
void gtim_timx_cnt_chy_init(uint16_t psc);                  /* 通用定时器 脉冲计数初始化函数 */
uint32_t gtim_timx_cnt_chy_get_count(void);                 /* 通用定时器 获取脉冲计数 */
void gtim_timx_cnt_chy_restart(void);                       /* 通用定时器 重启计数器 */

void gtim_tim3_cnt_chy_init(uint16_t psc);                  /* 通用定时器 脉冲计数初始化函数 */

#endif


四:小结

本章内容就到此为了,如果需要源码可以点击这里 stm32控制行驶指定距离觉得本章内容对你有用的话可以给博主点个赞支持一下,本人后续还会分享相关的学习,想要一块学习的小伙伴可以关注一下博主,让我们一块成长。文章来源地址https://www.toymoban.com/news/detail-856476.html

到了这里,关于stm32通过编码器控制小车行驶指定的距离的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32-编码器测速

    编码电机 旋转编码器 A,B相分别接通道一和二的引脚,VCC,GND接单片机VCC,GND 以前的代码是通过触发外部中断,然后在中断函数里手动进行计次。使用编码器接口的好处就是节约软件资源。对于频繁执行,操作简单的任务,一般设计一个硬件电路模块来自动完成。 使用定时器

    2024年03月19日
    浏览(48)
  • STM32编码器模式(带方向/正交编码)

    看前说明 :这里重点介绍的时STM32的定时器编码器模式,是根据STMF10x参考手册,如果有使用过编码器或编码器不一样的可以直接跳过前面的编码器介绍,直接看理论分析与程序部分。 这里需要注意的参数 输出脉冲线数:1024线: 编码器每旋转一周输出的脉冲的个数 ,这个数

    2023年04月24日
    浏览(55)
  • 基于STM32F103C8T6使用Arduino IDE编程闭环控制4个带编码器的有刷直流电机

    题记:标题有点长了,纯粹为了方便被检索到~~~本贴主要用于支持南方科技大学SDIM学院工业设计专业大三综合项目移动底盘学习,也是我自己按照费曼学习方法的一次尝试,用从底层搭建一个机器人底盘来复习自动控制原理。         由于工业设计专业没有开设嵌入式课程

    2024年02月05日
    浏览(46)
  • STM32——TIM编码器接口

    Encoder Interface 编码器接口 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲, 自动控制CNT自增或自减 ,从而指示编码器的位置、旋转方向和旋转速度 每个高级定时器和通用定时器都拥有 1个编码器接口 ,C8T6拥有4个编码器接口 两个输入引脚

    2024年01月19日
    浏览(41)
  • STM32 TIM编码器接口

    单片机学习! 目录 文章目录 前言 一、编码器接口简介 1.1 编码器接口作用 1.2 编码器接口工作流程 1.3 编码器接口资源分布 1.4 编码器接口输入引脚 二、正交编码器 2.1 正交编码器功能 2.2 引脚作用 2.3 如何测量方向 2.4 正交信号优势 2.5 执行逻辑 三、编码器定时器框图 3.1 编

    2024年04月14日
    浏览(45)
  • ESP32(MicroPython) 编码器电机闭环控制

    本人最近查找资料时,发现ESP32上的使用MicroPython的编码器电机相关程序较少,闭环控制程序都是Pyboard上的,与ESP32不完全兼容。本人通过micropython编程 esp32+drv8833+霍尔编码器_micropython 编码器_青右的博客-CSDN博客 上的程序读取编码器计数,然后另写了控制程序,有两个版本。

    2024年02月16日
    浏览(36)
  • STM32 ABZ编码器模式详解

            本文旨在记录和说明STM32CubeIde中ABZ编码器的配置。本人作为STM32新手,在使用STM32时,太多的意义不明的配置项让我摸不着头脑,查阅资料并在这里记录,如果有不对的,欢迎各位大佬指正。         本文硬件使用ST官方提供的NUCLEO-G474RE+X-NUCLEO-IHM16M1,记录ABZ的配

    2024年02月19日
    浏览(63)
  • STM32 EC11 旋转编码器

    代码在最后,复制可直接食用 以及我的电路图 在研究EC11的时序之前首先要了解一点,EC11按旋转的输出动作可以分为两种。一种是转两格,A、B对C端输出一个完整脉冲(转一格就只是由低电平-高电平或由高电平-低电平);另一种就是转一格,A、B对C端输出一个完整脉冲。

    2024年02月02日
    浏览(39)
  • stm32霍尔编码器电机测速原理

            本次选用的编码器电机为13线的霍尔编码器电机,电机减速比为30:1,转动一圈输出13*30=390个脉冲。轮胎直径为75mm,轮胎周长为pi*d=3*75=225mm.定时器采用四倍频计数,则一圈输出390*4=1560个脉冲。具体编码器知识这里就不多说了。          根据测速原理:假设编

    2024年02月15日
    浏览(48)
  • stm32编码器电机测速(hal库)

    记录一下今天参考别人的代码实现了四个电机的测速。   编码器被广泛应用于电机测速,实现电机闭环控制 。所以不论是自己做小车还是后续参加各种比赛,必须要学会编码器测速。         编码电机其实就是一个带有编码器的电机,我的这个电机是一个带霍尔传感器的

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包