01测试介绍
本次测试使用MC SDK提供的API函数调节电机的转速。
测试硬件:
IHM16M1 + NUCLEO-G431RB 电机套件
SSD1306 OLED IIC接口显示屏·
EC1 旋转编码器
RED LED 灯
ZD2808-V1.9 BLDC 电机
杜邦线+万用板+Type-C连接线
12V 1A开关电源
测试使用EC1旋转编码器调节电机的目标转速,使用开发板user1按钮启动/停止电机。OLED显示电机转速和调节转速设置,LED指示电机状态

02开发板资源分配
SSD1306 OLED使用 I2C1 接口,引脚 PB9 =>SDA ,PB8 => SCL
EC1旋转编码器 使用 TIM3定时器 ,引脚 PC6 => TIM3_CH1, PC7 => TIM3_CH2
RED LED ,引脚 PB7 => LED

LED需要串接 2K 电阻R,不可以直接接入MCU引脚。
03程序设置与引脚分配
1、旋转编码设置

EC1旋转编码器,使用TIM3定时器,模式设置为:ENCoder MODE,引脚PC6 => EC1_CLK, PC7 => EC1_DT
输入过滤值选择:15,其它默认。如果EC1旋转时跳动厉害,可以降低TIM3预分频器。
2、SSD1306 128*64 OLED

OLED使用I2C1作为控制,引脚PB9 =>OLED_SDA ,PB8 => OLED_SCL
3、RED LED

LED使用GPIO PB8引脚,将引脚设置上拉和输出模式。
04程序与工作原理
1、EC1是一种简易的旋转编码器,可以生产两路脉冲CLK、DT,该组脉冲相差90度,编码器作为机械部件其输出的波形不如磁编的好,所以输出引脚需要上拉电阻和103的电容滤波。
编码器可以使用__HAL_TIM_GET_COUNTER(&htim3)获得编码的计数累加值。__HAL_TIM_SetCounter(&htim3,0);设置编码器的初始值。
向上滑动阅览
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_CORDIC_Init();
MX_TIM1_Init();
MX_USART2_UART_Init();
MX_MotorControl_Init();
MX_I2C1_Init();
MX_TIM3_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
rspeed = MC_GetMecSpeedReferenceMotor1();
HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);
ssd1306_Init();
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_WriteString("EEWORLD", Font_11x18, White);
ssd1306_UpdateScreen();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (IDLE == MC_GetSTMStateMotor1())
{
/* Ramp parameters should be tuned for the actual motor */
HAL_GPIO_WritePin(Mstatus_GPIO_Port,Mstatus_Pin,GPIO_PIN_RESET);
speed = 0;
counter = __HAL_TIM_GET_COUNTER(&htim3);
if(counter != counter_old)
{
//rspeed = MC_GetMecSpeedReferenceMotor1();
rspeed += counter/2;
if( rspeed <0)
{
rspeed=0;
__HAL_TIM_SetCounter(&htim3,0);
}
if( rspeed > 420)
{
rspeed=420;
__HAL_TIM_SetCounter(&htim3,0);
}
MC_ProgramSpeedRampMotor1(rspeed, 1000);
}
counter_old = counter;
}
else
{
HAL_GPIO_WritePin(Mstatus_GPIO_Port,Mstatus_Pin,GPIO_PIN_SET);
speed = MC_GetMecSpeedAverageMotor1();
}
ssd1306_Fill(Black);
ssd1306_SetCursor(0, 0);
ssd1306_WriteString("SPEED TEST", Font_11x18, White);
ssd1306_SetCursor(0, 20);
memset(MessageStr,'�',sizeof(MessageStr));
sprintf(MessageStr,"%d RPM",speed * 6);
ssd1306_WriteString(MessageStr, Font_11x18, White);
ssd1306_SetCursor(0, 40);
memset(MessageStr,'�',sizeof(MessageStr));
sprintf(MessageStr,"%d R",rspeed * 6);
ssd1306_WriteString(MessageStr, Font_11x18, White);
ssd1306_UpdateScreen();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
2、电机的状态使用MC_GetSTMStateMotor1()函数返回,IDLE状态为电机停止且准备好状态,在该状态下可以调节参数和设置电机启动。本例将电机参数设置放在该状态下完成。
向上滑动阅览
if (IDLE == MC_GetSTMStateMotor1())
{
/* Ramp parameters should be tuned for the actual motor */
HAL_GPIO_WritePin(Mstatus_GPIO_Port,Mstatus_Pin,GPIO_PIN_RESET);
speed = 0;
counter = __HAL_TIM_GET_COUNTER(&htim3);
if(counter != counter_old)
{
//rspeed = MC_GetMecSpeedReferenceMotor1();
rspeed += counter/2;
if( rspeed <0)
{
rspeed=0;
__HAL_TIM_SetCounter(&htim3,0);
}
if( rspeed > 420)
{
rspeed=420;
__HAL_TIM_SetCounter(&htim3,0);
}
MC_ProgramSpeedRampMotor1(rspeed, 1000);
}
counter_old = counter;
}
else
{
HAL_GPIO_WritePin(Mstatus_GPIO_Port,Mstatus_Pin,GPIO_PIN_SET);
speed = MC_GetMecSpeedAverageMotor1();
}
参数设置:MC_ProgramSpeedRampMotor1(rspeed, 1000);该函数可以设置从上一个状态到目标状态需要持续的时间,其时间斜率需要根据电机的性能参数而定。
05测试
修改转速过程,使用旋转编码器进行参数的调节,顺时针:增加转速,逆时针:降低转速
以上测评内容撰写自电子工程世界(EEWORLD)用户:bigbat。感谢这位小伙伴对测评活动的大力支持!
全部0条评论
快来发表一下你的评论吧 !