- 2025-03-10
-
回复了主题帖:
请教一个循环流水灯的设计
用%运行就可以了吧
-
回复了主题帖:
基于【STSPIN32G4】的BLDC电机控制
- 2025-03-08
-
回复了主题帖:
【TMC2208评测测评】带加减速过程的PWM电机位置模式转起来
Jacktang 发表于 2025-3-8 11:15
代码是deepseek帮忙生成的么
是的,初始化,和使用代码都是生成的.我就调调加减速参数
- 2025-03-07
-
发表了主题帖:
【TMC2208评测测评】带加减速过程的PWM电机位置模式转起来
话接上回.PWM输出已经正常.现在需要增加一个PWM高速位置模式.
经常和deepseek讨论,最终选择了余弦S曲线加减速算法.deepseek帮忙生成了基本算法.我调整了加速时间和频率更新时间间隔
#define M_PI 3.14159265358979323846f // 单精度浮点版本
// 加速控制参数
#define ACCEL_TIME_MS 10 // 总加速时间 (ms)
#define ACCEL_INTERVAL 2 // 频率更新间隔 (ms)
#define MAX_SPEED 20000
// 方式1:三次多项式S曲线(更节省计算资源)
float Cubic_S_Curve(float t, float T)
{
t = t / T; // 归一化时间 [0,1]
return 3 * t * t - 2 * t * t * t; // 三次多项式曲线
}
// 方式2:余弦S曲线(更平滑)
float Cosine_S_Curve(float t, float T)
{
return 0.5f - 0.5f * cosf(t * M_PI / T); // 0.5*(1 - cos(πt/T))
}
由于使用PWM模式,位置模式下脉冲计数又成了难题.再次请教了deepseek.它帮我想了三个解决方案
最终我选择了主从定时器门控的方案.
所以本测试使用了三个定时器
TIM1 // PWM定时器
TIM2 // 加减速定时器
TIM3 // 计数定时器
TIM1的初始化和使用接口
/* 硬件配置:TIM1_CH4 -> PA11 */
void PWM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// 1. 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE);
// 2. 配置GPIO
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);
// 3. 配置定时器基础参数
TIM_InitStruct.TIM_Period = 9999; // 自动重装载值
TIM_InitStruct.TIM_Prescaler = 71; // 预分频系数
TIM_InitStruct.TIM_ClockDivision = 0;
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_InitStruct);
// 4. 配置PWM模式
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 5000; // 初始占空比50%
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC4Init(TIM1, &TIM_OCInitStruct); // 5. 配置通道4(PA11)
// 5. 使能预装载寄存器
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
// 6. 使能TIM1主输出
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器需要这个设置
// 7. 启动TIM1
// TIM_Cmd(TIM1, ENABLE);
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC4Ref); // 主定时器触发源为更新事件?:ml-citation{ref="1,2" data="citationList"}
}
// 更新PWM频率
void Update_PWM_Freq(uint32_t freq)
{
uint32_t arr = (1000000 / freq) - 1; // 计算ARR值(72MHz主频)
if (running == 0) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStruct;
// 重新配置时基
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// 保持占空比50%
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = (arr + 1) / 2; // 初始占空比50%
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC4Init(TIM1, &TIM_OCInitStruct); // 5. 配置通道4(PA11)
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器需要这个设置
TIM_Cmd(TIM1, ENABLE);
} else {
TIM1->CCR4 = (arr + 1) / 2;
TIM1->ARR = arr;
}
running = 1;
}
加减速定时器实现
// 动态修改函数示例
void Set_Motor_Speed(uint8_t direction, uint32_t new_target)
{
if (direction)
GPIO_ResetBits(GPIOA, GPIO_Pin_10); // DIR low
else
GPIO_SetBits(GPIOA, GPIO_Pin_10); // DIR high
START_FREQ = current_freq;
if (current_freq == 0)
START_FREQ = 1000;
TARGET_FREQ = new_target;
// 重置加速状态
elapsed_time = 0;
speed_down = 0;
TIM_Cmd(TIM2, ENABLE); // 重新启动加速过程
}
// 定时器2初始化(用于加速控制)
void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 定时器配置:20ms中断间隔
TIM_TimeBaseStructure.TIM_Period = (1000000 / 1000 * ACCEL_INTERVAL) - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 1MHz计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM2, TIM_IT_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// TIM_Cmd(TIM2, ENABLE);
// 配置NVIC
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// TIM2中断处理(加速控制)
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update)) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 选择其中一种S曲线算法
//float ratio = Cubic_S_Curve(elapsed_time, ACCEL_TIME_MS);
float ratio = Cosine_S_Curve(elapsed_time, ACCEL_TIME_MS);
if (speed_down == 0)
current_freq = START_FREQ + (TARGET_FREQ - START_FREQ) * ratio;
else
current_freq = START_FREQ - (START_FREQ - TARGET_FREQ) * ratio;
Update_PWM_Freq(current_freq);
elapsed_time += ACCEL_INTERVAL;
if (elapsed_time > ACCEL_TIME_MS || current_freq == TARGET_FREQ) {
TIM_Cmd(TIM2, DISABLE); // 加速完成停止定时器
}
}
}
位置控制定时器实现代码,并使用TIM3的比较中断提前预估开始减速的位置.在匹配中断中启动PWM减速
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
current_freq = 0;
running = 0;
TIM_Cmd(TIM1, DISABLE); // 停止PWM定时器
TIM_Cmd(TIM2, DISABLE); // 停止加减速定时器
TIM_Cmd(TIM3, DISABLE); // 停止计数定时器
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) {
if (running) {
START_FREQ = current_freq;
TARGET_FREQ = 1000;
// 重置加速状态
elapsed_time = 0;
speed_down = 1;
TIM_Cmd(TIM2, ENABLE); // 重新启动加速过程
}
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
}
}
void Set_Motor_Position(uint32_t new_target)
{
int steps = (int)abs((int)(new_target - current_pos));
// 时基配置(ARR为脉冲总数)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_TimeBaseStruct.TIM_Period = steps - 1; // 设定脉冲数
TIM_TimeBaseStruct.TIM_Prescaler = 0;
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
// 触发源配置
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0); // 触发源选择ITR1(TIM1主)?:ml-citation{ref="1,2" data="citationList"}
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1); // 从模式为外部触发?:ml-citation{ref="1,2" data="citationList"}
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_ClearFlag(TIM3, TIM_IT_Update | TIM_IT_CC1);
TIM_ITConfig(TIM3, TIM_IT_Update | TIM_IT_CC1, ENABLE); // 使能更新中断
NVIC_EnableIRQ(TIM3_IRQn); // 启用中断通道
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 在main函数初始化中设置优先级分组
NVIC_SetPriority(TIM3_IRQn, 0); // 设置高优先级
TIM_SetCompare1(TIM3, steps - 169);
TIM_Cmd(TIM3, ENABLE);
Set_Motor_Speed(current_pos < new_target, MAX_SPEED);
current_pos = new_target;
}
最终使用方法
static void step_task_entry(ULONG thread_input)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_9); // 默认使能驱动器
SetMicrostep(3); // 16细分
PWM_Config();
TIM2_Init();
// Set_Motor_Speed(0, MAX_SPEED); // 启动到23K
while (1) {
//Set_Motor_Speed(0, 22000); // 启动到22K
Set_Motor_Position(200 * 16);
tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND / 2);
//Set_Motor_Speed(0, 2000); // 启动到22K
Set_Motor_Position(0);
tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND / 2);
}
}
加减速效果如图
运行效果
[localvideo]ef9d707100ea6e2873bc771ed534dee3[/localvideo]
测试总结:
19年前第一次做项目,也涉及到步进电机的控制.当时使用PWM时,还是使用PWM的中断来进行计数的.
这个主从定时器的方案让我眼前一亮.效果太好了.
实测16细分时,最大速度20K,运行稳定,定位精准,声音很小.
- 2025-03-04
-
发表了主题帖:
【TMC2208评测测评】PWM电机转起来
作为一名码农,这个板子的测试好像货不对板.本应该评测驱动芯片的性能.如驱动能力,电流,发热等等.奈何码农手头没装备.脑袋里也没货.不知道从哪下手.
还是从软件角度出发.这次改用PWM控制电机,并验证细分的效果.
功能比较简单,先贴基本代码,细分设置:
// 设置微步模式(0-1/8,1-1/2步,2-1/4步,3-1/16步)
// MS1 => PB6
// MS2 => PB7
void SetMicrostep(uint8_t mode)
{
switch (mode) {
case 0: // 1/8步
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
break;
case 1: // 1/2步
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
break;
case 2: // 1/4步
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_7);
break;
case 3: // 1/16步
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_7);
break;
}
}
PWM生成使用PA11(TIM1_CH4),之前贴子定的是PA8(TIM1_CH1)奈何一直无法输出波形.只能先改用PA11了!
/* 硬件配置:TIM1_CH4 -> PA11 */
void PWM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// 1. 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO, ENABLE);
// 2. 配置GPIO
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE);
// 3. 配置定时器基础参数
TIM_InitStruct.TIM_Period = 9999; // 自动重装载值
TIM_InitStruct.TIM_Prescaler = 71; // 预分频系数
TIM_InitStruct.TIM_ClockDivision = 0;
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_InitStruct);
// 4. 配置PWM模式
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 5000; // 初始占空比50%
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM1, &TIM_OCInitStruct); // 5. 配置通道4(PA11)
// 5. 使能预装载寄存器
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
// 6. 使能TIM1主输出
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器需要这个设置
// 7. 启动TIM1
// TIM_Cmd(TIM1, ENABLE);
}
// 更新PWM频率
void Update_PWM_Freq(uint32_t freq)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
uint32_t arr = (72000000 / freq) - 1; // 计算ARR值(72MHz主频)
// 重新配置时基
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// 保持占空比50%
TIM_SetCompare4(TIM1, (arr + 1) / 2);
TIM_Cmd(TIM1, ENABLE);
}
main函数中直接调用
GPIO_ResetBits(GPIOA, GPIO_Pin_9); // 默认使能驱动器
SetMicrostep(3);
PWM_Config();
Update_PWM_Freq(16000);
直接输出就可以了.
硬件PWM输出还是非常NICE的.
在无加速的情况下:
16细分下,PWM可以上到16K.
2细分下,PWM可上2K.
基本就是这个比例了.
电机运行效果很好,很安静...
[localvideo]ecc34263aa32cb63c004e206d45b92d0[/localvideo]
- 2025-02-28
-
回复了主题帖:
图中的4个按键,只有3个IO,如何实现按键检测
1:4,5上拉输入,6输出高,检查4,5低电平判断S1,S2有没有按下
2:5,6转下拉输入,4转高输出,检查6高电平判断S3有没有按下
3.4,6转下拉输入,5转高输出,检查6高电平判断S4有没有按下
这样不停的扫描.
个人意见
-
回复了主题帖:
【TMC2208评测测评】电机转起来
是的呀.直接把芯片的手册丢给他就行了.
- 2025-02-27
-
回复了主题帖:
【TMC2208评测测评】电机转起来
哎,视频怎么看不到
-
发表了主题帖:
【TMC2208评测测评】电机转起来
在经历烧掉一块Bluepill和一块TMC2208驱动板之后,电机终于转起来了.
[localvideo]3a7c83eba88755d15567c441699e0815[/localvideo]
测试硬件环境:
Bluepill一块
TMC2208驱动板一块
LM2596电源模块一块
合宙DAPlink仿真器
本次代码主要由deepseek协助完成.
我将我的要求提供给了deepseek.首先帮我生成代码框架
但是它生成的代码是基于HAL库.我的STM32F103的代码是基于标准库的.于是要求用标准库重新写
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
// 精确延时函数(基于72MHz主频)
void Delay_us(uint32_t us) {
us *= 72; // 72 cycles per microsecond
while(us--) __asm__("nop");
}
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置STEP引脚(PA8)
GPIO_InitStructure.GPIO_Pin = STEP_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置EN引脚(PA9,开漏输出)
GPIO_InitStructure.GPIO_Pin = EN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, EN_PIN); // 默认使能驱动器
// 配置DIR引脚(PA10)
GPIO_InitStructure.GPIO_Pin = DIR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置微步引脚(PB6/PB7)
GPIO_InitStructure.GPIO_Pin = MS1_PIN | MS2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
// 设置微步模式(0-全步,1-1/2步,2-1/4步,3-1/8步)
void SetMicrostep(uint8_t mode) {
switch(mode) {
case 0: // 全步
GPIO_ResetBits(GPIOB, MS1_PIN);
GPIO_ResetBits(GPIOB, MS2_PIN);
break;
case 1: // 1/2步
GPIO_SetBits(GPIOB, MS1_PIN);
GPIO_ResetBits(GPIOB, MS2_PIN);
break;
case 2: // 1/4步
GPIO_ResetBits(GPIOB, MS1_PIN);
GPIO_SetBits(GPIOB, MS2_PIN);
break;
case 3: // 1/8步
GPIO_SetBits(GPIOB, MS1_PIN);
GPIO_SetBits(GPIOB, MS2_PIN);
break;
}
}
// 发送单个脉冲(最小脉宽1us)
void SingleStep(void) {
GPIO_SetBits(GPIOA, STEP_PIN);
Delay_us(1); // 保持高电平至少1us
GPIO_ResetBits(GPIOA, STEP_PIN);
Delay_us(1); // 低电平保持
}
// 连续步进控制
void Stepping(uint32_t steps, uint8_t direction, uint16_t speed_us) {
GPIO_WriteBit(GPIOA, DIR_PIN, direction ? Bit_SET : Bit_RESET);
for(uint32_t i=0; i<steps; i++) {
SingleStep();
if(speed_us > 2) Delay_us(speed_us - 2); // 补偿脉冲时间
}
}
int main(void) {
SystemInit();
GPIO_Configuration();
SetMicrostep(3); // 使用1/8微步
while(1) {
Stepping(200, 1, 1000); // 正转200步,1ms/步
Delay_us(500000); // 暂停500ms
Stepping(200, 0, 1000); // 反转200步,1ms/步
Delay_us(500000);
}
}
代码注释清晰,并给出了解释.非常的不错
这样一个简单的基于GPIO翻转发送脉冲的步进电机控制程序就完成了.代码复制进我现有的项目中.就能跑起来了.
主要代码如下.
// 精确延时函数(基于72MHz主频)
void Delay_us(uint32_t us)
{
us *= 72; // 72 cycles per microsecond
while (us--) __asm__("nop");
}
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// Enable GPIOA and GPIOB clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置STEP引脚(PA8)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置EN引脚(PA9,开漏输出)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置DIR引脚(PA10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置微步引脚(PB6/PB7)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
// 设置微步模式(0-1/8,1-1/2步,2-1/4步,3-1/16步)
void SetMicrostep(uint8_t mode)
{
switch (mode) {
case 0: // 1/8步
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
break;
case 1: // 1/2步
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
break;
case 2: // 1/4步
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_7);
break;
case 3: // 1/16步
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_SetBits(GPIOB, GPIO_Pin_7);
break;
}
}
void StepperMotor_Step(uint16_t steps, uint8_t direction)
{
uint16_t i;
if (direction)
GPIO_ResetBits(GPIOA, GPIO_Pin_10); // DIR low
else
GPIO_SetBits(GPIOA, GPIO_Pin_10); // DIR high
for (i = 0; i < steps; i++) {
GPIO_SetBits(GPIOA, GPIO_Pin_8); // STEP high
Delay_us(10); // Adjust the delay for your step frequency
GPIO_ResetBits(GPIOA, GPIO_Pin_8); // STEP low
Delay_us(10); // Adjust the delay for your step frequency
}
//GPIO_SetBits(GPIOA, GPIO_Pin_9);
}
int main()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* 使能 PWR 和 BKP 外设时钟 */
PWR_BackupAccessCmd(ENABLE); /* 使能后备寄存器访问 */
BKP_WriteBackupRegister(BKP_DR1, 0); /* 向指定的后备寄存器中写入用户程序数据 */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GpioInit(GPIO_LED, GPIO_Speed_50MHz, GPIO_Mode_Out_PP);
UartInit(0, 115200);
GPIO_Config();
GPIO_ResetBits(GPIOA, GPIO_Pin_9); // 默认使能驱动器
SetMicrostep(0);
printf("System is running\r\n");
while (1) {
StepperMotor_Step(200 * 8, 1); // 正转1600步
Delay_us(50000); // 暂停500ms
StepperMotor_Step(200 * 8, 0); // 反转1600步
Delay_us(50000);
}
}
还是发现AI生成的细分设置代码是错误的
这段代码和手册说明不一致.
由于本次测评,并不是一个完整的可运行硬件环境,所以过程比较坎坷.电源问题还烧坏了板子,那一种青烟袅绕...
环境搭起来了,下一步改用PWM模式控制测试一下加减速功能.
- 2025-02-14
-
发表了主题帖:
【TMC2208评测测评】开箱和测试环境准备
本帖最后由 flyaqiao 于 2025-2-15 13:36 编辑
TMC2208是一款超静音的两相步进电机驱动芯片,持续驱动电流1.4A,峰值电流2A,电压范围4.75V-36V,256细分;灵活的microPlyer插值单元,可提供高达256的细分,即使是在脉冲频率有限的系统中仍可完美地实现正弦控制;由于stealthChop2超静音技术在3D打印中被广泛应用,因此这些组件的设计也与现有3D打印机电子设备兼容,省去了重新设计所产生的昂贵费用。具有标准的step/dir接口,使用起来简单方便。可以替代原有的TMC2100,更低的发热量,特别适合3D打印市场。
主要特点
功率管内置驱动电流1.4A峰值电流2A,电压范围4.75V-36V
多达256个本地微步(无插值)
CoolStep™电流动态调节技术,可节省70%的能源
stealthChop2 - 比stealthChop更快的电机加速/减速
dcStep™,stallGuard2™失速检测技术
根据速度自动进行stealthChop和spreadCycle切换
硬件兼容StepStick和Pololu A4988步进驱动器
底部PCB一侧的元件可以获得更好的散热效果
自动待机电流减少
StealthChop静音技术
高度动态的电机控制斩波器
先来一张全家福:
驱动板的接口说明:
开发板的接口说明
电源板:
电机:
准备了两个步进电机,一个42的,一个35的.
接口定义:
结束语:
东拼西凑的终于准备全了测试环境.为下一步编码打下了坚实的基础
-
回复了主题帖:
你参加哪吒2的百亿项目了吗?
好贵,三张票搞了2张多软妹子
- 2025-02-12
-
回复了主题帖:
求助!!!MOSFET开关电路
本帖最后由 flyaqiao 于 2025-2-12 00:21 编辑
NMOS管的S是不是应该接地.Vgs>Vth时才能导通吧
- 2025-02-05
-
回复了主题帖:
开工大吉,你们收到开工红包了吗~
Chn 发表于 2025-2-5 14:34
有的会在公司大门口给员工一个个发红包,有的在群里发应该
我们
- 2025-01-27
-
回复了主题帖:
年前最后一贴,同志们来顶顶
2025顺风顺水顺财神
- 2025-01-19
-
回复了主题帖:
【测评入围名单(最后1批)】年终回炉:FPGA、AI、高性能MCU、书籍等65个测品邀你来~
个人信息无误,可按时完成测评计划
- 2025-01-16
-
回复了主题帖:
你们春节放几天呀?
吾妻思萌 发表于 2025-1-14 17:10
好多公司就是强制休息然后扣年假,省得你年假用不完后面离职时候还要付给你工资捏
是的,已经攒了50多天年假了,又不给休,还舍不得给钱,就挂着,心里慌的一比
- 2025-01-10
-
回复了主题帖:
你们春节放几天呀?
我们自己需要强制请两天年假,时间来到了11天,怎么和我们一样,往年都不扣年假,今年还要扣年假了
-
回复了主题帖:
【回顾2024,展望2025】新年抢楼活动来啦!
⑴遇到过什么技术问题,是否解决了?怎么解决的。没解决需要帮助也可以说说,论坛伙伴们帮忙看看
重写了总工代码的近10年的功能,解决几个幽灵BUG
-
回复了主题帖:
【回顾2024,展望2025】新年抢楼活动来啦!
本帖最后由 flyaqiao 于 2025-1-10 14:37 编辑
⑸立一个新年Flag
新年FLAG,刚买了一块K230的开发板,新年好好学习一下AI视觉,希望能用到项目上
-
回复了主题帖:
【回顾2024,展望2025】新年抢楼活动来啦!
本帖最后由 flyaqiao 于 2025-1-10 14:37 编辑
⑵实现了哪些目标,达成了什么成就?比如迈向人生新阶段升学毕业结婚生子,比如解决了技术难题完成了新项目学会了新技能...
好好的学习了4G通信和LINUX内核编译,以及LINUX下4G模块USB驱动支持