diff --git a/CMakeLists.txt b/CMakeLists.txt index a88e3f2..79bc5b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(TARGET_C_SRC ${CMAKE_SOURCE_DIR}/src/soft_i2c.c ${CMAKE_SOURCE_DIR}/src/i2c.c ${CMAKE_SOURCE_DIR}/src/fwdgt.c + ${CMAKE_SOURCE_DIR}/src/rs485_protocol.c ) add_executable(${PROJECT_NAME} ${TARGET_C_SRC}) diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake index f071ea8..48937ea 100644 --- a/cmake/toolchain.cmake +++ b/cmake/toolchain.cmake @@ -91,9 +91,15 @@ set(TARGET_CFLAGS_HARDWARE "-mcpu=cortex-m23 -mfloat-abi=soft -mthumb -mthumb-in # Conditional flags # DEBUG -set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") -set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") -set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") +#set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") +#set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") +#set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O0 -g") +set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -O2 -g") +set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -O2 -g") +set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -O2 -g") +#set(CMAKE_C_FLAGS_DEBUG "-DDEBUG=0 -Os -g") +#set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG=0 -Os -g") +#set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG=0 -Os -g") # RELEASE set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3") # -flto diff --git a/inc/board_config.h b/inc/board_config.h index c2edf57..c45a322 100644 --- a/inc/board_config.h +++ b/inc/board_config.h @@ -31,7 +31,7 @@ #define USART_PHY USART0 #define USART_PHY_BAUDRATE 115200U #define RS485_EN_PORT GPIOA -#define RS485_EN_PIN GPIO_PIN_1 +#define RS485_EN_PIN GPIO_PIN_4 /******************************************************************************/ diff --git a/inc/gd32e23x_it.h b/inc/gd32e23x_it.h index 1b3b1ba..70a4747 100644 --- a/inc/gd32e23x_it.h +++ b/inc/gd32e23x_it.h @@ -39,6 +39,9 @@ OF SUCH DAMAGE. #include "main.h" #include "systick.h" #include "board_config.h" +#include "usart.h" +#include "fwdgt.h" +#include "rs485_protocol.h" /* function declarations */ /* this function handles NMI exception */ diff --git a/inc/rs485_protocol.h b/inc/rs485_protocol.h new file mode 100644 index 0000000..b358deb --- /dev/null +++ b/inc/rs485_protocol.h @@ -0,0 +1,51 @@ +// +// Created by yelv1 on 24-12-31. +// + +#ifndef RS485_PROTOCOL_H +#define RS485_PROTOCOL_H + +#include "gd32e23x.h" +#include "systick.h" +#include "gd32e23x_libopt.h" +#include "board_config.h" +#include "usart.h" +#include "fwdgt.h" +#include +#include +#include + +/******************************************************************************/ + +#define RX_BUFFER_SIZE 32 + +#define PROTOCOL_PACKAGE_HEADER 0xD5 +#define PROTOCOL_BOARD_TYPE 0x03 +#define PROTOCOL_PACKAGE_LENGTH 0x02 + +/******************************************************************************/ + +typedef enum +{ + VALIDATION_SUCCESS = 0, + VALIDATION_CRC_ERROR = 1, + VALIDATION_HEADER_ERROR = 2, + VALIDATION_TYPE_ERROR = 4, + VALIDATION_LENGTH_ERROR = 8 +} validation_result_t; + +/******************************************************************************/ + +void process_command(uint8_t* cmd, size_t length); + +uint8_t calculate_crc(uint8_t data[], uint8_t data_length); + +validation_result_t validate_package_crc(uint8_t* data, uint8_t data_length); + +validation_result_t validate_package_header(uint8_t* data); + +validation_result_t validate_package_type(uint8_t* data); + +validation_result_t validate_data_length(uint8_t* data); + +#endif //RS485_PROTOCOL_H diff --git a/src/gd32e23x_it.c b/src/gd32e23x_it.c index 4dc5453..906adb9 100644 --- a/src/gd32e23x_it.c +++ b/src/gd32e23x_it.c @@ -120,4 +120,28 @@ void TIMER16_IRQHandler(void) } led_status = !led_status; } +} + +void USART0_IRQHandler(void) { + static uint8_t rx_index = 0; + static uint8_t rx_buffer[RX_BUFFER_SIZE]; + + if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { + usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE); + uint8_t received_data = (uint8_t) usart_data_receive(USART0); + + // 将接收到的数据存储到缓冲区 + if (rx_index < RX_BUFFER_SIZE - 1) { + rx_buffer[rx_index++] = received_data; + } + } + + if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) { + usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); + + process_command(rx_buffer, rx_index); // 处理指令 + + rx_index = 0; // 重置缓冲区索引 + return; + } } \ No newline at end of file diff --git a/src/main.c b/src/main.c index c6b5403..bfce4af 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ */ int main(void) { + setbuf(stdout, NULL); /* configure systick */ systick_config(); /* configure USART */ @@ -25,9 +26,10 @@ int main(void) printf("system start!\r\n"); + // gpio_bit_write(RS485_EN_PORT, RS485_EN_PIN, RESET); while(1){ - printf("hello world!\r\n"); - delay_ms(500); + // printf("hello world!\r\n"); + // delay_ms(500); watchdog_reload(); } diff --git a/src/rs485_protocol.c b/src/rs485_protocol.c new file mode 100644 index 0000000..ea8ce98 --- /dev/null +++ b/src/rs485_protocol.c @@ -0,0 +1,92 @@ +// +// Created by yelv1 on 24-12-31. +// + +#include "rs485_protocol.h" + +void process_command(uint8_t *cmd, size_t length) { + char combined_str[3]; + validation_result_t validate = VALIDATION_SUCCESS; + + validate = (validate_package_header(cmd) | + validate_package_type(cmd) | + validate_data_length(cmd) | + validate_package_crc(cmd, length)); + + switch (validate) { + case VALIDATION_SUCCESS: + // printf("%d", length); + sprintf(combined_str, "%c%c", cmd[3], cmd[4]); + if (strcmp(combined_str, "M1") == 0) { + printf("%c%c%c%c%c%c", 0xB5, 0xF1, 0x02, 0x6F, 0x6B, 0xCC); + // eddy_current_value_report(); + } else if (strcmp(combined_str, "M2") == 0) { + printf("%c%c%c%c%c%c%c", 0xB5, 0xF1, 0x02, 0x6F, 0x6B, 0x6B, 0xCC); + // tempture_value_report(); + } else if (strcmp(combined_str, "M3") == 0) + { + printf("%c%c%c%c%c%c", 0xB5, 0xF1, 0x02, 0x6F, 0x6B, 0xCC); + fwdgt_reset_mcu(); + } else { + printf("%c%c%c%c%c%c%c", 0xB5, 0xF0, 0x03, 0x65, 0x72, 0x72, 0x3C); + return; + } + break; + case VALIDATION_CRC_ERROR: + printf("%c%c%c%c%c%c%c", 0xB5, 0xF1, 0x03, 0x65, 0x72, 0x72, 0x3D); + break; + case VALIDATION_HEADER_ERROR: + printf("%c%c%c%c%c%c%c", 0xB5, 0xF2, 0x03, 0x65, 0x72, 0x72, 0x3E); + break; + case VALIDATION_TYPE_ERROR: + printf("%c%c%c%c%c%c%c", 0xB5, 0xF3, 0x03, 0x65, 0x72, 0x72, 0x3F); + break; + case VALIDATION_LENGTH_ERROR: + printf("%c%c%c%c%c%c%c", 0xB5, 0xF4, 0x03, 0x65, 0x72, 0x72, 0x40); + break; + default: + break; + } +} + +uint8_t calculate_crc(uint8_t data[], uint8_t data_length) { + uint8_t crc = 0; + + for (uint8_t i = 1; i < data_length - 1; i++) { + crc += data[i]; + } + + return (uint8_t) (crc & 0xFF); +} + +validation_result_t validate_package_crc(uint8_t *data, uint8_t data_length) { + if (data[data_length - 1] == calculate_crc(data, data_length) && data_length == 3 + data[2] + 1) { + return VALIDATION_SUCCESS; + } else { + return VALIDATION_CRC_ERROR; + } +} + +validation_result_t validate_package_header(uint8_t *data) { + if (data[0] == PROTOCOL_PACKAGE_HEADER) { + return VALIDATION_SUCCESS; + } else { + return VALIDATION_HEADER_ERROR; + } +} + +validation_result_t validate_package_type(uint8_t *data) { + if (data[1] == PROTOCOL_BOARD_TYPE) { + return VALIDATION_SUCCESS; + } else { + return VALIDATION_TYPE_ERROR; + } +} + +validation_result_t validate_data_length(uint8_t *data) { + if (data[2] == PROTOCOL_PACKAGE_LENGTH) { + return VALIDATION_SUCCESS; + } else { + return VALIDATION_LENGTH_ERROR; + } +} diff --git a/src/usart.c b/src/usart.c index 25e1a4e..4416f9e 100644 --- a/src/usart.c +++ b/src/usart.c @@ -28,6 +28,10 @@ void usart_config(void) usart_transmit_config(USART_PHY, USART_TRANSMIT_ENABLE); usart_enable(USART_PHY); + + nvic_irq_enable(USART0_IRQn, 0); + usart_interrupt_enable(USART_PHY, USART_INT_RBNE); + usart_interrupt_enable(USART_PHY, USART_INT_IDLE); } /**