From 816b800643032d802074261a2103505f556eea0f Mon Sep 17 00:00:00 2001 From: huoyujia081 Date: Wed, 12 Jun 2024 14:06:12 +0800 Subject: [PATCH] Add RS485 module in ch32v208rbt6 Just input "test_rs485" command to test RS485 bus. 1. Connect the board with the USB-RS485 switcher. 2. Open a serial IPC, using 115200 Baud rate. 3. Input "test_rs485" command. 4. Now input any contents in IPC, minding that every line shoule be append with '\n'. --- .../XiZi_IIoT/board/ch32v208rbt6/board.c | 4 + .../ch32v208rbt6/third_party_driver/Kconfig | 8 +- .../ch32v208rbt6/third_party_driver/Makefile | 3 + .../third_party_driver/can/Kconfig | 11 ++ .../third_party_driver/rs485/Kconfig | 14 +++ .../third_party_driver/rs485/Makefile | 4 + .../third_party_driver/rs485/test/Makefile | 4 + .../rs485/test/rs485_test.c | 115 ++++++++++++++++++ .../third_party_driver/uart/connect_uart.c | 30 +++++ .../third_party_driver/uart/test/rs485_test.c | 20 +-- 10 files changed, 202 insertions(+), 11 deletions(-) create mode 100755 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/can/Kconfig create mode 100755 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Kconfig create mode 100755 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Makefile create mode 100755 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/rs485_test.c diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c index be4f3b20c..3677342fc 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c @@ -72,6 +72,7 @@ void InitBoardHardware() InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); #ifdef BSP_USING_UART + /* include RS485 */ InitHwUart(); InstallConsole("uart1", SERIAL_DRV_NAME_1, SERIAL_1_DEVICE_NAME_0); #endif @@ -87,10 +88,13 @@ void InitBoardHardware() #ifdef BSP_USING_BLE WCHBLE_Init(); HAL_Init(); + #endif + #ifdef BSP_USING_CAN InitHwCan(); #endif + KPrintf("consle init completed.\n"); KPrintf("board initialization......\n"); // KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, gd32vf103_SRAM_SIZE); diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig index a91fcbebd..14e2eb7e6 100755 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig @@ -25,4 +25,10 @@ menuconfig BSP_USING_CAN if BSP_USING_CAN source "$BSP_DIR/third_party_driver/can/Kconfig" endif - \ No newline at end of file + +menuconfig BSP_USING_RS485 + bool "Using RS485" + default y + if BSP_USING_RS485 + source "$BSP_DIR/third_party_driver/rs485/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile index 90ba02065..e837bc03d 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile @@ -16,4 +16,7 @@ endif ifeq ($(CONFIG_BSP_USING_CAN),y) SRC_DIR += can endif +ifeq ($(CONFIG_BSP_USING_RS485),y) + SRC_DIR += rs485 +endif include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/can/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/can/Kconfig new file mode 100755 index 000000000..34fb7d247 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/can/Kconfig @@ -0,0 +1,11 @@ +config CAN_BUS_NAME_1 + string "can bus name" + default "can1" + +config CAN_DRIVER_NAME + string "can driver name" + default "can1_drv" + +config CAN_1_DEVICE_NAME_1 + string "can bus 1 device 1 name" + default "can1_dev1" \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Kconfig new file mode 100755 index 000000000..8bf36a4de --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Kconfig @@ -0,0 +1,14 @@ +menuconfig BSP_USING_UART3 + bool "Enable UART3" + default y + if BSP_USING_UART3 + config SERIAL_BUS_NAME_3 + string "serial bus 3 name" + default "uart3" + config SERIAL_DRV_NAME_3 + string "serial bus 3 driver name" + default "uart3_drv" + config SERIAL_3_DEVICE_NAME_0 + string "serial bus 3 device name" + default "uart3_dev1" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Makefile new file mode 100755 index 000000000..f88b1b19c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/Makefile @@ -0,0 +1,4 @@ +# SRC_FILES := connect_uart.c test_uart.c +SRC_DIR := test + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/Makefile new file mode 100755 index 000000000..7b33f7977 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := rs485_test.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/rs485_test.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/rs485_test.c new file mode 100644 index 000000000..82935b422 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/rs485/test/rs485_test.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file rs485_test.c + * @brief test ch32v307 485 + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2024-03-14 + */ +#include "shell.h" +#include "ch32v20x.h" +#include "ch32v20x_usart.h" +#include "connect_uart.h" + +// RS485发送数据 +static void RS485_SendData(uint8_t data) +{ + // 等待发送缓冲区为空 + while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET) + { + } + + // 发送数据 + USART_SendData(USART3, data); +} + +// RS485接收数据 +static uint16_t RS485_ReceiveData(void) +{ + // 等待接收缓冲区非空 + while (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET) + { + } + + // 读取接收数据 + return USART_ReceiveData(USART3); +} + +static void RS485_SendString(const char *buffer) +{ + size_t len = strlen(buffer); + for (size_t i = 0; i < len; i++) + { + if (buffer[i] != '\r' || buffer[i] != '\n') + { + RS485_SendData(buffer[i]); + } + } +} + +static void RS485_ReceiveString(char *buffer, size_t bufferSize) +{ + size_t i = 0; + + while (i < bufferSize - 1) + { + char receivedChar = RS485_ReceiveData() & 0xFF; + + if (receivedChar == '\n') + { + // 收到回车或换行符,表示字符串接收完毕 + break; + } + + buffer[i] = receivedChar; + i++; + } + + buffer[i] = '\0'; // 在字符串末尾添加空字符,表示字符串结束 + + while (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) != RESET) + { + char dummy = USART_ReceiveData(USART3); + (void)dummy; // 避免编译器警告 + } +} + +int test_rs485(int argc, char *argv[]) +{ + KPrintf("485 Test\r\n"); + char receiveBuffer[100]; + char *sendString = "hello aiit 485\r\n"; + int n = 10; + RS485_SendString(sendString); + while (n--) + { + // 接收字符串 + RS485_ReceiveString(receiveBuffer, sizeof(receiveBuffer)); + KPrintf("%s\n", receiveBuffer); + if (receiveBuffer[0] == 0xfd) + { + RS485_SendString(sendString); + } + else + { + USART_ClearFlag(USART3, USART_FLAG_TC); + RS485_SendString(receiveBuffer); + } + } + + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + test_rs485, test_rs485, test rs485); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/uart/connect_uart.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/uart/connect_uart.c index da0675b88..d173dcc47 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/uart/connect_uart.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/uart/connect_uart.c @@ -383,5 +383,35 @@ int InitHwUart(void) USART_Init((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, &usart_init_struct); USART_Cmd((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, ENABLE); + +#ifdef BSP_USING_RS485 + /* RS485为电气协议,不涉及通信协议,使用串口直接发送 */ + GPIO_InitTypeDef GPIO_InitStructure = {0}; + USART_InitTypeDef USART_InitStructure = {0}; + NVIC_InitTypeDef NVIC_InitStructure = {0}; + + //uart3 init + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); + + /* USART3 TX-->B.10 RX-->B.11 */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + USART_InitStructure.USART_BaudRate = 115200; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + + USART_Init(USART3, &USART_InitStructure); + USART_Cmd(USART3, ENABLE); +#endif return ret; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v307vct6/third_party_driver/uart/test/rs485_test.c b/Ubiquitous/XiZi_IIoT/board/ch32v307vct6/third_party_driver/uart/test/rs485_test.c index 875e2ea8b..67387dc38 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v307vct6/third_party_driver/uart/test/rs485_test.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v307vct6/third_party_driver/uart/test/rs485_test.c @@ -23,7 +23,7 @@ #include "connect_uart.h" // UART5发送数据 -static void UART5_SendData(uint8_t data) +static void RS485_SendData(uint8_t data) { // 等待发送缓冲区为空 while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET) @@ -35,7 +35,7 @@ static void UART5_SendData(uint8_t data) } // UART5接收数据 -static uint8_t UART5_ReceiveData(void) +static uint8_t RS485_ReceiveData(void) { // 等待接收缓冲区非空 while (USART_GetFlagStatus(UART5, USART_FLAG_RXNE) == RESET) @@ -46,25 +46,25 @@ static uint8_t UART5_ReceiveData(void) return USART_ReceiveData(UART5); } -static void UART5_SendString(const char *buffer) +static void RS485_SendString(const char *buffer) { size_t len = strlen(buffer); for (size_t i = 0; i < len; i++) { if (buffer[i] != '\r' || buffer[i] != '\n') { - UART5_SendData(buffer[i]); + RS485_SendData(buffer[i]); } } } -static void UART5_ReceiveString(char *buffer, size_t bufferSize) +static void RS485_ReceiveString(char *buffer, size_t bufferSize) { size_t i = 0; while (i < bufferSize - 1) { - char receivedChar = UART5_ReceiveData(); + char receivedChar = RS485_ReceiveData(); if (receivedChar == '\n') { @@ -91,20 +91,20 @@ int test_rs485(int argc, char *argv[]) char receiveBuffer[100]; char *sendString = " hello aiit 485\r\n"; int n = 10; - UART5_SendString(sendString); + RS485_SendString(sendString); while (n--) { // 接收字符串 - UART5_ReceiveString(receiveBuffer, sizeof(receiveBuffer)); + RS485_ReceiveString(receiveBuffer, sizeof(receiveBuffer)); KPrintf("%s\r\n", receiveBuffer); if (receiveBuffer[0] == 0xfd) { - UART5_SendString(sendString); + RS485_SendString(sendString); } else { USART_ClearFlag(UART5, USART_FLAG_TC); - UART5_SendString(receiveBuffer); + RS485_SendString(receiveBuffer); } }