/* * @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; uint8_t res; int rx_count = 0; //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(USART2, 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; const char *o_status = (char *)status; if(!strncmp(o_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 100000 // 精度,即小数点后的位数 static float 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]; // 数字部分的值 float result = (float)num / PRECISION; // 将数字部分和小数部分合并成浮点数 return result; } static void command_distance_read_rsp(void) { uint8_t distance[10] = {0}; float 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; const char *z_status = (char *)status; if(!strncmp(z_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}, }; void uart2_init(void) { /*接收配置*/ //使能空闲中断 LL_USART_EnableIT_IDLE(USART2); /*发送配置*/ //设置外设地址,因为这个是DMA串口发送, LL_DMA_SetPeriphAddress(DMA1,LL_DMA_STREAM_6,(uint32_t)&USART2->DR); //使能DMA串口发送 LL_USART_EnableDMAReq_TX(USART2); //使能DMA2发送完成中断 LL_DMA_EnableIT_TC(DMA1,LL_DMA_STREAM_6); LL_USART_EnableIT_RXNE(USART2); //开启接收中断 } void laser_init(send_data_cb_t cb) { 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; } //串口接收中断回调函数,激光 void laser_rx_cb(void)//uint8_t uart_index, uint8_t *data, uint16_t len { // 空闲中断,表明接收到了1帧所有的数据 if(LL_USART_IsActiveFlag_IDLE(USART2)) { //清除空闲中断 LL_USART_ClearFlag_IDLE(USART2); laser_data_process(uart_buf,rx_count); rx_count = 0; } // Rx非空中断,表明接收到了一个字节 // 读取Rx可自动清除中断标志位 if(LL_USART_IsActiveFlag_RXNE(USART2)) { // 如果数组长度大于设置的data最大长度,直接停止接收 if(rx_count > 50) rx_count = 0; // wait for the next data uart_buf[rx_count] = LL_USART_ReceiveData8(USART2); rx_count ++; } } //根据cmd指令执行相应程序 void cmd_parsing(char *str) { //if(strcmp(str, "WC") == 0) if(!strncmp(str, REQ_DEVICE_ONLINE,2)) command_device_connect_rsp(); else if(!strncmp(str, REQ_OPEN_STATUS,3)) command_open_status_rsp(); else if(!strncmp(str, REQ_OPEN_STATUS_WRITE,3)) command_open_status_write_rsp(); else if(!strncmp(str, REQ_DISTANCE_READ,3)) command_distance_read_rsp(); else if(!strncmp(str, REQ_ZERO_STATUS,3)) command_zero_status_rsp(); else if(!strncmp(str, REQ_ZERO_STATUS_WRITE,3)) command_zero_status_write_rsp(); } //激光传感器任务流程 void laser_task(void) { //command_zero_status_open_req(); if (laser_handle.state != LASER_READY) { if(it_500ms_falg == 1) { if(laser_handle.state == LASER_IDEL) command_device_connect_req(); else if(laser_handle.state == LASER_CONNECT) command_open_status_req(); else if(laser_handle.state == LASER_OPEN_STATUS) command_zero_status_close_req(); else if(laser_handle.state == LASER_ZERO_STATUS_CLOSE) command_zero_status_open_req(); else if(laser_handle.state == LASER_ZERO_STATUS_OPEN) command_distance_read_req(); else if(laser_handle.state == LASER_DISTANCE) _laser_ready(); it_500ms_falg = 0; } } // else // { // if(it_10ms_falg == 1) // { // laser_handle.command_distance_read_req(); // if(laser_handle.distance >= 0) // { // InputReg[4] = laser_handle.distance; // } // else // { // int laser_num = -laser_handle.distance; // // InputReg[4] = (uint16_t)((0xFFFF - laser_num) + 1); // } // it_10ms_falg = 0; // //laser_handle.connect = true; // } // } }