/* * @Author: shenghao.xu * @Date: 2023-04-13 22:39:28 * @LastEditors: shenghao.xu * @LastEditTime: 2023-04-24 12:34:05 * @Description: HL-G103-S-J * email:545403892@qq.com * Copyright (c) 2023 by shenghao.xu, All Rights Reserved. */ #include #include "laser.h" extern size_t strlen(const char *); extern uart_t *uarts[UART_NUM_MAX]; const char FRAME_HEAD_RSP = '$'; const char FRAME_TAIL = '\r'; const char FRAME_HEAD[] = "%01#"; const char FRAME_TRUE[] = "+00001"; const char FRAME_FALSE[] = "+00000"; const char FRAME_BCC[] = "**"; const char REQ_DEVICE_ONLINE[] = "WCSR03001"; const char REQ_OPEN_STATUS[] = "RLR"; // 激光开启状态查询 const char REQ_OPEN_STATUS_WRITE[] = "WLR"; // 激光开启状态设置 const char REQ_DISTANCE_READ[] = "RMD"; // 测定值读出 const char REQ_ZERO_STATUS[] = "RZS"; // 调零状态查询 const char REQ_ZERO_STATUS_WRITE[] = "WZS"; // 调零状态设置 static uart_t *handle; static char request_buf[RS485_REC_LEN]; static uint8_t uart_buf[RS485_REC_LEN]; static uint8_t *response_ptr; static uint8_t response_ptr_offset = 0; laser_t laser_handle; static void laser_rx_cb(uint8_t uart_index, uint8_t *data, uint16_t len); static void laser_send(uint8_t *data, uint8_t length) { laser_handle.send_data_cb(RS485_PORT, data, length); } // 是否在线 static void command_device_connect_req(void) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%c", FRAME_HEAD, REQ_DEVICE_ONLINE, FRAME_BCC, FRAME_TAIL); laser_send((uint8_t *)request_buf, strlen(request_buf)); } // 激光开启状态查询 static void command_open_status_req(void) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%c", FRAME_HEAD, REQ_OPEN_STATUS, FRAME_BCC, FRAME_TAIL); laser_send((uint8_t *)request_buf, strlen(request_buf)); } // 激光开启状态设置 static void command_open_status_write_req(BOOL open) { if (open) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%s%c", FRAME_HEAD, REQ_OPEN_STATUS_WRITE, FRAME_TRUE, FRAME_BCC, FRAME_TAIL); } else { snprintf(request_buf, sizeof(request_buf), "%s%s%s%s%c", FRAME_HEAD, REQ_OPEN_STATUS_WRITE, FRAME_FALSE, FRAME_BCC, FRAME_TAIL); } laser_send((uint8_t *)request_buf, strlen(request_buf)); } // 测定值读出 static void command_distance_read_req(void) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%c", FRAME_HEAD, REQ_DISTANCE_READ, FRAME_BCC, FRAME_TAIL); laser_send((uint8_t *)request_buf, strlen(request_buf)); } // 调零状态查询 static void command_zero_status_req(void) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%c", FRAME_HEAD, REQ_ZERO_STATUS, FRAME_BCC, FRAME_TAIL); laser_send((uint8_t *)request_buf, strlen(request_buf)); } // 调零状态开启 static void command_zero_status_write_req(BOOL open) { if (open) { snprintf(request_buf, sizeof(request_buf), "%s%s%s%s%c", FRAME_HEAD, REQ_ZERO_STATUS_WRITE, FRAME_TRUE, FRAME_BCC, FRAME_TAIL); } else { snprintf(request_buf, sizeof(request_buf), "%s%s%s%s%c", FRAME_HEAD, REQ_ZERO_STATUS_WRITE, FRAME_FALSE, FRAME_BCC, FRAME_TAIL); } laser_send((uint8_t *)request_buf, strlen(request_buf)); } static void command_zero_status_close_req(void) { command_zero_status_write_req(FALSE); } static void command_zero_status_open_req(void) { command_zero_status_write_req(TRUE); } // 处理数据 static void laser_data_process(uint8_t *data, uint8_t length) { char cmd[3] = {0}; // 向右偏移4个位置获取指令部分 response_ptr_offset = 0; response_ptr = data; response_ptr_offset += 4; if (!laser_handle.connect) { osel_memcpy((uint8_t *)cmd, response_ptr + response_ptr_offset, 2); response_ptr_offset += 2; } else { osel_memcpy((uint8_t *)cmd, response_ptr + response_ptr_offset, 3); response_ptr_offset += 3; } cmd_parsing(cmd); } static void command_device_connect_rsp(void) { laser_handle.connect = TRUE; if (laser_handle.state != LASER_READY) { laser_handle.state = LASER_CONNECT; } } static void command_open_status_rsp(void) { uint8_t status[5] = {0}; response_ptr_offset++; // 跳过符号 osel_memcpy(status, response_ptr + response_ptr_offset, 5); const char *cs = FRAME_TRUE; if (IsEqual(status, (cs + 1), 5)) { laser_handle.open_status = TRUE; if (laser_handle.state != LASER_READY) { laser_handle.state = LASER_OPEN_STATUS; } } else { laser_handle.open_status = FALSE; } #if STATUS_DEFAULT == 1 if (laser_handle.state == LASER_CONNECT) { if (!laser_handle.open_status) { command_open_status_write_req(TRUE); } } #endif } static void command_open_status_write_rsp(void) { } #define PRECISION 10000 // 精度,即小数点后的位数 static float32 to_float(uint8_t *arr) { int num = arr[0] * 1000000 + arr[1] * 100000 + arr[2] * 10000 + arr[3] * 1000 + arr[4] * 100 + arr[5] * 10 + arr[6]; // 数字部分的值 float32 result = (float32)num / PRECISION; // 将数字部分和小数部分合并成浮点数 return result; } static void command_distance_read_rsp(void) { uint8_t distance[10] = {0}; float32 f = 0; osel_memcpy(distance, response_ptr + response_ptr_offset, 10); for (uint8_t i = 1; i <= 7; i++) { CHAR_TO_NUM(distance[i], distance[i]); } f = to_float(&distance[1]); if (distance[0] == '-') { f = -f; } if (laser_handle.state != LASER_READY) { laser_handle.state = LASER_DISTANCE; } laser_handle.distance = f * 1000; } static void command_zero_status_rsp(void) { uint8_t status[5] = {0}; response_ptr_offset++; // 跳过符号 osel_memcpy(status, response_ptr + response_ptr_offset, 5); const char *cs = FRAME_TRUE; if (IsEqual(status, (cs + 1), 5)) { laser_handle.zero_status = TRUE; } else { laser_handle.zero_status = FALSE; } } static void command_zero_status_write_rsp(void) { #if STATUS_DEFAULT == 1 if (laser_handle.state == LASER_OPEN_STATUS) { laser_handle.zero_status = FALSE; laser_handle.state = LASER_ZERO_STATUS_CLOSE; } else if (laser_handle.state == LASER_ZERO_STATUS_CLOSE) { laser_handle.zero_status = TRUE; laser_handle.state = LASER_ZERO_STATUS_OPEN; } else { laser_handle.zero_status = FALSE; laser_handle.state = LASER_CONNECT; } #endif } static void _laser_ready(void) { laser_handle.state = LASER_READY; } REGISTER_CMD(WC, command_device_connect_rsp, ""); REGISTER_CMD(RLR, command_open_status_rsp, ""); REGISTER_CMD(WLR, command_open_status_write_rsp, ""); REGISTER_CMD(RMD, command_distance_read_rsp, ""); REGISTER_CMD(RZS, command_zero_status_rsp, ""); REGISTER_CMD(WZS, command_zero_status_write_rsp, ""); laser_event_t laser_event[] = { {LASER_IDEL, command_device_connect_req}, {LASER_CONNECT, command_open_status_req}, {LASER_OPEN_STATUS, command_zero_status_close_req}, {LASER_ZERO_STATUS_CLOSE, command_zero_status_open_req}, {LASER_ZERO_STATUS_OPEN, command_distance_read_req}, {LASER_DISTANCE, _laser_ready}, }; static void uart5_init(void) { if (uarts[RS485_PORT] == NULL) { uarts[RS485_PORT] = uart_create(USART5, FALSE, 1, laser_rx_cb, FALSE, 0, NULL); uarts[RS485_PORT]->uart_index = RS485_PORT; uart_recv_en(uarts[RS485_PORT]); } } void laser_init(send_data_cb_t cb) { cmd_init(); /* 命令初始化 */ uart5_init(); handle = uarts[RS485_PORT]; DBG_ASSERT(handle != NULL __DBG_LINE); GPIO_SET(RS485_EN3_GPIO_Port, RS485_EN3_Pin); // 485使能 osel_memset((uint8_t *)&laser_handle, 0, sizeof(laser_t)); laser_handle.state = LASER_IDEL; laser_handle.send_data_cb = cb; laser_handle.command_device_connect_req = command_device_connect_req; laser_handle.command_open_status_req = command_open_status_req; laser_handle.command_open_status_write_req = command_open_status_write_req; laser_handle.command_distance_read_req = command_distance_read_req; laser_handle.command_zero_status_req = command_zero_status_req; laser_handle.command_zero_status_write_req = command_zero_status_write_req; } // 串口接收中断回调函数,激光 static void laser_rx_cb(uint8_t uart_index, uint8_t *data, uint16_t len) { if (data[0] == '\r') { if (uart_buf[0] == 0x25 && uart_buf[3] == FRAME_HEAD_RSP) // '%' is the start of the data { laser_data_process(uart_buf, handle->rx_sta & 0X3FFF); handle->rx_sta = 0; } else { handle->rx_sta = 0; } } else { uart_buf[handle->rx_sta & 0X3FFF] = data[0]; handle->rx_sta++; if (handle->rx_sta > (RS485_REC_LEN - 1)) { handle->rx_sta = 0; } } }