在经历烧掉一块Bluepill和一块TMC2208驱动板之后,电机终于转起来了.
WeChat_20250303085649
测试硬件环境:
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模式控制测试一下加减速功能.