Compare commits

...
3 Commits
6 changed files with 63 additions and 11 deletions
+2
View File
@@ -9,4 +9,6 @@ void actuator_init(void);
void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_direction_t direction); void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_direction_t direction);
void actuator_stop(actuator_channel_t channel);
#endif // ACTUATOR_H #endif // ACTUATOR_H
+8
View File
@@ -51,6 +51,8 @@
#define RTT_PutChar(ch, c) #define RTT_PutChar(ch, c)
#endif #endif
#define RS485_MODE CFG_ENABLE // CFG_DISABLE: RS485 off; CFG_ENABLE: RS485 on
/******************************************************************************/ /******************************************************************************/
/* Dynamic USART Configuration Structure */ /* Dynamic USART Configuration Structure */
@@ -129,6 +131,12 @@ typedef enum {
#define UART_RX_PIN GPIO_PIN_3 #define UART_RX_PIN GPIO_PIN_3
#define UART_BAUDRATE 115200U #define UART_BAUDRATE 115200U
#if RS485_MODE == CFG_ENABLE
#define RS485_DE_RCU RCU_GPIOA
#define RS485_DE_PORT GPIOA
#define RS485_DE_PIN GPIO_PIN_1
#endif
/******************************************************************************/ /******************************************************************************/
#define DEBUG_UART USART0 #define DEBUG_UART USART0
+23 -2
View File
@@ -80,19 +80,21 @@ void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_directi
// For example, setting the duty cycle to a specific value to activate the actuator // For example, setting the duty cycle to a specific value to activate the actuator
if (channel == ACTUATOR_CH1) { if (channel == ACTUATOR_CH1) {
if (direction == DIRECTION_PUSH) { if (direction == DIRECTION_PUSH) {
SEGGER_RTT_printf(0, "Actuator CH1 PUSH with duty %d\n", duty); SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH1 PUSH with duty %d\n", duty);
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction LOW 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); timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, duty);
} else if (direction == DIRECTION_PULL) { } else if (direction == DIRECTION_PULL) {
SEGGER_RTT_printf(0, "Actuator CH1 PULL with duty %d\n", duty); SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH1 PULL with duty %d\n", duty);
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set direction HIGH 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)); timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, (999 - duty));
} }
} else if (channel == ACTUATOR_CH2) { } else if (channel == ACTUATOR_CH2) {
if (direction == DIRECTION_PUSH) { if (direction == DIRECTION_PUSH) {
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH2 PUSH with duty %d\n", duty);
gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction LOW 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); timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, duty);
} else if (direction == DIRECTION_PULL) { } else if (direction == DIRECTION_PULL) {
SEGGER_RTT_printf(0, "[ACTUATOR] Actuator CH2 PULL with duty %d\n", duty);
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set direction HIGH 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)); timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, (999 - duty));
} }
@@ -103,4 +105,23 @@ void actuator_output(actuator_channel_t channel, uint16_t duty, actuator_directi
gpio_bit_reset(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW 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 gpio_bit_reset(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
} }
}
void actuator_stop(actuator_channel_t channel) {
if(channel == ACTUATOR_CH1) {
SEGGER_RTT_printf(0, "[ACTUATOR] Stopping Actuator CH1\n");
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 999); // Ensure CH1 is off
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
} else if(channel == ACTUATOR_CH2) {
SEGGER_RTT_printf(0, "[ACTUATOR] Stopping Actuator CH2\n");
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 999); // Ensure CH2 is off
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
} else {
// Invalid channel, handle error if necessary
SEGGER_RTT_printf(0, "[ACTUATOR] Invalid channel specified for stop: %d\n", channel);
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH1_PWM_TIMER_CH, 999); // Ensure CH1 is off
timer_channel_output_pulse_value_config(ACTUATOR_PWM_TIMER, ACTUATOR_CH2_PWM_TIMER_CH, 999); // Ensure CH2 is off
gpio_bit_set(ACTUATOR_CH1_GPIO_PORT, ACTUATOR_CH1_GPIO_PIN); // Set CH1 direction LOW
gpio_bit_set(ACTUATOR_CH2_GPIO_PORT, ACTUATOR_CH2_GPIO_PIN); // Set CH2 direction LOW
}
} }
+14 -2
View File
@@ -462,7 +462,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
send_response(RESP_TYPE_PARAM_ERR, s_report_status_err, sizeof(s_report_status_err)); send_response(RESP_TYPE_PARAM_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
COMMAND_DEBUG("M3 Command(PUSH): Actuator Channel=%u, Duty Cycle=%u", p_val, s_val); SEGGER_RTT_printf(0, "[COMMAND] M3 Command(PUSH): Actuator Channel=%u, Duty Cycle=%u \n", p_val, s_val);
actuator_output((actuator_channel_t)p_val, (uint16_t)s_val, DIRECTION_PUSH); actuator_output((actuator_channel_t)p_val, (uint16_t)s_val, DIRECTION_PUSH);
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
} }
@@ -484,12 +484,24 @@ void handle_command(const uint8_t *frame, uint8_t len) {
send_response(RESP_TYPE_PARAM_ERR, s_report_status_err, sizeof(s_report_status_err)); send_response(RESP_TYPE_PARAM_ERR, s_report_status_err, sizeof(s_report_status_err));
return; return;
} }
COMMAND_DEBUG("M4 Command(PULL): Actuator Channel=%u, Duty Cycle=%u", p_val, s_val); SEGGER_RTT_printf(0, "[COMMAND] M4 Command(PULL): Actuator Channel=%u, Duty Cycle=%u \n", p_val, s_val);
actuator_output((actuator_channel_t)p_val, (uint16_t)s_val, DIRECTION_PULL); actuator_output((actuator_channel_t)p_val, (uint16_t)s_val, DIRECTION_PULL);
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
} }
return; return;
case 5u: // M5 stop actuator output
uint32_t p_val = 0;
bool has_p = find_parameter_value(cmd, cmd_len, 'P', &p_val);
if (!has_p || p_val > (uint32_t)ACTUATOR_CH2) {
send_response(RESP_TYPE_PARAM_ERR, s_report_status_err, sizeof(s_report_status_err));
return;
}
SEGGER_RTT_printf(0, "[COMMAND] M5 Command(STOP): Actuator Channel=%u \n", p_val);
actuator_stop((actuator_channel_t)p_val);
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
return;
/* ========================================== /* ==========================================
* M888 软件重启命令 * M888 软件重启命令
* ========================================== */ * ========================================== */
+1 -7
View File
@@ -53,9 +53,6 @@ int main(void)
{ {
led_init(); led_init();
mcu_detect_and_config(); mcu_detect_and_config();
// delay_ms(1000);
systick_config(); systick_config();
uart_ring_buffer_init(); uart_ring_buffer_init();
@@ -63,10 +60,6 @@ int main(void)
actuator_init(); actuator_init();
// actuator_output(ACTUATOR_CH1, 800, DIRECTION_PULL); // Set actuator channel 1 to high, channel 2 to low
// i2c_config();
#if DEBUG_MODE == CFG_ENABLE #if DEBUG_MODE == CFG_ENABLE
printf("Hello World!\r\n"); printf("Hello World!\r\n");
#endif #endif
@@ -82,6 +75,7 @@ int main(void)
#endif #endif
/* ========== Command Testing ========== */ /* ========== Command Testing ========== */
// command_execute("M3P0S999");
/* ========== */ /* ========== */
+15
View File
@@ -17,6 +17,14 @@ void uart_init(void) {
gpio_mode_set(UART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART_TX_PIN | UART_RX_PIN); gpio_mode_set(UART_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, UART_TX_PIN | UART_RX_PIN);
gpio_output_options_set(UART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART_TX_PIN | UART_RX_PIN); gpio_output_options_set(UART_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, UART_TX_PIN | UART_RX_PIN);
#if RS485_MODE == CFG_ENABLE
/* 配置 RS485 DE 引脚 */
rcu_periph_clock_enable(RS485_DE_RCU);
gpio_mode_set(RS485_DE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_DE_PIN);
gpio_output_options_set(RS485_DE_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_DE_PIN);
gpio_bit_reset(RS485_DE_PORT, RS485_DE_PIN); // 初始状态为接收模式
#endif
/* 配置波特率、数据位、停止位等 */ /* 配置波特率、数据位、停止位等 */
usart_deinit(UART_PHY); usart_deinit(UART_PHY);
usart_word_length_set(UART_PHY, USART_WL_8BIT); usart_word_length_set(UART_PHY, USART_WL_8BIT);
@@ -26,6 +34,13 @@ void uart_init(void) {
usart_receive_config(UART_PHY, USART_RECEIVE_ENABLE); usart_receive_config(UART_PHY, USART_RECEIVE_ENABLE);
usart_transmit_config(UART_PHY, USART_TRANSMIT_ENABLE); usart_transmit_config(UART_PHY, USART_TRANSMIT_ENABLE);
#if RS485_MODE == CFG_ENABLE
// 配置 RS485 模式
usart_rs485_driver_enable(UART_PHY);
usart_driver_assertime_config(UART_PHY, 10); // 设置驱动器断言时间为 10 个时钟周期
usart_driver_deassertime_config(UART_PHY, 10); // 设置驱动器去断言时间为 10 个时钟周期
#endif
usart_enable(UART_PHY); usart_enable(UART_PHY);
nvic_irq_enable(UART_IRQ, 0); nvic_irq_enable(UART_IRQ, 0);