fm_ccjy/Board/Src/laser.c

394 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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 <stdio.h>
#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;
// }
// }
}