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 */ } }