找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9277|回复: 9
收起左侧

STM32步进电机编码器读取源码

  [复制链接]
ID:364498 发表于 2018-11-9 15:19 | 显示全部楼层 |阅读模式
STM32F10X  步进电机编码器 读取  Hal固件库。  

【1】例程简介
  使用定时器功能输出PWM信号到步进电机驱动器,使其驱动步进电机转动。
  编码器用于电机测速。在电机转动一圈时编码器可以输出固定的脉冲数,通过读取编码器
脉冲可以获取当前电机转动状态。
一般处理编码器脉冲有两种方法:
1. T法:计算一定量的脉冲数所用的时间
2. M法:计算一段固定时间内所捕获的脉冲数。

【2】跳线帽情况
编码器              A相  --> PC6
                B相  --> PC7
               
步进电机驱动器    DIR- --> PB13
                ENA- --> PB14
                PUL- --> PA8
                DIR+ --> +5V
                ENA+ --> +5V
                PUL+ --> +5V
        
【3】操作及现象
  根据引脚定义方法连接开发板和步进电机驱动器,另外步进电机驱动器和
步进电机的连接自行根据电机和驱动器标识连接,步进电机驱动器需要一个24V的直流
电源供电,编码器是开漏输出.所以需要接上拉电阻才能正常读取数据。接线时注意开发板与步进电机
驱动板“共地”连接,编码器与开发板"共地"连接。使用开发板配套的MINI USB线连接到开发板标示
“调试串口”字样的MIMI USB接口为开发板提供电源。下载完程序之后,开发板持续PWM脉冲给步进
电机驱动器,电机持续转动,同时在串口发送当前编码器捕获值,和速度值.


单片机源程序如下:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.1
  6.   * 功    能: 步进电机编码测速

  7.   */
  8. /* 包含头文件 ----------------------------------------------------------------*/
  9. #include "stm32f1xx_hal.h"
  10. #include "StepMotor/bsp_STEPMOTOR.h"
  11. #include "usart/bsp_debug_usart.h"
  12. #include "EncoderTIM/bsp_EncoderTIM.h"
  13. #include  <string.h>
  14. /* 私有类型定义 --------------------------------------------------------------*/
  15. /* 私有宏定义 ----------------------------------------------------------------*/
  16. #define SAMPLING_PERIOD             20    // 采样周期;单位20ms
  17. #define TXDCYCLE                  1000    // 数据发送周期;单位:ms
  18. #define SAMPLING                  0x01    // 采样标记
  19. #define TXD                       0x02    // 发送数据标记                        
  20. #define SPEED_CONSTANT            ((((float)(TXDCYCLE)/SAMPLING_PERIOD))/PSPM);//脉冲数转换为mm/s的系数,1秒的脉冲数/1毫米的脉冲数,这里扩大10倍

  21. #define abs(x)                    ((x)<0?(-x):(x))
  22. #define SENDBUFF_SIZE             60  // 串口DMA发送缓冲区大小

  23. /* 私有变量 ------------------------------------------------------------------*/
  24. __IO uint16_t time_count=0;         // 时间计数,每1ms增加一(与滴答定时器频率有关)
  25. __IO int32_t CaptureNumber=0;       // 输入捕获数
  26. __IO int32_t Last_CaptureNumber=0;  // 上一次捕获值

  27. __IO static int16_t Speed = 50;   // 换算为丝杠上行进的速度,单位为:0.1mm/s所以实际速度是5mm/s
  28. __IO uint16_t SUM_Pulse = 0;
  29. __IO int16_t MSF = 0;               // 电机反馈速度
  30. __IO float MMPS = 0;                // mm Per Seconed (mm/s)
  31. __IO uint8_t Time_Flag = 0;         // 标记时间

  32. uint8_t aTxBuffer[SENDBUFF_SIZE];          // 串口DMA发送缓冲区
  33. /* 扩展变量 ------------------------------------------------------------------*/
  34. extern int16_t OverflowCount;             //编码器计数溢出 计数器
  35. /* 私有函数原形 --------------------------------------------------------------*/
  36. /* 函数体 --------------------------------------------------------------------*/

  37. /**
  38.   * 函数功能: 系统时钟配置
  39.   * 输入参数: 无
  40.   * 返 回 值: 无
  41.   * 说    明: 无
  42.   */
  43. void SystemClock_Config(void)
  44. {
  45.   RCC_OscInitTypeDef RCC_OscInitStruct;
  46.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  47.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  48.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  49.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  50.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  51.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  52.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍频,得到72MHz主时钟
  53.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  54.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  55.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  56.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHz
  57.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟:72MHz
  58.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1时钟:36MHz
  59.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2时钟:72MHz
  60.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  61.          // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
  62.         // HAL_RCC_GetHCLKFreq()/100000         10us中断一次
  63.         // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  64.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器
  65.   /* 系统滴答定时器时钟源 */
  66.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  67.   /* 系统滴答定时器中断优先级配置 */
  68.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  69. }

  70. /**
  71.   * 函数功能: 主函数.
  72.   * 输入参数: 无
  73.   * 返 回 值: 无
  74.   * 说    明: 无
  75.   */
  76. int main(void)
  77. {
  78.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  79.   HAL_Init();
  80.   /* 配置系统时钟 */
  81.   SystemClock_Config();

  82.   /* 调试串口初始化 */
  83.   MX_DEBUG_USART_Init();

  84.   /* 编码器定时器初始化并配置输入捕获功能 */
  85.   ENCODER_TIMx_Init();
  86.   /* 启动编码器接口 */
  87.   HAL_TIM_Encoder_Start(&htimx_Encoder, TIM_CHANNEL_ALL);
  88.   
  89.   /* 步进电机定时器初始化*/
  90.   STEPMOTOR_TIMx_Init();
  91.   /* 启动定时器 */
  92.   HAL_TIM_Base_Start(&htimx_STEPMOTOR);
  93.   /* 启动比较输出并使能中断 */
  94.   HAL_TIM_OC_Start_IT(&htimx_STEPMOTOR,TIM_CHANNEL_1);
  95.   STEPMOTOR_OUTPUT_ENABLE();
  96.   /* 无限循环 */
  97.   while (1)
  98.   {
  99.     //采样和控制周期为20ms
  100.     if(Time_Flag & SAMPLING)
  101.     {
  102.       //获得编码器的脉冲值
  103.       CaptureNumber = OverflowCount*65535 + __HAL_TIM_GET_COUNTER(&htimx_Encoder);

  104.       //M法 测速度 M法是测量单位时间内的脉数,然后换算成频率,这里不算频率
  105.       MSF = CaptureNumber  - Last_CaptureNumber;
  106.       Last_CaptureNumber = CaptureNumber;
  107.       //对速度进行累计,得到1s内的脉冲数
  108.       MSF = abs(MSF);
  109.       SUM_Pulse += MSF;
  110.       MMPS = MSF*SPEED_CONSTANT;//由脉冲数转换为 mm/s, MMPS = (MSF*(TXDCYCLE/SAMPLING_PERIOD))/PSPM;

  111.       if(Speed >= MAX_SPEED)//限制最大速度
  112.         Speed = MAX_SPEED;
  113.       if(Speed <= MIN_SPEED)
  114.         Speed = MIN_SPEED;
  115.    
  116.       STEPMOTOR_Motion_Ctrl(CW,Speed);
  117.       Time_Flag &= ~SAMPLING;
  118.     }
  119.     //数据发送周期为1s
  120.     if(Time_Flag & TXD)
  121.     {
  122.       sprintf(aTxBuffer,"捕获值: %d -- 速度: %.2f mm/s\n",CaptureNumber,(float)MMPS);
  123.       sprintf(aTxBuffer+strlen((const char*)aTxBuffer),"1s内编码器计数值: %5d \n\0",SUM_Pulse);
  124.       HAL_UART_Transmit_DMA(&husart_debug,aTxBuffer,strlen((const char*)aTxBuffer));
  125.       SUM_Pulse = 0;
  126.       Time_Flag &= ~TXD;
  127.     }
  128.   }
  129. }

  130. /**
  131.   * 函数功能: 系统滴答定时器中断回调函数
  132.   * 输入参数: 无
  133.   * 返 回 值: 无
  134.   * 说    明: 每发生一次滴答定时器中断进入该回调函数一次
  135.   */
  136. void HAL_SYSTICK_Callback(void)
  137. {
  138.   // 每1ms自动增一
  139.   time_count++;         
  140.   if(time_count%(SAMPLING_PERIOD) == 0)// 20ms读取一次编码器数值
  141.   {
  142.     Time_Flag |= SAMPLING;
  143.   }
  144.   else if(time_count>=TXDCYCLE)        //1s发送一次数据
  145.   {
  146.     Time_Flag |= TXD;
  147.     time_count=0;
  148.   }
  149. }
  150. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

所有资料51hei提供下载:
YSF1_HAL_MOTOR-017. 步进电机编码器读取.rar (3.15 MB, 下载次数: 198)
回复

使用道具 举报

ID:185372 发表于 2018-11-22 08:43 | 显示全部楼层
这个先支持一下,最近一直调试这个,解决不了呢。
回复

使用道具 举报

ID:242969 发表于 2018-11-26 13:37 | 显示全部楼层
这个先支持一下
回复

使用道具 举报

ID:242797 发表于 2018-12-12 17:42 | 显示全部楼层
学习一下编码器
回复

使用道具 举报

ID:484341 发表于 2019-3-4 16:22 | 显示全部楼层
支持楼主
回复

使用道具 举报

ID:489661 发表于 2019-4-8 15:49 | 显示全部楼层
刚需,学习一下啊
回复

使用道具 举报

ID:500798 发表于 2019-7-11 11:12 | 显示全部楼层
我是想找楼主要一下hal库的教程的。我刚开始用hal库,很多不是很懂,想找个视频教程什么的。或者课件也是可以的
回复

使用道具 举报

ID:305616 发表于 2019-12-19 17:40 | 显示全部楼层

感谢分享!!
回复

使用道具 举报

ID:305616 发表于 2019-12-19 17:41 | 显示全部楼层


这个先支持一下
回复

使用道具 举报

ID:237117 发表于 2020-5-13 10:54 | 显示全部楼层
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表