add(actuator):添加推杆的驱动函数已经验证OK。

This commit is contained in:
2026-07-28 15:28:30 +08:00
parent cb720da01f
commit 6e3290c70e
6 changed files with 197 additions and 35 deletions
+2 -1
View File
@@ -34,8 +34,9 @@ set(TARGET_SRC
Src/led.c
Src/uart_ring_buffer.c
Src/command.c
Src/i2c.c
# Src/i2c.c
Src/board_config.c
Src/actuator.c
)
# 设置输出目录
+12
View File
@@ -0,0 +1,12 @@
#ifndef ACTUATOR_H
#define ACTUATOR_H
#include "board_config.h"
#include "gd32e23x.h"
#include "stdbool.h"
void actuator_init(void);
void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_direction_t direction);
#endif // ACTUATOR_H
+54 -17
View File
@@ -1,12 +1,15 @@
#ifndef BOARD_CONFIG_H
#define BOARD_CONFIG_H
#ifndef DISABLE
#define DISABLE 0
#include "gd32e23x.h"
#include "stdbool.h"
#ifndef CFG_DISABLE
#define CFG_DISABLE 0
#endif
#ifndef ENABLE
#define ENABLE 1
#ifndef CFG_ENABLE
#define CFG_ENABLE 1
#endif
#define GD32E23XF4 0x10
@@ -19,25 +22,25 @@
/* >>>>>>>>>>>>>>>>>>>>[IIC TYPE DEFINE]<<<<<<<<<<<<<<<<<<<< */
#define SOFTWARE_IIC DISABLE // DISABLE: Hardware IIC; ENABLE: Software IIC
#define SOFTWARE_IIC CFG_DISABLE // CFG_DISABLE: Hardware IIC; CFG_ENABLE: Software IIC
/* >>>>>>>>>>>>>>>>>>>>[DEBUG MODE]<<<<<<<<<<<<<<<<<<<< */
#define DEBUG_MODE DISABLE // DISABLE: Release Mode; ENABLE: Debug Mode
#define DEBUG_MODE CFG_DISABLE // CFG_DISABLE: Release Mode; CFG_ENABLE: Debug Mode
/* >>>>>>>>>>>>>>>>>>>>[COMMAND DEBUG]<<<<<<<<<<<<<<<<<<<< */
#define COM_DEBUG DISABLE // DISABLE: Command debug off; ENABLE: Command debug on
#define COM_DEBUG CFG_DISABLE // CFG_DISABLE: Command debug off; CFG_ENABLE: Command debug on
/* >>>>>>>>>>>>>>>>>>>>[DEBUG ASSERTIONS DEFINE]<<<<<<<<<<<<<<<<<<<< */
#define DEBUG_VERBOSE DISABLE // DISABLE: Verbose debug off; ENABLE: Verbose debug on
#define DEBUG_VERBOSE CFG_DISABLE // CFG_DISABLE: Verbose debug off; CFG_ENABLE: Verbose debug on
/* >>>>>>>>>>>>>>>>>>>>[SEGGER RTT DETECTION]<<<<<<<<<<<<<<<<<<<< */
#define SEGGER_RTT_DETECTION ENABLE // DISABLE: SEGGER RTT off; ENABLE: SEGGER RTT on
#define SEGGER_RTT_DETECTION CFG_ENABLE // CFG_DISABLE: SEGGER RTT off; CFG_ENABLE: SEGGER RTT on
#if SEGGER_RTT_DETECTION == ENABLE
#if SEGGER_RTT_DETECTION == CFG_ENABLE
#include "SEGGER_RTT.h"
#define RTT_printf(ch, ...) SEGGER_RTT_printf(ch, __VA_ARGS__)
#define RTT_WriteString(ch, s) SEGGER_RTT_WriteString(ch, s)
@@ -67,13 +70,13 @@ void usart1_irq_handler(void);
/******************************************************************************/
#define RCU_GPIO_I2C RCU_GPIOF
#define RCU_I2C RCU_I2C0
#define I2C_SCL_PORT GPIOF
#define I2C_SCL_PIN GPIO_PIN_1
#define I2C_SDA_PORT GPIOF
#define I2C_SDA_PIN GPIO_PIN_0
#define I2C_GPIO_AF GPIO_AF_1
// #define RCU_GPIO_I2C RCU_GPIOF
// #define RCU_I2C RCU_I2C0
// #define I2C_SCL_PORT GPIOF
// #define I2C_SCL_PIN GPIO_PIN_1
// #define I2C_SDA_PORT GPIOF
// #define I2C_SDA_PIN GPIO_PIN_0
// #define I2C_GPIO_AF GPIO_AF_1
/******************************************************************************/
@@ -83,6 +86,40 @@ void usart1_irq_handler(void);
/******************************************************************************/
typedef enum {
ACTUATOR_CH1 = 0,
ACTUATOR_CH2
} actuator_channel_t;
typedef enum {
DIRECTION_PUSH = 0, // 推动方向
DIRECTION_PULL // 拉动方向
} actuator_direction_t;
/******************************************************************************/
#define ACTUATOR_CH1_PWM_RCU RCU_GPIOA
#define ACTUATOR_CH1_PWM_PORT GPIOA
#define ACTUATOR_CH1_PWM_PIN GPIO_PIN_10
#define ACTUATOR_CH1_GPIO_RCU RCU_GPIOF
#define ACTUATOR_CH1_GPIO_PORT GPIOF
#define ACTUATOR_CH1_GPIO_PIN GPIO_PIN_0
#define ACTUATOR_CH2_PWM_RCU RCU_GPIOA
#define ACTUATOR_CH2_PWM_PORT GPIOA
#define ACTUATOR_CH2_PWM_PIN GPIO_PIN_9
#define ACTUATOR_CH2_GPIO_RCU RCU_GPIOF
#define ACTUATOR_CH2_GPIO_PORT GPIOF
#define ACTUATOR_CH2_GPIO_PIN GPIO_PIN_1
#define ACTUATOR_PWM_TIMER_RCU RCU_TIMER0
#define ACTUATOR_PWM_TIMER TIMER0
#define ACTUATOR_CH1_PWM_TIMER_CH TIMER_CH_2
#define ACTUATOR_CH2_PWM_TIMER_CH TIMER_CH_1
/******************************************************************************/
#define UART_RCU (g_usart_config.rcu_usart)
#define UART_PHY (g_usart_config.usart_periph)
#define UART_IRQ (g_usart_config.irq_type)
+106
View File
@@ -0,0 +1,106 @@
#include "actuator.h"
void actuator_init(void) {
// Initialize PWM pins for actuators
rcu_periph_clock_enable(ACTUATOR_CH1_PWM_RCU);
rcu_periph_clock_enable(ACTUATOR_CH2_PWM_RCU);
rcu_periph_clock_enable(ACTUATOR_CH1_GPIO_RCU);
rcu_periph_clock_enable(ACTUATOR_CH2_GPIO_RCU);
// rcu_periph_clock_enable(PWM3_RCU);
// rcu_periph_clock_enable(PWM4_RCU);
rcu_periph_clock_enable(ACTUATOR_PWM_TIMER_RCU); // Enable clock for TIMER0
gpio_mode_set(ACTUATOR_CH1_PWM_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ACTUATOR_CH1_PWM_PIN);
gpio_output_options_set(ACTUATOR_CH1_PWM_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH1_PWM_PIN);
gpio_af_set(ACTUATOR_CH1_PWM_PORT, GPIO_AF_2, ACTUATOR_CH1_PWM_PIN);
gpio_mode_set(ACTUATOR_CH2_PWM_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, ACTUATOR_CH2_PWM_PIN);
gpio_output_options_set(ACTUATOR_CH2_PWM_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH2_PWM_PIN);
gpio_af_set(ACTUATOR_CH2_PWM_PORT, GPIO_AF_2, ACTUATOR_CH2_PWM_PIN);
gpio_mode_set(ACTUATOR_CH1_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ACTUATOR_CH1_GPIO_PIN);
gpio_output_options_set(ACTUATOR_CH1_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH1_GPIO_PIN);
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set initial state to LOW
gpio_mode_set(ACTUATOR_CH2_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ACTUATOR_CH2_GPIO_PIN);
gpio_output_options_set(ACTUATOR_CH2_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ACTUATOR_CH2_GPIO_PIN);
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set initial state to LOW
// Additional actuator initialization code can be added here
// HSI = 72MHz , Freq Timer = 72MHz / (Prescaler + 1) / (Period + 1)
timer_deinit(ACTUATOR_PWM_TIMER);
timer_parameter_struct timer_initpara;
timer_initpara.prescaler = 2; // 72MHz / (2+1) = 24MHz
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 999; // 24MHz / (999 + 1) = 24kHz
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(ACTUATOR_PWM_TIMER, &timer_initpara);
timer_oc_parameter_struct timer_ocinitpara;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
// CH0
timer_channel_output_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, &timer_ocinitpara);
timer_channel_output_mode_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 0);
// CH1
timer_channel_output_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, &timer_ocinitpara);
timer_channel_output_mode_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, TIMER_OC_SHADOW_ENABLE);
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 0);
timer_auto_reload_shadow_enable(ACTUATOR_PWM_TIMER);
timer_primary_output_config(ACTUATOR_PWM_TIMER, ENABLE);
timer_enable(ACTUATOR_PWM_TIMER);
}
void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_direction_t direction) {
if (duty > 999) duty = 999; // Limit duty cycle to max value
if (direction != DIRECTION_PUSH && direction != DIRECTION_PULL) {
// Invalid direction, handle error if necessary
return;
}
// Set PWM output for the specified actuator channel
// This is a placeholder; actual implementation will depend on the PWM configuration
// For example, setting the duty cycle to a specific value to activate the actuator
if (channel == ACTUATOR_CH1) {
if (direction == DIRECTION_PUSH) {
SEGGER_RTT_printf(0, "Actuator CH1 PUSH with duty %d\n", duty);
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction LOW
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, duty);
} else if (direction == DIRECTION_PULL) {
SEGGER_RTT_printf(0, "Actuator CH1 PULL with duty %d\n", duty);
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction HIGH
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, (999 - duty));
}
} else if (channel == ACTUATOR_CH2) {
if (direction == DIRECTION_PUSH) {
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction LOW
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, duty);
} else if (direction == DIRECTION_PULL) {
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction HIGH
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, (999 - duty));
}
} else {
// Invalid channel, handle error if necessary
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 0); // Ensure CH1 is off
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 0); // Ensure CH2 is off
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
}
}
+12 -11
View File
@@ -21,6 +21,7 @@
#include "gd32e23x_usart.h"
#include "i2c.h"
#include "core_cm23.h"
#include "actuator.h"
/* ============================================================================
* 协议格式说明
@@ -67,15 +68,15 @@
/** @name 响应帧标识符
* @{ */
#define RESP_HEADER 0xB5 /**< 响应帧包头标识 >**/
#define RESP_TYPE_OK 0xF0 /**< 成功响应类型 >**/
#define RESP_TYPE_CRC_ERR 0xF1 /**< CRC校验错误 >**/
#define RESP_TYPE_HEADER_ERR 0xF2 /**< 包头错误 >**/
#define RESP_TYPE_TYPE_ERR 0xF3 /**< 板类型错误 >**/
#define RESP_TYPE_LEN_ERR 0xF4 /**< 长度错误 >**/
#define RESP_TYPE_PARAM_ERR 0xFD /**< 参数错误 >**/
#define RESP_TYPE_CMD_ERR 0xFE /**< 命令错误 >**/
#define RESP_TYPE_ERR 0xFF /**< 通用错误 >**/
#define RESP_HEADER 0xB5 /**< 响应帧包头标识 */
#define RESP_TYPE_OK 0xF0 /**< 成功响应类型 */
#define RESP_TYPE_CRC_ERR 0xF1 /**< CRC校验错误 */
#define RESP_TYPE_HEADER_ERR 0xF2 /**< 包头错误 */
#define RESP_TYPE_TYPE_ERR 0xF3 /**< 板类型错误 */
#define RESP_TYPE_LEN_ERR 0xF4 /**< 长度错误 */
#define RESP_TYPE_PARAM_ERR 0xFD /**< 参数错误 */
#define RESP_TYPE_CMD_ERR 0xFE /**< 命令错误 */
#define RESP_TYPE_ERR 0xFF /**< 通用错误 */
/** @} */
/* ============================================================================
@@ -101,7 +102,7 @@ void system_software_reset(void)
}
/* Debug output control */
#if COM_DEBUG == ENABLE
#if COM_DEBUG == CFG_ENABLE
#include <stdio.h>
#define COMMAND_DEBUG(fmt, ...) printf("[COMMAND] " fmt "\n", ##__VA_ARGS__)
#else
@@ -565,7 +566,7 @@ void command_process(void) {
// 到帧尾,进行各项校验
bool verification_status = true;
#if DEBUG_VERBOSE == ENABLE
#if DEBUG_VERBOSE == CFG_ENABLE
if (cmd_buf[0] != PROTOCOL_PACKAGE_HEADER) {
send_response(RESP_TYPE_HEADER_ERR, s_report_status_err, sizeof(s_report_status_err));
verification_status = false;
+11 -6
View File
@@ -41,6 +41,7 @@ OF SUCH DAMAGE.
#include <stdio.h>
#include "i2c.h"
#include "board_config.h"
#include "actuator.h"
/*!
\brief main function
@@ -60,20 +61,24 @@ int main(void)
uart_ring_buffer_init();
uart_init();
i2c_config();
actuator_init();
#if DEBUG_MODE == ENABLE
// actuator_output(ACTUATOR_CH1, 800, DIRECTION_PULL); // Set actuator channel 1 to high, channel 2 to low
// i2c_config();
#if DEBUG_MODE == CFG_ENABLE
printf("Hello World!\r\n");
#endif
#if SEGGER_RTT_DETECTION == ENABLE
#if SEGGER_RTT_DETECTION == CFG_ENABLE
RTT_printf(0, "Hello World!\r\n");
#endif
#if DEBUG_VERBOSE == ENABLE
i2c_scan();
#if DEBUG_VERBOSE == CFG_ENABLE
// i2c_scan();
i2c_bus_reset();
// i2c_bus_reset();
#endif
/* ========== Command Testing ========== */