From d1d2f8e50e96464e975a2a60c895846303b1f017 Mon Sep 17 00:00:00 2001 From: xushenghao Date: Tue, 24 Dec 2024 16:15:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9tmc2240=20=E7=BB=86=E5=88=86?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE1/8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/c_cpp_properties.json | 18 ++++ .vscode/launch.json | 24 +++++ .vscode/settings.json | 59 +++++++++++++ lib/driver/tmc2240.c | 159 ++++++++++++++++++++++++++++++++-- lib/driver/tmc2240.h | 40 ++++++--- 5 files changed, 281 insertions(+), 19 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..ff92585 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/TDM-GCC-64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c6a9069 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "e:/work/stm32/study/motor_cs103/User/system/lib/driver", + "program": "e:/work/stm32/study/motor_cs103/User/system/lib/driver/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bb879da --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/lib/driver/tmc2240.c b/lib/driver/tmc2240.c index f691ee0..d4e2296 100644 --- a/lib/driver/tmc2240.c +++ b/lib/driver/tmc2240.c @@ -93,7 +93,12 @@ static void tmc2240_config_write(tmc2240_index_e index) tmc->config.drvconf.data = 0x00000021; tmc->config.global_scaler.data = 0x00000000; - tmc->config.ihold_irun.data = 0x00071f1f; + + tmc->config.ihold_irun.bits.ihold = 31; + tmc->config.ihold_irun.bits.irun = 31; + tmc->config.ihold_irun.bits.iholddelay = 0; + tmc->config.ihold_irun.bits.irundelay = 0; + tmc->config.pwmconf.data = 0xC44C261E; tmc->config.gstat.data = 0x00000007; tmc2240_reg_write(index, TMC2240_GCONF, tmc->config.gconf.data); @@ -105,21 +110,75 @@ static void tmc2240_config_write(tmc2240_index_e index) tmc2240_reg_write(index, TMC2240_GSTAT, tmc->config.gstat.data); } +static void _tmc2240_motor_update(tmc2240_index_e index) +{ + DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); + tmc2240_t *tmc = &_tmc2240[index]; + DBG_ASSERT(tmc != NULL __DBG_LINE); + + switch (tmc->config.chopconf.bits.mres) + { + case TMC2240_MRES_256: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 256; + break; + case TMC2240_MRES_128: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 128; + break; + case TMC2240_MRES_64: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 64; + break; + case TMC2240_MRES_32: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 32; + break; + case TMC2240_MRES_16: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 16; + break; + case TMC2240_MRES_8: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 8; + break; + case TMC2240_MRES_4: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 4; + break; + case TMC2240_MRES_2: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE / 2; + break; + case TMC2240_MRES_1: + tmc->motor.step_angle = MOTOR_42_STEP_ANGLE; + break; + default: + break; + } + + tmc->motor.circle_pulse = 360 / tmc->motor.step_angle; +} + static void _tmc2240_enable(tmc2240_index_e index, BOOL enable) { DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); tmc2240_t *tmc = &_tmc2240[index]; DBG_ASSERT(tmc != NULL __DBG_LINE); + BOOL state = tmc->en->read(*tmc->en) == 0 ? TRUE : FALSE; + + if (state == enable) + { + return; + } + if (enable == TRUE) { - tmc->en->reset(*tmc->en); PWM_START(tmc->timer, tmc->time_ch); + tmc->en->reset(*tmc->en); + tmc2240_reg_write(index, TMC2240_CHOPCONF, tmc->config.chopconf.data); } else { - tmc->en->set(*tmc->en); PWM_STOP(tmc->timer, tmc->time_ch); + tmc->en->set(*tmc->en); + chopconf_u chopconf; + osel_memset((uint8_t *)&chopconf, 0, sizeof(chopconf_u)); + chopconf.bits.mres = TMC2240_MRES_1; + tmc2240_reg_write(index, TMC2240_CHOPCONF, chopconf.data); } } @@ -143,12 +202,12 @@ void tmc2240_init(tmc2240_index_e index, SPI_TypeDef *SPIx, TIM_TypeDef *timer, { DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); tmc2240_t *tmc = &_tmc2240[index]; + osel_memset((uint8_t *)tmc, 0, sizeof(tmc2240_t)); + tmc->timer = timer; tmc->time_ch = time_ch; tmc->spi = spi_create(SPI_TYPE_NORMAL, *gpios, 0); DBG_ASSERT(tmc->spi != NULL __DBG_LINE); - osel_memset((uint8_t *)&tmc->config, 0, sizeof(tmc2240_config_t)); - osel_memset((uint8_t *)&tmc->read_config, 0, sizeof(tmc2240_config_t)); tmc->spi->interface.hardware_enable(tmc->spi, SPIx); { tmc->default_tm.sysclk = SystemCoreClock / 1000; @@ -162,6 +221,7 @@ void tmc2240_init(tmc2240_index_e index, SPI_TypeDef *SPIx, TIM_TypeDef *timer, tmc->params.enable = FALSE; tmc->params.direction = TMC2240_FORWARD; tmc2240_config_write(index); + _tmc2240_motor_update(index); } tmc2240_t *tmc2240_get(tmc2240_index_e index) @@ -196,15 +256,64 @@ void tmc2240_config_read(tmc2240_index_e index) tmc->data.tmc2240_temperature = (float32)(tmc->data.tmc2240_adc_temp - 2038) / 7.7; } -void tmc2240_process(tmc2240_index_e index) +void tmc2240_test(tmc2240_index_e index) { DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); tmc2240_t *tmc = &_tmc2240[index]; DBG_ASSERT(tmc != NULL __DBG_LINE); _tmc2240_enable(index, tmc->params.enable); - _tmc2240_direction(index, tmc->params.direction); + if (tmc->params.enable == TRUE) + { + _tmc2240_direction(index, tmc->params.direction); + + if (PWM_GET_ARR(tmc->timer) != tmc->params.arr) + { + if (tmc->params.arr == 0) + { + tmc->params.arr = tmc->default_tm.arr; + } + PWM_SET_ARR(tmc->timer, tmc->params.arr); + tmc->params.freq = PWM_GET_FREQ(tmc->timer); + } + + tmc2240_percent(index, tmc->params.percent); + + if (tmc->config.chopconf.bits.mres != tmc->read_config.chopconf.bits.mres) + { + tmc2240_reg_write(index, TMC2240_CHOPCONF, tmc->config.chopconf.data); + _tmc2240_motor_update(index); + } + } +} + +void tmc2240_motor_set_angle(tmc2240_index_e index, int32_t angle) +{ + DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); + tmc2240_t *tmc = &_tmc2240[index]; + DBG_ASSERT(tmc != NULL __DBG_LINE); + + if (angle == 0) + { + return; + } + + if (angle > 0) + { + tmc->params.direction = TMC2240_FORWARD; + } + else + { + tmc->params.direction = TMC2240_BACKWARD; + } + + tmc->motor.pulse_count = ABS(angle) / tmc->motor.step_angle; + tmc->motor.step_angle_count = 0; + + tmc->params.enable = TRUE; + + _tmc2240_direction(index, tmc->params.direction); if (PWM_GET_ARR(tmc->timer) != tmc->params.arr) { if (tmc->params.arr == 0) @@ -216,4 +325,40 @@ void tmc2240_process(tmc2240_index_e index) } tmc2240_percent(index, tmc->params.percent); + + if (tmc->config.chopconf.bits.mres != tmc->read_config.chopconf.bits.mres) + { + tmc2240_reg_write(index, TMC2240_CHOPCONF, tmc->config.chopconf.data); + _tmc2240_motor_update(index); + } + _tmc2240_enable(index, tmc->params.enable); +} + +void tmc2240_motor_update(tmc2240_index_e index) +{ + DBG_ASSERT(index < TMC2240_MAX __DBG_LINE); + tmc2240_t *tmc = &_tmc2240[index]; + DBG_ASSERT(tmc != NULL __DBG_LINE); + + if (tmc->motor.pulse_count > 0) + { + tmc->motor.pulse_count--; // 脉冲数 + tmc->motor.step_angle_count++; // 步距个数 + if (tmc->params.direction == TMC2240_FORWARD) + { + tmc->motor.add_pulse_count++; /* 绝对位置++ */ + } + else + { + tmc->motor.add_pulse_count--; /* 绝对位置-- */ + } + } + + /* 当脉冲数等于0的时候 代表需要发送的脉冲个数已完成,停止输出 */ + + if (tmc->motor.pulse_count <= 0) + { + tmc->params.enable = FALSE; + _tmc2240_enable(index, tmc->params.enable); + } } diff --git a/lib/driver/tmc2240.h b/lib/driver/tmc2240.h index 47709d2..1f5379d 100644 --- a/lib/driver/tmc2240.h +++ b/lib/driver/tmc2240.h @@ -5,6 +5,7 @@ * @version 0.1 * @note * 1. 芯片VM需要供电,否则SPI无法正常通信 + * 2. 42步进电机每步1.8度,1圈200步。1/8细分,1步=0.225度,电机转一周需要1600个脉冲 */ #ifndef __TMC2240_H @@ -12,6 +13,7 @@ #include "main.h" #include "spis.h" +#define MOTOR_42_STEP_ANGLE 1.8f // 42步进电机每步1.8度 #define TMC2240_PWM_DUTY_DEFAULT 50 // PWM默认占空比 /* @@ -327,30 +329,44 @@ typedef struct // PRIVATE struct { - uint32_t sysclk; - uint32_t psc; // 预分频系数 - uint16_t arr; // 自动重装值 auto reload value - uint32_t freq; + uint32_t sysclk; // 系统时钟 + uint32_t psc; // 预分频系数 + uint16_t arr; // 自动重装值 auto reload value + uint32_t freq; // 频率 } default_tm; struct { - BOOL enable; // 使能 - tmc2240_direction_e direction; - float32 percent; - uint16_t arr; - uint32_t freq; + BOOL enable; // 使能 + tmc2240_direction_e direction; // 方向 + float32 percent; // 占空比 + uint16_t arr; // 自动重装值(改变速度) + uint32_t freq; // 频率 } params; struct { - uint16_t tmc2240_adc_temp; - float32 tmc2240_temperature; + float32 step_angle; // 步进角度 + uint16_t circle_pulse; // 一圈脉冲数 + + __IO int32_t add_pulse_count; /* 脉冲个数累计 */ + __IO uint32_t pulse_count; /* 脉冲个数记录 */ + __IO uint32_t step_angle_count; /* 步距个数 */ + } motor; + + struct + { + uint16_t tmc2240_adc_temp; // 温度ADC值 + float32 tmc2240_temperature; // 温度 } data; + } tmc2240_t; void tmc2240_init(tmc2240_index_e index, SPI_TypeDef *SPIx, TIM_TypeDef *timer, uint32_t time_ch, spi_gpio_group_t *gpios); tmc2240_t *tmc2240_get(tmc2240_index_e index); -void tmc2240_process(tmc2240_index_e index); +void tmc2240_motor_set_angle(tmc2240_index_e index, int32_t angle); +void tmc2240_motor_update(tmc2240_index_e index); + +void tmc2240_test(tmc2240_index_e index); void tmc2240_config_read(tmc2240_index_e index); #endif // __TMC2240_H