diff --git a/CMakeLists.txt b/CMakeLists.txt index 55f7253..dc5036d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ set(TARGET_SRC Src/uart_ring_buffer.c Src/command.c Src/i2c.c + Src/ultrasonic_analog.c ) # 设置输出目录 diff --git a/Inc/board_config.h b/Inc/board_config.h index 5b43610..47b3c6e 100644 --- a/Inc/board_config.h +++ b/Inc/board_config.h @@ -8,19 +8,14 @@ /* >>>>>>>>>>>>>>>>>>>>[IIC TYPE DEFINE]<<<<<<<<<<<<<<<<<<<< */ -// #define SOFTWARE_IIC // IIC Type : Software IIC -#undef SOFTWARE_IIC // IIC Type : Hardware IIC +#define POWER_SUPPLY_24V // Powwer Supplu : 24V +// #undef POWER_SUPPLY_24V // Powwer Supplu : 12V /* >>>>>>>>>>>>>>>>>>>>[DEBUG ASSERTIONS DEFINE]<<<<<<<<<<<<<<<<<<<< */ // #define DEBUG_VERBOSE // Debug Assertions Status : Debug Verbose Information #undef DEBUG_VERBOSE // Debug Assertions Status : No Debug Verbose Information -/* >>>>>>>>>>>>>>>>>>>>[EDDY DRIVE CURRENT DETECTION]<<<<<<<<<<<<<<<<<<<< */ - -// #define EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Enable -#undef EDDY_DRIVE_CURRENT_DETECTION // Eddy Drive Current Detection : Disable - /******************************************************************************/ #define RCU_GPIO_I2C RCU_GPIOF @@ -36,7 +31,7 @@ /******************************************************************************/ #define LED_PORT GPIOA -#define LED_PIN GPIO_PIN_7 +#define LED_PIN GPIO_PIN_9 #define LED_RCU RCU_GPIOA /******************************************************************************/ @@ -53,4 +48,40 @@ /******************************************************************************/ +#define US_TX_GPIO_RCU RCU_GPIOB +#define US_TX_GPIO_PORT GPIOB +#define US_TX_GPIO_PIN GPIO_PIN_1 +#define US_TX_GPIO_AF GPIO_AF_0 +#define US_TX_TIMER_RCU RCU_TIMER13 +#define US_TX_TIMER TIMER13 +#define US_TX_TIMER_CH TIMER_CH_0 + +/******************************************************************************/ + +#define US_TX_DELAY_RCU RCU_TIMER15 +#define US_TX_DELAY_TIMER TIMER15 + +/******************************************************************************/ + +#define US_RX_GPIO_RCU RCU_GPIOB +#define US_RX_EXTI_RCU RCU_CFGCMP +#define US_RX_GPIO_PORT GPIOA +#define US_RX_GPIO_PIN GPIO_PIN_0 +#define US_RX_GPIO_EXTI EXTI_0 +#define US_RX_EXTI_LINE EXTI_SOURCE_PIN0 +#define US_RX_EXTI_IRQ EXTI0_1_IRQn + +/******************************************************************************/ + +#define US_ECHO_RCU RCU_TIMER16 +#define US_ECHO_TIMER TIMER16 +#define US_ECHO_CH TIMER_CH_0 + +/******************************************************************************/ + +#define TIME_CORRECTION_US 230U +#define CAPTURE_VALUE_MAX 550U + +/******************************************************************************/ + #endif //BOARD_CONFIG_H diff --git a/Inc/command.h b/Inc/command.h index b9d9c77..d5b56f1 100644 --- a/Inc/command.h +++ b/Inc/command.h @@ -16,6 +16,10 @@ * @{ */ +/** @brief 传感器周期上报使能标志 */ +extern volatile bool g_eddy_current_sensor_report_enabled; +extern volatile bool g_temperature_sensor_report_enabled; + /** * @section Command_Protocol 协议格式 * 接收命令帧格式: diff --git a/Inc/gd32e23x_it.h b/Inc/gd32e23x_it.h index 04a9d99..456385e 100644 --- a/Inc/gd32e23x_it.h +++ b/Inc/gd32e23x_it.h @@ -49,4 +49,8 @@ void PendSV_Handler(void); /* this function handles SysTick exception */ void SysTick_Handler(void); +void TIMER13_IRQHandler(void); + +void USART0_IRQHandler(void); + #endif /* GD32E23X_IT_H */ diff --git a/Inc/ultrasonic_analog.h b/Inc/ultrasonic_analog.h new file mode 100644 index 0000000..ed6af7e --- /dev/null +++ b/Inc/ultrasonic_analog.h @@ -0,0 +1,31 @@ +#ifndef ULTRASONIC_ANALOG_H +#define ULTRASONIC_ANALOG_H + +#include +#include + +extern volatile bool g_ultrasonic_measure_done; + +/**************************************************************************************************/ + +#define ULTRASONIC_TX_CYCLES 5U /* 发送5个PWM周期驱动换能器 */ +#define ULTRASONIC_TX_TIME 498U // ms +#define ULTRASONIC_MAX_TOF_RELOAD 1000U //us + +/**************************************************************************************************/ + +void ultrasonic_tx_init(void); + +void ultrasonic_pwm_out_cycles(void); + +// void ultrasonic_transmit_delay(const uint16_t micro_second); + +// void ultrasonic_rece_exti_config(void); + +void ultrasonic_echo_timer_config(void); + +void ultrasonic_config(void); + +// uint16_t ultrasonic_calc_distance(void); + +#endif // UART_H diff --git a/Src/command.c b/Src/command.c index c041765..f7a3980 100644 --- a/Src/command.c +++ b/Src/command.c @@ -17,6 +17,7 @@ #include #include "board_config.h" #include "gd32e23x_usart.h" +#include "ultrasonic_analog.h" /* ============================================================================ * 协议格式说明 @@ -52,7 +53,7 @@ /** @name 协议帧标识符 * @{ */ #define PROTOCOL_PACKAGE_HEADER 0xD5 /**< 命令帧包头标识 */ -#define PROTOCOL_BOARD_TYPE 0x03 /**< 板卡类型标识 */ +#define PROTOCOL_BOARD_TYPE 0x04 /**< 板卡类型标识 */ /** @} */ /** @name 命令长度限制 @@ -82,6 +83,8 @@ static const uint8_t s_report_status_ok[] = { 'o', 'k' }; /**< 成功响应 static const uint8_t s_report_status_err[] = { 'e','r','r' }; /**< 错误响应数据 */ /** @} */ +extern volatile bool g_ultrasonic_measure_done; + /* ============================================================================ * 公共接口函数 * ============================================================================ */ @@ -251,20 +254,31 @@ void handle_command(const uint8_t *frame, uint8_t len) { // 仅基础命令,如 M1, M2, M3 switch (base_cmd) { case 1u: // M1: enable sensor report - send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); - return; + // g_ultrasonic_measure_done = false; + ultrasonic_pwm_out_cycles(); + gpio_bit_toggle(GPIOA, GPIO_PIN_0); + + while (g_ultrasonic_measure_done) + { + g_ultrasonic_measure_done = false; + send_response(RESP_TYPE_OK, s_report_status_err, sizeof(s_report_status_err)); + return; + } + + + case 2u: // M2: disable sensor report send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); return; - case 3u: - send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); - return; + // case 3u: + // + // return; - case 4u: - send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); - return; + // case 4u: + // + // return; // case 201u: // M201命令 // send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok)); @@ -404,4 +418,3 @@ void command_process(void) { } } } - \ No newline at end of file diff --git a/Src/gd32e23x_it.c b/Src/gd32e23x_it.c index aa19aa8..1712db6 100644 --- a/Src/gd32e23x_it.c +++ b/Src/gd32e23x_it.c @@ -37,6 +37,9 @@ OF SUCH DAMAGE. #include "uart.h" #include "uart_ring_buffer.h" #include "led.h" +#include "ultrasonic_analog.h" + +extern uint16_t g_capture_value; /*! \brief this function handles NMI exception @@ -101,9 +104,78 @@ void SysTick_Handler(void) { delay_decrement(); } +// /** +// * @brief This function handles TIMER15 interrupt request. +// * @param[in] none +// * @param[out] none +// * @retval None +// */ +// void TIMER15_IRQHandler(void) { +// if (timer_interrupt_flag_get(US_TX_DELAY_TIMER, TIMER_INT_FLAG_UP) == SET) +// { +// timer_interrupt_flag_clear(US_TX_DELAY_TIMER, TIMER_INT_FLAG_UP); +// exti_interrupt_enable(US_RX_GPIO_EXTI); // turn on hardware external input interrupt +// timer_counter_value_config(US_ECHO_TIMER, 0); +// timer_enable(US_ECHO_TIMER); // turn on timer to calculate the first ultrasonic echo time +// timer_disable(US_TX_DELAY_TIMER); +// } +// } + +void TIMER15_IRQHandler(void) { + if (timer_interrupt_flag_get(TIMER15, TIMER_INT_FLAG_CH1)) { + timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_CH1); + // g_ultrasonic_measure_done = true; // TODO 测距命令发送回报标识位,最终不应在这里 + gpio_bit_set(GPIOA, GPIO_PIN_0); // TODO waiting for delete + } + + if (timer_interrupt_flag_get(TIMER15, TIMER_INT_FLAG_UP)) { + timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_UP); + timer_disable(TIMER15); + } + +} + + + +/** + * @brief This function handles external lines 0 to 1 interrupt request + * @param[in] none + * @param[out] none + * @retval None + */ +void EXTI0_1_IRQHandler(void) { + if (exti_interrupt_flag_get(US_RX_GPIO_EXTI) == SET) + { + exti_interrupt_flag_clear(US_RX_GPIO_EXTI); + g_capture_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH); + + timer_disable(US_ECHO_TIMER); + exti_interrupt_disable(US_RX_GPIO_EXTI); + } +} + + +/* PWM周期计数器 - 使用ULTRASONIC_TX_CYCLES宏 */ +volatile uint8_t pwm_cycle_count = 0; + +void TIMER13_IRQHandler(void) +{ + if(SET == timer_interrupt_flag_get(TIMER13, TIMER_INT_FLAG_UP)) { + timer_interrupt_flag_clear(TIMER13, TIMER_INT_FLAG_UP); + pwm_cycle_count++; + + if(pwm_cycle_count >= (ULTRASONIC_TX_CYCLES)) { + timer_disable(TIMER13); + pwm_cycle_count = 0; + g_ultrasonic_measure_done = true; // TODO 测距命令发送回报标识位,最终不应在这里 + } + + } +} + void USART0_IRQHandler(void) { if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { uint8_t data = usart_data_receive(USART0); (void)uart_ring_buffer_put(data); // 缓冲满时丢弃,返回值可用于统计 } -} \ No newline at end of file +} diff --git a/Src/main.c b/Src/main.c index c49f112..fbc34bd 100644 --- a/Src/main.c +++ b/Src/main.c @@ -40,6 +40,9 @@ OF SUCH DAMAGE. #include #include "i2c.h" #include "board_config.h" +#include "ultrasonic_analog.h" + +volatile uint16_t g_capture_value; /*! \brief main function @@ -49,12 +52,14 @@ OF SUCH DAMAGE. */ int main(void) { - setbuf(stdout, NULL); + systick_config(); + rs485_init(); led_init(); + ultrasonic_config(); #ifdef DEBUG_VERBOSE char hello_world[] = {"Hello World!\r\n"}; @@ -68,16 +73,16 @@ int main(void) while (usart_flag_get(RS485_PHY, USART_FLAG_TC) == RESET) {} #endif - i2c_config(); - -#ifdef DEBUG_VERBOSE - i2c_scan(); - - i2c_bus_reset(); -#endif while(1){ + + // ultrasonic_pwm_out_cycles(); + + // delay_ms(10); command_process(); - delay_ms(10); + delay_ms(10); + // uint16_t ultrasonic_value = ultrasonic_calc_distance(); + // printf("ultrasonic value: %d", ultrasonic_value); + // delay_ms(10); } } diff --git a/Src/ultrasonic_analog.c b/Src/ultrasonic_analog.c new file mode 100644 index 0000000..957346e --- /dev/null +++ b/Src/ultrasonic_analog.c @@ -0,0 +1,176 @@ +#include "ultrasonic_analog.h" +#include "gd32e23x_usart.h" +#include "gd32e23x_rcu.h" +#include "gd32e23x_gpio.h" +#include "board_config.h" +#include "systick.h" + +volatile bool g_ultrasonic_measure_done = false; +extern uint32_t g_capture_value; + +void ultrasonic_tx_init(void) { + + // TODO + rcu_periph_clock_enable(RCU_GPIOA); + + gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0); + gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_0); + gpio_bit_reset(GPIOA, GPIO_PIN_0); + + rcu_periph_clock_enable(US_TX_GPIO_RCU); + + gpio_mode_set(US_TX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, US_TX_GPIO_PIN); + gpio_output_options_set(US_TX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, US_TX_GPIO_PIN); + gpio_af_set(US_TX_GPIO_PORT, US_TX_GPIO_AF, US_TX_GPIO_PIN); + + timer_oc_parameter_struct timer_ocinitpara; + timer_parameter_struct timer_initpara; + + rcu_periph_clock_enable(US_TX_TIMER_RCU); + + timer_deinit(US_TX_TIMER); + + timer_struct_para_init(&timer_initpara); + /* 配置为300kHz PWM输出 (72MHz/240) */ + timer_initpara.prescaler = 0; // 不分频 + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = 239; // 72MHz/300kHz - 1 + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_init(US_TX_TIMER, &timer_initpara); + + timer_channel_output_struct_para_init(&timer_ocinitpara); + timer_ocinitpara.outputstate = TIMER_CCX_DISABLE; + 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; + timer_channel_output_config(US_TX_TIMER, US_TX_TIMER_CH, &timer_ocinitpara); + + /* config timer channel output mode */ + timer_channel_output_mode_config(US_TX_TIMER, US_TX_TIMER_CH, TIMER_OC_MODE_PWM0); + + /* config channel output pluse value (50% duty) */ + timer_channel_output_pulse_value_config(US_TX_TIMER, US_TX_TIMER_CH, 120); + + /* auto-reload preload enable */ + timer_auto_reload_shadow_enable(US_TX_TIMER); + + timer_counter_value_config(US_TX_TIMER, 0); + + timer_interrupt_enable(US_TX_TIMER, TIMER_INT_UP); + nvic_irq_enable(TIMER13_IRQn, 2); + +} + +void ultrasonic_pwm_out_cycles(void) { + + g_ultrasonic_measure_done = false; + + timer_disable(TIMER13); + + timer_channel_output_state_config(TIMER13, TIMER_CH_0, TIMER_CCX_ENABLE); + + timer_enable(US_TX_TIMER); + timer_enable(TIMER15); + +} + +// void ultrasonic_transmit_debounce_delay(const uint16_t micro_second) { +// rcu_periph_clock_enable(US_TX_DELAY_RCU); +// timer_deinit(US_TX_DELAY_TIMER); + +// timer_parameter_struct timer_initpara; +// timer_struct_para_init(&timer_initpara); +// timer_initpara.prescaler = 71; +// timer_initpara.alignedmode = TIMER_COUNTER_EDGE; +// timer_initpara.counterdirection = TIMER_COUNTER_UP; +// timer_initpara.period = micro_second - 1; +// timer_initpara.clockdivision = TIMER_CKDIV_DIV1; +// timer_initpara.repetitioncounter = 0; +// timer_init(US_TX_DELAY_TIMER, &timer_initpara); + +// timer_auto_reload_shadow_enable(US_TX_DELAY_TIMER); +// timer_interrupt_enable(US_TX_DELAY_TIMER, TIMER_INT_UP); +// nvic_irq_enable(TIMER15_IRQn, 1U); +// } + +void ultrasonic_receive_exti_config(void) { + rcu_periph_clock_enable(US_RX_GPIO_RCU); + rcu_periph_clock_enable(US_RX_EXTI_RCU); + + gpio_mode_set(US_RX_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, US_RX_GPIO_PIN); + nvic_irq_enable(US_RX_EXTI_IRQ, 0U); + syscfg_exti_line_config(EXTI_SOURCE_GPIOA, US_RX_EXTI_LINE); + + exti_init(US_RX_GPIO_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING); + exti_flag_clear(US_RX_GPIO_EXTI); + + // exti_interrupt_enable(EXTI_0); +} + +void ultrasonic_echo_timer_config(void) { + rcu_periph_clock_enable(US_ECHO_RCU); + timer_deinit(US_ECHO_TIMER); + + timer_parameter_struct timer_initpara; + timer_struct_para_init(&timer_initpara); + timer_initpara.prescaler = 71; + timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + timer_initpara.counterdirection = TIMER_COUNTER_UP; + timer_initpara.period = ULTRASONIC_MAX_TOF_RELOAD - 1; + timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + timer_init(TIMER15, &timer_initpara); + + timer_oc_parameter_struct timer_oc_initpara; + timer_channel_output_struct_para_init(&timer_oc_initpara); + timer_oc_initpara.outputstate = TIMER_CCX_ENABLE; + timer_oc_initpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_channel_output_config(TIMER15, TIMER_CH_1,&timer_oc_initpara); + + timer_interrupt_enable(TIMER15, TIMER_INT_CH1 | TIMER_INT_UP); + nvic_irq_enable(TIMER15_IRQn, 0); + + + // timer_parameter_struct timer_initpara; + // timer_struct_para_init(&timer_initpara); + // timer_initpara.prescaler = 71; + // timer_initpara.alignedmode = TIMER_COUNTER_EDGE; + // timer_initpara.counterdirection = TIMER_COUNTER_UP; + // timer_initpara.period = ULTRASONIC_MAX_TOF_RELOAD; + // timer_initpara.clockdivision = TIMER_CKDIV_DIV1; + // timer_initpara.repetitioncounter = 0; + // timer_init(US_ECHO_TIMER, &timer_initpara); + + // timer_ic_parameter_struct timer_icinitpara; + // timer_channel_input_struct_para_init(&timer_icinitpara); + // timer_icinitpara.icpolarity = TIMER_IC_POLARITY_BOTH_EDGE; + // timer_icinitpara.icselection = TIMER_IC_SELECTION_INDIRECTTI; + // timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; + // timer_icinitpara.icfilter = 0x03; + // timer_input_capture_config(US_ECHO_TIMER, US_ECHO_CH, &timer_icinitpara); + + +} + +void ultrasonic_config(void) { + ultrasonic_tx_init(); + // ultrasonic_transmit_debounce_delay(TIME_CORRECTION_US); + // ultrasonic_receive_exti_config(); + ultrasonic_echo_timer_config(); +} + +// uint16_t ultrasonic_calc_distance(void) { +// // while (!ultrasonicMeasurementDone); +// // uint32_t us_value = timer_channel_capture_value_register_read(US_ECHO_TIMER, US_ECHO_CH); +// uint16_t distance = (TIME_CORRECTION_US + g_capture_value) * 17; +// /* +// * (TIME_CORRECTION_US + us_value) * 340 m/s +// * ----------------------------------------- +// * 1000 000 +// * ---------------------------------------------- +// * 2 +// */ +// return distance; +// }