diff --git a/.clang-format b/.clang-format
index ecc57c4..408ff24 100644
--- a/.clang-format
+++ b/.clang-format
@@ -7,8 +7,8 @@ Language: Cpp
###################################
UseTab: Never
-IndentWidth: 4
-TabWidth: 4
+IndentWidth: 2
+TabWidth: 2
ColumnLimit: 0
AccessModifierOffset: -4
NamespaceIndentation: All
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 984a112..718a76a 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -7,7 +7,7 @@
"request": "launch",
"name": "openocd",
"servertype": "openocd",
- "executable": "build\\BC3D\\BC3D.elf",
+ "executable": "build\\Debug\\BC3D.elf",
"runToEntryPoint": "main",
"configFiles": [
"interface/cmsis-dap.cfg",
diff --git a/BC3D.ATWP b/BC3D.ATWP
index 3d53aab..670c04d 100644
--- a/BC3D.ATWP
+++ b/BC3D.ATWP
@@ -36,17 +36,21 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -67,11 +71,9 @@
0;0;0
0;0;0
0;0;0
- 0;0;0
0;0;0
- 0;0;0
- 0;0;0
0;0;0
+ 1;0;0
0;0;0
@@ -134,7 +136,7 @@
BC3D
- C:/Users/ForgotDoge/Desktop/BC2024/firmware
+ C:/Users/evan/Desktop
MDK_V5
true
0x200
diff --git a/BC3D.code-workspace b/BC3D.code-workspace
index a4f1757..362d592 100644
--- a/BC3D.code-workspace
+++ b/BC3D.code-workspace
@@ -30,7 +30,7 @@
"titleBar.activeBackground": "#3B3485",
"titleBar.activeForeground": "#FCFCFE"
},
- "EIDE.OpenOCD.ExePath": "D:/Program Files (x86)/at32_OpenOCD_V2.0.2/bin/openocd.exe",
+ "EIDE.OpenOCD.ExePath": "C:/toolchains/openocd-arterytek/bin/openocd.exe",
"cortex-debug.variableUseNaturalFormat": true
}
}
\ No newline at end of file
diff --git a/app/by_stepper.c b/app/by_stepper.c
index 7244fa9..2d0eb7f 100644
--- a/app/by_stepper.c
+++ b/app/by_stepper.c
@@ -1,41 +1,166 @@
#include "by_stepper.h"
+#include
#include
#include
#include "by_debug.h"
+#define GEAR_INDEXING_DIAMETER (16.0f) // 齿轮分度圆直径
+#define GEAR_MODULUS (2.0f) // 齿轮模数
+#define ENCODER_PULSE_PER_CIRCLE (2048.0f) // 编码器每圈脉冲数
+#define MILLIMETER_PER_CIRCLE (GEAR_INDEXING_DIAMETER * GEAR_MODULUS) // 齿轮每圈行走长度
+#define ENCODER_PULSE_PER_MILLIMETER (ENCODER_PULSE_PER_CIRCLE / MILLIMETER_PER_CIRCLE) // 编码器每毫米脉冲数
+#define STEPPER_STEP_ANGLE (1.8f) // 步进角度
+#define DRIVER_PULSE_PER_STEP (16.0f) // 驱动器细分
+#define DRIVER_PULSE_PER_CIRCLE (360.0f / STEPPER_STEP_ANGLE * DRIVER_PULSE_PER_STEP) // 驱动器每圈脉冲数
+#define DRIVER_PULSE_PER_MILLIMETER (DRIVER_PULSE_PER_CIRCLE / MILLIMETER_PER_CIRCLE) // 驱动器每毫米脉冲数
+
+#define ENCODER_ERROR_THRESHOLD (20)
+
+int64_t position = 0;
+int64_t position_aim = 0;
+int64_t position_offset = 0;
+
+uint8_t running_flag = 0;
+
// TODO 是否增加一个动作列表?一般都比较简单吧
struct by_stepper_t {
- uint8_t dir;
- stepper_speed_t speed;
+ uint8_t dir;
+ stepper_speed_t speed;
};
struct by_stepper_t by_stepper;
-void by_stepper_init(void)
+static int64_t abs_s64(int64_t x)
{
- memset(&by_stepper, 0x00, sizeof(by_stepper));
+ return x > 0 ? x : -x;
}
void by_stepper_set_dir(uint8_t dir)
{
- by_stepper.dir = dir;
+ by_stepper.dir = dir;
}
void by_stepper_set_speed(stepper_speed_t speed)
{
- by_stepper.speed = speed;
+ by_stepper.speed = speed;
}
void by_stepper_run(void)
{
- // 根据预设条件发送脉冲
+ // 根据预设条件发送脉冲
+ gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
+ gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
+ DWT_Delay(40U * (uint16_t)by_stepper.speed);
+}
+
+void by_stepper_stop(uint8_t hold)
+{
+ gpio_bits_write(GPIOA, GPIO_PINS_9, hold ? FALSE : TRUE); // EN
+
+ gpio_bits_write(GPIOA, GPIO_PINS_8, FALSE); // DIR
+ gpio_bits_write(GPIOB, GPIO_PINS_15, FALSE); // CLK
+}
+
+void by_stepper_set_position_millimeter(float distance)
+{
+ if (!running_flag) {
+ position_aim = (int64_t)(distance * ENCODER_PULSE_PER_MILLIMETER);
+ position_offset = position_aim - position;
+ running_flag = 1;
+ }
+}
+
+void by_stepper_add_position_millimeter(float distance)
+{
+ if (!running_flag) {
+ position_aim = position + (int64_t)(distance * ENCODER_PULSE_PER_MILLIMETER);
+ position_offset = position_aim - position;
+ running_flag = 1;
+ }
+}
+
+void by_stepper_init(void)
+{
+ uint32_t slow_start_cnt = 30000;
+ LOGD("by_stepper init...");
+
+ memset(&by_stepper, 0x00, sizeof(by_stepper));
+
+ gpio_bits_write(GPIOB, GPIO_PINS_12, TRUE); // MODE2
+ gpio_bits_write(GPIOB, GPIO_PINS_13, FALSE); // MODE1
+ gpio_bits_write(GPIOB, GPIO_PINS_14, FALSE); // MODE0
+ gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
+ gpio_bits_write(GPIOA, GPIO_PINS_8, TRUE); // DIR
+ gpio_bits_write(GPIOB, GPIO_PINS_15, FALSE); // CLK
+
+ by_stepper_set_dir(0);
+ by_stepper_set_speed(STEPPER_SPEED_DIV2);
+
+ while (gpio_input_data_bit_read(GPIOB, GPIO_PINS_10) == SET && slow_start_cnt--) {
gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
DWT_Delay(40U * (uint16_t)by_stepper.speed);
+ }
+
+ by_stepper_set_speed(STEPPER_SPEED_DIV1);
+
+ while (gpio_input_data_bit_read(GPIOB, GPIO_PINS_10) == SET) {
+ gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
+ gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
+ DWT_Delay(40U * (uint16_t)by_stepper.speed);
+ }
+
+ position = 0; // 位置归零
+ tmr_counter_value_set(TMR3, 0);
+
+ LOGD("by_stepper init ok");
}
-void by_stepper_stop(void)
+void by_stepper_loop(void)
{
+ int16_t temp = (int16_t)tmr_counter_value_get(TMR3);
+ position += (int64_t)temp;
+ tmr_counter_value_set(TMR3, 0);
+
+ if (running_flag) {
+ if (position_offset > 0) {
+ by_stepper_set_dir(0);
+ by_stepper_run();
+ } else if (position_offset < 0) {
+ by_stepper_set_dir(1);
+ by_stepper_run();
+ }
+
+ // 当定位误差小于阈值时,停止运动。否则重新计算定位误差
+ if (abs_s64(position_aim - position) < ENCODER_ERROR_THRESHOLD) {
+ running_flag = 0;
+ position_offset = 0;
+ } else {
+ position_offset = position_aim - position;
+ }
+ } else {
+ by_stepper_stop(0);
+ }
+
+ // if (position_offset) {
+ // if (position_offset > 0) {
+ // by_stepper_set_dir(0);
+ // by_stepper_run();
+ // position_offset -= 1;
+ // } else if (position_offset++ < 0) {
+ // by_stepper_set_dir(1);
+ // by_stepper_run();
+ // position_offset += 1;
+ // }
+ // } else {
+ // by_stepper_stop(0);
+ // }
+}
+
+void by_stpepper_int(void)
+{
+ // position += (int16_t)(tmr_counter_value_get(TMR3));
+ // tmr_counter_value_set(TMR3, 0);
}
\ No newline at end of file
diff --git a/app/by_stepper.h b/app/by_stepper.h
index 8b20976..ea9dd1b 100644
--- a/app/by_stepper.h
+++ b/app/by_stepper.h
@@ -1,10 +1,29 @@
+#ifndef _BY_STEPPER_H__
+#define _BY_STEPPER_H__
+
#include "at32f413.h"
typedef enum stepper_speed_t {
- STEPPER_SPEED_DIV0 = 0,
- STEPPER_SPEED_DIV2 = 2,
- STEPPER_SPEED_DIV4 = 4,
- STEPPER_SPEED_DIV8 = 8,
- STEPPER_SPEED_DIV16 = 16,
- STEPPER_SPEED_DIV32 = 32
-} stepper_speed_t;
\ No newline at end of file
+ STEPPER_SPEED_DIV1 = 1,
+ STEPPER_SPEED_DIV2 = 2,
+ STEPPER_SPEED_DIV4 = 4,
+ STEPPER_SPEED_DIV8 = 8,
+ STEPPER_SPEED_DIV16 = 16,
+ STEPPER_SPEED_DIV32 = 32
+} stepper_speed_t;
+
+extern void by_stepper_set_dir(uint8_t dir);
+extern void by_stepper_set_speed(stepper_speed_t speed);
+extern void by_stepper_init(void);
+extern void by_stepper_run(void);
+extern void by_stepper_stop(uint8_t hold);
+extern void by_stepper_set_position_millimeter(float distance);
+extern void by_stepper_add_position_millimeter(float distance);
+extern void by_stepper_loop(void);
+extern void by_stpepper_int(void);
+
+extern int64_t position;
+extern int64_t position_aim;
+extern int64_t position_offset;
+
+#endif
\ No newline at end of file
diff --git a/project/inc/at32f413_int.h b/project/inc/at32f413_int.h
index cac4c27..9e3e1f5 100644
--- a/project/inc/at32f413_int.h
+++ b/project/inc/at32f413_int.h
@@ -65,6 +65,7 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
+void TMR4_GLOBAL_IRQHandler(void);
/* add user code begin exported functions */
/* add user code end exported functions */
diff --git a/project/inc/at32f413_wk_config.h b/project/inc/at32f413_wk_config.h
index f35a28d..4f00297 100644
--- a/project/inc/at32f413_wk_config.h
+++ b/project/inc/at32f413_wk_config.h
@@ -55,6 +55,65 @@ extern "C" {
/* add user code end exported macro */
+/* add user code begin dma define */
+/* user can only modify the dma define value */
+//#define DMA1_CHANNEL1_BUFFER_SIZE 0
+//#define DMA1_CHANNEL1_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL1_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL2_BUFFER_SIZE 0
+//#define DMA1_CHANNEL2_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL2_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL3_BUFFER_SIZE 0
+//#define DMA1_CHANNEL3_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL3_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL4_BUFFER_SIZE 0
+//#define DMA1_CHANNEL4_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL4_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL5_BUFFER_SIZE 0
+//#define DMA1_CHANNEL5_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL5_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL6_BUFFER_SIZE 0
+//#define DMA1_CHANNEL6_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL6_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA1_CHANNEL7_BUFFER_SIZE 0
+//#define DMA1_CHANNEL7_MEMORY_BASE_ADDR 0
+//#define DMA1_CHANNEL7_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL1_BUFFER_SIZE 0
+//#define DMA2_CHANNEL1_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL1_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL2_BUFFER_SIZE 0
+//#define DMA2_CHANNEL2_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL2_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL3_BUFFER_SIZE 0
+//#define DMA2_CHANNEL3_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL3_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL4_BUFFER_SIZE 0
+//#define DMA2_CHANNEL4_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL4_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL5_BUFFER_SIZE 0
+//#define DMA2_CHANNEL5_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL5_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL6_BUFFER_SIZE 0
+//#define DMA2_CHANNEL6_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL6_PERIPHERAL_BASE_ADDR 0
+
+//#define DMA2_CHANNEL7_BUFFER_SIZE 0
+//#define DMA2_CHANNEL7_MEMORY_BASE_ADDR 0
+//#define DMA2_CHANNEL7_PERIPHERAL_BASE_ADDR 0
+/* add user code end dma define */
+
/* Private defines -------------------------------------------------------------*/
#define MODE2_PIN GPIO_PINS_12
#define MODE2_GPIO_PORT GPIOB
@@ -94,12 +153,12 @@ extern "C" {
/* init usart2 function. */
void wk_usart2_init(void);
- /* init tmr1 function. */
- void wk_tmr1_init(void);
-
/* init tmr3 function. */
void wk_tmr3_init(void);
+ /* init tmr4 function. */
+ void wk_tmr4_init(void);
+
/* init tmr10 function. */
void wk_tmr10_init(void);
diff --git a/project/src/at32f413_int.c b/project/src/at32f413_int.c
index fefe0e3..3f72b76 100644
--- a/project/src/at32f413_int.c
+++ b/project/src/at32f413_int.c
@@ -29,7 +29,8 @@
/* private includes ----------------------------------------------------------*/
/* add user code begin private includes */
-
+#include "by_debug.h"
+#include "by_stepper.h"
/* add user code end private includes */
/* private typedef -----------------------------------------------------------*/
@@ -204,6 +205,25 @@ void PendSV_Handler(void)
/* add user code end PendSV_IRQ 1 */
}
+/**
+ * @brief this function handles TMR4 handler.
+ * @param none
+ * @retval none
+ */
+void TMR4_GLOBAL_IRQHandler(void)
+{
+ /* add user code begin TMR4_GLOBAL_IRQ 0 */
+ if(SET == tmr_interrupt_flag_get(TMR4, TMR_OVF_FLAG)){
+ by_stpepper_int();
+ tmr_flag_clear(TMR4, TMR_OVF_FLAG);
+ }
+
+ /* add user code end TMR4_GLOBAL_IRQ 0 */
+ /* add user code begin TMR4_GLOBAL_IRQ 1 */
+
+ /* add user code end TMR4_GLOBAL_IRQ 1 */
+}
+
/* add user code begin 1 */
/* add user code end 1 */
diff --git a/project/src/at32f413_wk_config.c b/project/src/at32f413_wk_config.c
index a9f8e48..9169021 100644
--- a/project/src/at32f413_wk_config.c
+++ b/project/src/at32f413_wk_config.c
@@ -165,15 +165,15 @@ void wk_periph_clock_config(void)
/* enable gpiod periph clock */
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
- /* enable tmr1 periph clock */
- crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
-
/* enable tmr10 periph clock */
crm_periph_clock_enable(CRM_TMR10_PERIPH_CLOCK, TRUE);
/* enable tmr3 periph clock */
crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
+ /* enable tmr4 periph clock */
+ crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, TRUE);
+
/* enable usart2 periph clock */
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
@@ -200,6 +200,8 @@ void wk_debug_config(void)
void wk_nvic_config(void)
{
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
+
+ nvic_irq_enable(TMR4_GLOBAL_IRQn, 0, 0);
}
/**
@@ -284,7 +286,7 @@ void wk_exint_config(void)
exint_init(&exint_init_struct);
/* add user code begin exint_config 2 */
-
+ exint_interrupt_enable(EXINT_LINE_5, TRUE);
/* add user code end exint_config 2 */
}
@@ -337,40 +339,6 @@ void wk_usart2_init(void)
/* add user code end usart2_init 2 */
}
-/**
- * @brief init tmr1 function.
- * @param none
- * @retval none
- */
-void wk_tmr1_init(void)
-{
- /* add user code begin tmr1_init 0 */
-
- /* add user code end tmr1_init 0 */
-
-
- /* add user code begin tmr1_init 1 */
-
- /* add user code end tmr1_init 1 */
-
- /* configure counter settings */
- tmr_base_init(TMR1, 65535, 0);
- tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
- tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);
- tmr_repetition_counter_set(TMR1, 0);
- tmr_period_buffer_enable(TMR1, FALSE);
-
- /* configure primary mode settings */
- tmr_sub_sync_mode_set(TMR1, FALSE);
- tmr_primary_mode_select(TMR1, TMR_PRIMARY_SEL_RESET);
-
- tmr_counter_enable(TMR1, TRUE);
-
- /* add user code begin tmr1_init 2 */
-
- /* add user code end tmr1_init 2 */
-}
-
/**
* @brief init tmr3 function.
* @param none
@@ -439,6 +407,47 @@ void wk_tmr3_init(void)
/* add user code end tmr3_init 2 */
}
+/**
+ * @brief init tmr4 function.
+ * @param none
+ * @retval none
+ */
+void wk_tmr4_init(void)
+{
+ /* add user code begin tmr4_init 0 */
+
+ /* add user code end tmr4_init 0 */
+
+
+ /* add user code begin tmr4_init 1 */
+
+ /* add user code end tmr4_init 1 */
+
+ /* configure counter settings */
+ tmr_base_init(TMR4, 9999, 1999);
+ tmr_cnt_dir_set(TMR4, TMR_COUNT_UP);
+ tmr_clock_source_div_set(TMR4, TMR_CLOCK_DIV1);
+ tmr_period_buffer_enable(TMR4, FALSE);
+
+ /* configure primary mode settings */
+ tmr_sub_sync_mode_set(TMR4, FALSE);
+ tmr_primary_mode_select(TMR4, TMR_PRIMARY_SEL_RESET);
+
+ tmr_counter_enable(TMR4, TRUE);
+
+ /**
+ * Users need to configure TMR4 interrupt functions according to the actual application.
+ * 1. Call the below function to enable the corresponding TMR4 interrupt.
+ * --tmr_interrupt_enable(...)
+ * 2. Add the user's interrupt handler code into the below function in the at32f413_int.c file.
+ * --void TMR4_GLOBAL_IRQHandler(void)
+ */
+
+ /* add user code begin tmr4_init 2 */
+ tmr_interrupt_enable(TMR4, TMR_OVF_INT, TRUE);
+ /* add user code end tmr4_init 2 */
+}
+
/**
* @brief init tmr10 function.
* @param none
diff --git a/project/src/main.c b/project/src/main.c
index 6dbd982..637e0d5 100644
--- a/project/src/main.c
+++ b/project/src/main.c
@@ -33,6 +33,7 @@
#include "by_debug.h"
#include "by_can.h"
+#include "by_stepper.h"
/* add user code end private includes */
/* private typedef -----------------------------------------------------------*/
@@ -66,15 +67,15 @@
/* add user code end 0 */
/**
- * @brief main function.
- * @param none
- * @retval none
- */
+ * @brief main function.
+ * @param none
+ * @retval none
+ */
int main(void)
{
/* add user code begin 1 */
- by_debug_init();
- /* add user code end 1 */
+ by_debug_init();
+ /* add user code end 1 */
/* system clock config. */
wk_system_clock_config();
@@ -94,12 +95,12 @@ int main(void)
/* init exint function. */
wk_exint_config();
- /* init tmr1 function. */
- wk_tmr1_init();
-
/* init tmr3 function. */
wk_tmr3_init();
+ /* init tmr4 function. */
+ wk_tmr4_init();
+
/* init tmr10 function. */
wk_tmr10_init();
@@ -110,22 +111,14 @@ int main(void)
wk_gpio_config();
/* add user code begin 2 */
- DWT_Init();
+ DWT_Init();
+ by_stepper_init();
- LOGD("hello world");
+ /* add user code end 2 */
- gpio_bits_write(GPIOB, GPIO_PINS_12, FALSE); // MODE2
- gpio_bits_write(GPIOB, GPIO_PINS_13, TRUE); // MODE1
- gpio_bits_write(GPIOB, GPIO_PINS_14, TRUE); // MODE0
- gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
- gpio_bits_write(GPIOA, GPIO_PINS_8, TRUE); // DIR
- gpio_bits_write(GPIOB, GPIO_PINS_15, TRUE); // CLK
- /* add user code end 2 */
-
- while(1)
- {
+ while (1) {
/* add user code begin 3 */
- DWT_Delay(40);
- /* add user code end 3 */
+ by_stepper_loop();
+ /* add user code end 3 */
}
}