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脉冲给步进
电机驱动器,电机持续转动,同时在串口发送当前编码器捕获值,和速度值.
单片机源程序如下:
- /**
- ******************************************************************************
- * 文件名程: main.c
- * 作 者: 硬石嵌入式开发团队
- * 版 本: V1.1
- * 功 能: 步进电机编码测速
- */
- /* 包含头文件 ----------------------------------------------------------------*/
- #include "stm32f1xx_hal.h"
- #include "StepMotor/bsp_STEPMOTOR.h"
- #include "usart/bsp_debug_usart.h"
- #include "EncoderTIM/bsp_EncoderTIM.h"
- #include <string.h>
- /* 私有类型定义 --------------------------------------------------------------*/
- /* 私有宏定义 ----------------------------------------------------------------*/
- #define SAMPLING_PERIOD 20 // 采样周期;单位20ms
- #define TXDCYCLE 1000 // 数据发送周期;单位:ms
- #define SAMPLING 0x01 // 采样标记
- #define TXD 0x02 // 发送数据标记
- #define SPEED_CONSTANT ((((float)(TXDCYCLE)/SAMPLING_PERIOD))/PSPM);//脉冲数转换为mm/s的系数,1秒的脉冲数/1毫米的脉冲数,这里扩大10倍
- #define abs(x) ((x)<0?(-x):(x))
- #define SENDBUFF_SIZE 60 // 串口DMA发送缓冲区大小
- /* 私有变量 ------------------------------------------------------------------*/
- __IO uint16_t time_count=0; // 时间计数,每1ms增加一(与滴答定时器频率有关)
- __IO int32_t CaptureNumber=0; // 输入捕获数
- __IO int32_t Last_CaptureNumber=0; // 上一次捕获值
- __IO static int16_t Speed = 50; // 换算为丝杠上行进的速度,单位为:0.1mm/s所以实际速度是5mm/s
- __IO uint16_t SUM_Pulse = 0;
- __IO int16_t MSF = 0; // 电机反馈速度
- __IO float MMPS = 0; // mm Per Seconed (mm/s)
- __IO uint8_t Time_Flag = 0; // 标记时间
-
- uint8_t aTxBuffer[SENDBUFF_SIZE]; // 串口DMA发送缓冲区
- /* 扩展变量 ------------------------------------------------------------------*/
- extern int16_t OverflowCount; //编码器计数溢出 计数器
- /* 私有函数原形 --------------------------------------------------------------*/
- /* 函数体 --------------------------------------------------------------------*/
- /**
- * 函数功能: 系统时钟配置
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 无
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; // 外部晶振,8MHz
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 9倍频,得到72MHz主时钟
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 系统时钟:72MHz
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // AHB时钟:72MHz
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1时钟:36MHz
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2时钟:72MHz
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
- // HAL_RCC_GetHCLKFreq()/1000 1ms中断一次
- // HAL_RCC_GetHCLKFreq()/100000 10us中断一次
- // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); // 配置并启动系统滴答定时器
- /* 系统滴答定时器时钟源 */
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
- /* 系统滴答定时器中断优先级配置 */
- HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
- }
- /**
- * 函数功能: 主函数.
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 无
- */
- int main(void)
- {
- /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
- HAL_Init();
- /* 配置系统时钟 */
- SystemClock_Config();
- /* 调试串口初始化 */
- MX_DEBUG_USART_Init();
- /* 编码器定时器初始化并配置输入捕获功能 */
- ENCODER_TIMx_Init();
- /* 启动编码器接口 */
- HAL_TIM_Encoder_Start(&htimx_Encoder, TIM_CHANNEL_ALL);
-
- /* 步进电机定时器初始化*/
- STEPMOTOR_TIMx_Init();
- /* 启动定时器 */
- HAL_TIM_Base_Start(&htimx_STEPMOTOR);
- /* 启动比较输出并使能中断 */
- HAL_TIM_OC_Start_IT(&htimx_STEPMOTOR,TIM_CHANNEL_1);
- STEPMOTOR_OUTPUT_ENABLE();
- /* 无限循环 */
- while (1)
- {
- //采样和控制周期为20ms
- if(Time_Flag & SAMPLING)
- {
- //获得编码器的脉冲值
- CaptureNumber = OverflowCount*65535 + __HAL_TIM_GET_COUNTER(&htimx_Encoder);
- //M法 测速度 M法是测量单位时间内的脉数,然后换算成频率,这里不算频率
- MSF = CaptureNumber - Last_CaptureNumber;
- Last_CaptureNumber = CaptureNumber;
- //对速度进行累计,得到1s内的脉冲数
- MSF = abs(MSF);
- SUM_Pulse += MSF;
- MMPS = MSF*SPEED_CONSTANT;//由脉冲数转换为 mm/s, MMPS = (MSF*(TXDCYCLE/SAMPLING_PERIOD))/PSPM;
- if(Speed >= MAX_SPEED)//限制最大速度
- Speed = MAX_SPEED;
- if(Speed <= MIN_SPEED)
- Speed = MIN_SPEED;
-
- STEPMOTOR_Motion_Ctrl(CW,Speed);
- Time_Flag &= ~SAMPLING;
- }
- //数据发送周期为1s
- if(Time_Flag & TXD)
- {
- sprintf(aTxBuffer,"捕获值: %d -- 速度: %.2f mm/s\n",CaptureNumber,(float)MMPS);
- sprintf(aTxBuffer+strlen((const char*)aTxBuffer),"1s内编码器计数值: %5d \n\0",SUM_Pulse);
- HAL_UART_Transmit_DMA(&husart_debug,aTxBuffer,strlen((const char*)aTxBuffer));
- SUM_Pulse = 0;
- Time_Flag &= ~TXD;
- }
- }
- }
- /**
- * 函数功能: 系统滴答定时器中断回调函数
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明: 每发生一次滴答定时器中断进入该回调函数一次
- */
- void HAL_SYSTICK_Callback(void)
- {
- // 每1ms自动增一
- time_count++;
- if(time_count%(SAMPLING_PERIOD) == 0)// 20ms读取一次编码器数值
- {
- Time_Flag |= SAMPLING;
- }
- else if(time_count>=TXDCYCLE) //1s发送一次数据
- {
- Time_Flag |= TXD;
- time_count=0;
- }
- }
- /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
所有资料51hei提供下载:
YSF1_HAL_MOTOR-017. 步进电机编码器读取.rar
(3.15 MB, 下载次数: 198)
|