// // Created by huli on 2021/12/23. // #include "led_protocol.h" Led_protocol::Led_protocol() { } Led_protocol::~Led_protocol() { led_protocol_uninit(); } //led通信协议初始化, area_size必须为1~5 Error_manager Led_protocol::led_protocol_init(int area_size) { led_communication_msg_init(area_size); m_encapsulate_flag = false; return Error_code::SUCCESS; } Error_manager Led_protocol::led_protocol_uninit() { return Error_code::SUCCESS; } Error_manager Led_protocol::led_protocol_reset() { m_encapsulate_flag = false; //清除缓存后, 直接初始化可以重置所有... m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.clear(); led_protocol_init(); return Error_code::SUCCESS; } Error_manager Led_protocol::led_protocol_delete(int area_index) { if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end()) { m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.erase(area_index); } return Error_code::SUCCESS; } //创建led消息, 参数输入需要显示的字符串即可 std::string Led_protocol::create_led_message(int area_index, std::string show_string, unsigned short x, unsigned short y, unsigned short width, unsigned short heigth) { led_communication_area_create(area_index); m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_show_string = show_string; unsigned short t_area_x = 0x8000+x; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8; unsigned short t_area_y = y; //区域 Y 坐标,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8; unsigned short t_area_width = 0x8000+width; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8; unsigned short t_area_height = heigth; //区域高度,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8; return get_led_msg_total_string(); } //获取led协议封装后的最终消息, 这个结果就可以直接tcp发送了 std::string Led_protocol::get_led_msg_total_string() { led_communication_total_encapsulate(); return m_led_communication_msg.m_total_string; } //获取led协议封装后的最终消息, 这个结果就可以直接tcp发送了 std::string Led_protocol::get_led_msg_total_string(int area_index) { led_communication_total_encapsulate(area_index); return m_led_communication_msg.m_total_string; } //设置显示的内容 Error_manager Led_protocol::set_show_string(int area_index, std::string show_string) { led_communication_area_create(area_index); m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_show_string = show_string; return Error_code::SUCCESS; } //设置显示的矩形框, 单位像素点, (注:一个汉字为16*16像素) Error_manager Led_protocol::set_show_rectangle(int area_index, unsigned short x, unsigned short y, unsigned short width, unsigned short heigth) { led_communication_area_create(area_index); unsigned short t_area_x = 0x8000+x; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8; unsigned short t_area_y = y; //区域 Y 坐标,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8; unsigned short t_area_width = 0x8000+width; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8; unsigned short t_area_height = heigth; //区域高度,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8; return Error_code::SUCCESS; } //设置显示的行间距 Error_manager Led_protocol::set_lines_sizes(int area_index, unsigned char lines_sizes) { led_communication_area_create(area_index); m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[12] = lines_sizes; return Error_code::SUCCESS; } //设置显示动态区运行模式 Error_manager Led_protocol::set_run_mode(int area_index, unsigned char run_mode, unsigned short time_out) { led_communication_area_create(area_index); /*动态区运行模式 0—动态区数据循环显示。 1—动态区数据显示完成后静止显示最后一页数 据。 2—动态区数据循环显示,超过设定时间后数据仍 未更新时不再显示 3—动态区数据循环显示,超过设定时间后数据仍 未更新时显示 Logo 信息,Logo 信息即为动态区域 的最后一页信息 4—动态区数据顺序显示,显示完最后一页后就不 再显示 5—动态区数据顺序显示,超过设定次数后数据仍 未更新时不再显示*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[13] = run_mode; //动态区数据超时时间,单位为 秒/次数 (若RunMode=5,则表示更新次数), , 默认0x0002 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[14] = time_out; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[15] = time_out>>8; return Error_code::SUCCESS; } //设置显示的排版方式 Error_manager Led_protocol::set_type_setting(int area_index, unsigned char type_setting) { led_communication_area_create(area_index); /* 排 版 方 式 ( 上 下 左 右 有 优 先 级 ) 当 ExtendParaLen > 0,才发送该字节,否则不发送 0:表示先从左往右,再从上往下 1:表示先从右往左,再从上往下 2:表示先从上往下,再从左往右 3:表示先从上往下,再从右往左*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[17] = type_setting; return Error_code::SUCCESS; } //设置显示的对齐方式 Error_manager Led_protocol::set_text_alignment(int area_index, unsigned char text_alignment) { led_communication_area_create(area_index); /* 行(上下左右)字对齐方式 Bit1 Bit0 0 0 ----左对齐(左右 默认) 0 1 ----右对齐(左右) 1 0 ----居中对齐(左右) Bit3 Bit2 0 0 ----上对齐(上下 默认) 0 1 ----下对齐(上下) 1 0 ----居中对齐(上下)*/ unsigned char t_text_alignment = text_alignment; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[18] = t_text_alignment; return Error_code::SUCCESS; } //设置显示 是否单行显示 是否自动换行 Error_manager Led_protocol::set_line_mode(int area_index, unsigned char single_line, unsigned char new_line) { led_communication_area_create(area_index); /*是否单行显示 0x01——单行显示 0x02——多行显示*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[19] = single_line; /*是否自动换行 0x01——不自动换行,显示数据在换行时必须插入 换行符 0x02——自动换行,显示内容不需要换行符,但是 只能使用统一的中文字体和英文字体*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[20] = new_line; return Error_code::SUCCESS; } //设置显示方式, 文字移动的方式 Error_manager Led_protocol::set_display_mode(int area_index, unsigned char display_mode) { led_communication_area_create(area_index); /*显示方式,其定义如下: 0x01——静止显示 0x02——快速打出 0x03——向左移动 0x04——向右移动 0x05——向上移动 0x06——向下移动*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[21] = display_mode; return Error_code::SUCCESS; } //设置显示速度 显示特技停留时间 Error_manager Led_protocol::set_speed(int area_index, unsigned char speed, unsigned char stay_time) { led_communication_area_create(area_index); //显示速度, 默认0x00, 从0x00~0x18 数字越小速度越快 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[23] = speed; //显示特技停留时间,单位为 0.5s, 默认0x0a, 如:0x0A,则停留5秒 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[24] = stay_time; return Error_code::SUCCESS; } //led通信的区域数据, 新建, area_size为更新区域的索引编号//map里面没有就新建一个, 有就什么都不做. Error_manager Led_protocol::led_communication_area_create(int area_index) { //map里面没有就新建一个, 有就什么都不做. if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) == m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end() ) { unsigned short t_area_data_len = 0x0000; //区域的数据长度,就是 29-2+m_show_string.length(), 后面再赋值 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[0] = t_area_data_len; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[1] = t_area_data_len>>8; unsigned char t_area_type = 0x00; //区域类型, 默认0x00 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[2] = t_area_type; unsigned short t_area_x = 0x8000; //区域 X 坐标,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[3] = t_area_x; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[4] = t_area_x>>8; unsigned short t_area_y = 0x0000; //区域 Y 坐标,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[5] = t_area_y; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[6] = t_area_y>>8; unsigned short t_area_width = 0x8020; //区域宽度,默认以字节(8 个像素点)为单位, 高字节最高位为 1 时,表示以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[7] = t_area_width; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[8] = t_area_width>>8; unsigned short t_area_height = 0x0020; //区域高度,以像素点为单位 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[9] = t_area_height; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[10] = t_area_height>>8; //这里的宽高默认为0x20和0x20, 即为32*32, 可以显示4个汉字.(每个汉字为16*16, 字母为8*16) unsigned char t_area_index = area_index; //动态区域编号 //注意:该参数只对动态区有效,其他区域为默认值,动态区必须统一编号,编号从 0 开始递增。 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[11] = t_area_index; unsigned char t_lines_sizes = 0x00; //行间距, 默认0x00 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[12] = t_lines_sizes; unsigned char t_run_mode = 0x00; //动态区运行模式, 默认0x00 /*动态区运行模式 0—动态区数据循环显示。 1—动态区数据显示完成后静止显示最后一页数 据。 2—动态区数据循环显示,超过设定时间后数据仍 未更新时不再显示 3—动态区数据循环显示,超过设定时间后数据仍 未更新时显示 Logo 信息,Logo 信息即为动态区域 的最后一页信息 4—动态区数据顺序显示,显示完最后一页后就不 再显示 5—动态区数据顺序显示,超过设定次数后数据仍 未更新时不再显示*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[13] = t_run_mode; unsigned short t_timeout = 0x0002; //动态区数据超时时间,单位为 秒/次数 (若RunMode=5,则表示更新次数), , 默认0x0002 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[14] = t_timeout; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[15] = t_timeout>>8; unsigned char t_extend_para_len = 0x00; //拓展位个数, 默认0x00, 如:0x0A,则拓展位为 10 位, m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[16] = t_extend_para_len; unsigned char t_type_setting = 0x00; //排 版 方 式, 默认0x00, /* 排 版 方 式 ( 上 下 左 右 有 优 先 级 ) 当 ExtendParaLen > 0,才发送该字节,否则不发送 0:表示先从左往右,再从上往下 1:表示先从右往左,再从上往下 2:表示先从上往下,再从左往右 3:表示先从上往下,再从右往左*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[17] = t_type_setting; unsigned char t_text_alignment = 0x00; //字体对齐方式/区域数据排版, 默认0x00, 如:0x00, 左对齐 , 上对齐 /* 行(上下左右)字对齐方式 Bit1 Bit0 0 0 ----左对齐(左右 默认) 0 1 ----右对齐(左右) 1 0 ----居中对齐(左右) Bit3 Bit2 0 0 ----上对齐(上下 默认) 0 1 ----下对齐(上下) 1 0 ----居中对齐(上下)*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[18] = t_text_alignment; unsigned char t_single_line = 0x02; //是否单行显示, 默认0x02, 0x01——单行显示 0x02——多行显示 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[19] = t_single_line; unsigned char t_new_line = 0x01; //是否自动换行, 默认0x01, /*是否自动换行 0x01——不自动换行,显示数据在换行时必须插入 换行符 0x02——自动换行,显示内容不需要换行符,但是 只能使用统一的中文字体和英文字体*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[20] = t_new_line; unsigned char t_display_mode = 0x01; //显示方式, 默认0x01, 如果显示内容较多, 就需要滚动显示, 就设为向上移动0x05 /*显示方式,其定义如下: 0x01——静止显示 0x02——快速打出 0x03——向左移动 0x04——向右移动 0x05——向上移动 0x06——向下移动*/ m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[21] = t_display_mode; unsigned char t_exit_mode = 0x00; //退出方式, 默认0x00, m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[22] = t_exit_mode; unsigned char t_speed = 0x00; //显示速度, 默认0x00, 从0x00~0x18 数字越小速度越快 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[23] = t_speed; unsigned char t_stay_time = 0x0a; //显示特技停留时间,单位为 0.5s, 默认0x0a, 如:0x0A,则停留5秒 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[24] = t_stay_time; unsigned int t_show_string_len = 0x00000000; //数据长度(包括换行,颜色等转义参数), 就是 m_show_string.length(), 后面再赋值 m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[25] = t_show_string_len; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[26] = t_show_string_len>>8; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[27] = t_show_string_len>>16; m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_area_head[28] = t_show_string_len>>24; } return Error_code::SUCCESS; } //led通信的控制指令, 初始化, area_size为更新区域的数量, 默认为0 Error_manager Led_protocol::led_communication_cmd_init(int area_size) { //led通信的区域数据, 在修改里面具体参数的时候初始化 //多次修改也只初始化一次 //初始化 led通信的控制指令, 结构体 //0xA3 0x06 表示 发送实时显示区域数据 unsigned char t_cmd_group = 0xA3; //命令分组编号 m_led_communication_msg.m_led_communication_cmd.m_cmd_head[0] = t_cmd_group; unsigned char t_cmd = 0x06; //命令编号 m_led_communication_msg.m_led_communication_cmd.m_cmd_head[1] = t_cmd; unsigned char t_response = 0x01; //是否要求控制器回复, 默认0x01 /* 是否要求控制器回复。 0x01——控制器必须回复 0x02——控制器不必回复*/ m_led_communication_msg.m_led_communication_cmd.m_cmd_head[2] = t_response; unsigned char t_process_mode = 0x00; //处理模式, 默认0x00 /* 当该字节为 0 时,收到动态信息后不再进行清区域 和初始化区域的操作,当该字节为 1 时,收到动态 信息后需要进行清区域和初始化区域的操作。*/ m_led_communication_msg.m_led_communication_cmd.m_cmd_head[3] = t_process_mode; unsigned char t_reserved = 0x00; //此处保留1个byte m_led_communication_msg.m_led_communication_cmd.m_cmd_head[4] = t_reserved; unsigned char t_delete_area_num = 0x00; //要删除的区域个数, 默认0x00 /* 要删除的区域个数。 注意:如果该值为 0xFF,则删除所有动态区数据。 如果该值为 0x00,则不删除区域。*/ m_led_communication_msg.m_led_communication_cmd.m_cmd_head[5] = t_delete_area_num; unsigned char t_updata_area_num = area_size; //要更新的区域个数, 默认0x00 /* 要删除的区域个数。 注意:如果该值为 0xFF,则删除所有动态区数据。 如果该值为 0x00,则不删除区域。*/ m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] = t_updata_area_num; return Error_code::SUCCESS; } //led通信的物理传输层, 初始化, area_size为更新区域的数量, 默认为0 Error_manager Led_protocol::led_communication_msg_init(int area_size) { led_communication_cmd_init(area_size); //初始化 led通信的物理传输层, 结构体 memset(m_led_communication_msg.m_frame_head, 0xA5, 8); //帧头, 默认8个0xA5 unsigned short t_dst_addr = 0xFFFE; //屏地址, 默认0xFFFE /* 屏地址。 在 PHY 层,广播地址定义如下: 0xFFFF 为广播地址 1,此种模式下,控制器不返回 数据,其可用于广播校时等命令。 0xFFFE 为广播地址 2,此种模式主要用于广播设置 屏参,控制器需返回数据。在返回的数据帧中,地 址也应为 0XFFFE。 0x8000~0xDFFF 地址为保留地址,对于物理层类型 为 TCP/IP 或 GPRS 这种不需要处理 DstAddr 的,可 将其目标地址设置为这个范围中的一个,默认设置 地址为 0x8000。*/ m_led_communication_msg.m_frame_configuration[0] = t_dst_addr; m_led_communication_msg.m_frame_configuration[1] = t_dst_addr>>8; unsigned short t_src_addr = 0x8000; //屏地址, 默认0x8000 /* 源地址,几个特殊地址定义如下: PC 客户端软件从 0x8000 开始,范围为 0x8000~0xDFFF,用来代表不同客户端软件; 0xE000~0xFFFE 为保留地址*/ m_led_communication_msg.m_frame_configuration[2] = t_src_addr; m_led_communication_msg.m_frame_configuration[3] = t_src_addr>>8; unsigned char t_reserved = 0x00; //此处保留3个byte m_led_communication_msg.m_frame_configuration[4] = t_reserved; m_led_communication_msg.m_frame_configuration[5] = t_reserved; m_led_communication_msg.m_frame_configuration[6] = t_reserved; unsigned char t_option = 0x00; //选项, 默认0x00 /* 当该字节的 BIT0 为 1 时,需要发送接下来的 16 字 节 BarCode,这么做是为了便于在线设置控制器 IP. 反之,当该字节的 BIT0 为 0 时,不需要发送接下来 的 16 字节 BarCode. 注意: 1. 只有设置 IP 命令需要将该字节的 BIT0 设置为 1 2. 上位机需要通过网络搜索命令来获取当前局域网 内所有控制卡的 BarCode*/ m_led_communication_msg.m_frame_configuration[7] = t_option; unsigned char t_check_mode = 0x00; //校验模式, 默认0x00 /* 校验值共两个字节 当该字节为 0 时,采用 CRC16 方式 当该字节为 1 时,采用和校验的方式,仅保留最低 位两个字节,采用小端模式 当该字节为 2 时,无校验,校验字节可以为任意值*/ m_led_communication_msg.m_frame_configuration[8] = t_check_mode; unsigned char t_display_mode = 0x00; //显示模式, 默认0x00 /* 0x00:普通模式,动态区与节目可同时显示,但各 区域不可重叠。 0x01:动态模式,优先显示动态区,无动态区则显 示节目,动态区与节目区可重叠。 注:特殊动态区不支持动态模式。*/ m_led_communication_msg.m_frame_configuration[9] = t_display_mode; unsigned char t_device_type = LED_DEVICE_TYPE; //设备类型, 默认0x63 /* 用于区分网络中不同的设备类型,定义如下: 0x51——BX-5K1 0x58——BX-5K2 0x53——BX-5MK2 0x54——BX-5MK1 0x61——BX-6K1 与 5K1 (0x51)兼容 0x62——BX-6K2 与 5MK1 (0x54) 兼容 0x63——BX-6K3 与 5K2,5MK2 (0x53/0x58)兼容 0x64——BX-6K1-YY 0x65——BX-6K2-YY 0x66——BX-6K3-YY*/ m_led_communication_msg.m_frame_configuration[10] = t_device_type; unsigned char t_protocol_version = 0x02; //协议版本号, 默认0x02 //协议版本号,用于区分控制卡使用的协议 m_led_communication_msg.m_frame_configuration[11] = t_protocol_version; unsigned short t_data_len = 0; //数据域长度(不包括帧头、帧尾、帧校验和包头), 这里指通信指令, 后面再赋值 m_led_communication_msg.m_frame_configuration[12] = t_data_len; m_led_communication_msg.m_frame_configuration[13] = t_data_len>>8; unsigned short t_crc = 0; //crc校验码, 包校验为包头数据和数据域的校验值, 后面再赋值 m_led_communication_msg.m_frame_crc[0] = t_crc; m_led_communication_msg.m_frame_crc[1] = t_crc>>8; memset(m_led_communication_msg.m_frame_tail, 0x5A, 1); //帧尾, 默认1个0x5A return Error_code::SUCCESS; } //led通信的区域数据, 通过协议转化, m_led_communication_area 封装成 m_total_string Error_manager Led_protocol::led_communication_area_encapsulate() { for (auto iter = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.begin(); iter != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end(); ++iter) { //1.填写区域数据长度, 后面的27byte加显示字符串 unsigned short t_area_data_len = 29-2+iter->second.m_show_string.length(); iter->second.m_area_head[0] = t_area_data_len; iter->second.m_area_head[1] = t_area_data_len>>8; //2.填写显示字符串长度 unsigned int t_show_string_len = iter->second.m_show_string.length(); iter->second.m_area_head[25] = t_show_string_len; iter->second.m_area_head[26] = t_show_string_len>>8; iter->second.m_area_head[27] = t_show_string_len>>16; iter->second.m_area_head[28] = t_show_string_len>>24; //3.汇总字符串 iter->second.m_total_string = std::string( (char*)iter->second.m_area_head, 29); iter->second.m_total_string += iter->second.m_show_string; } return Error_code::SUCCESS; } //led通信的区域数据, 通过协议转化, m_led_communication_area 封装成 m_total_string Error_manager Led_protocol::led_communication_area_encapsulate(int area_index) { if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end()) { auto & second = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index]; //1.填写区域数据长度, 后面的27byte加显示字符串 unsigned short t_area_data_len = 29-2+second.m_show_string.length(); second.m_area_head[0] = t_area_data_len; second.m_area_head[1] = t_area_data_len>>8; //2.填写显示字符串长度 unsigned int t_show_string_len = second.m_show_string.length(); second.m_area_head[25] = t_show_string_len; second.m_area_head[26] = t_show_string_len>>8; second.m_area_head[27] = t_show_string_len>>16; second.m_area_head[28] = t_show_string_len>>24; //3.汇总字符串 second.m_total_string = std::string( (char*)second.m_area_head, 29); second.m_total_string += second.m_show_string; } return Error_code::SUCCESS; } //led通信的控制指令, 通过协议转化, m_led_communication_cmd 封装成 m_total_string Error_manager Led_protocol::led_communication_cmd_encapsulate() { //1.填写更新区域的个数 m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size(); //2.汇总字符串 m_led_communication_msg.m_led_communication_cmd.m_total_string = std::string( (char*)m_led_communication_msg.m_led_communication_cmd.m_cmd_head, 7); for (auto iter = m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.begin(); iter != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end(); ++iter) { m_led_communication_msg.m_led_communication_cmd.m_total_string += iter->second.m_total_string; } return Error_code::SUCCESS; } //led通信的控制指令, 通过协议转化, m_led_communication_cmd 封装成 m_total_string Error_manager Led_protocol::led_communication_cmd_encapsulate(int area_index) { //1.填写更新区域的个数 m_led_communication_msg.m_led_communication_cmd.m_cmd_head[6] = 1; //2.汇总字符串 m_led_communication_msg.m_led_communication_cmd.m_total_string = std::string( (char*)m_led_communication_msg.m_led_communication_cmd.m_cmd_head, 7); if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) != m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end()) { m_led_communication_msg.m_led_communication_cmd.m_total_string += m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map[area_index].m_total_string; } return Error_code::SUCCESS; } //led通信的物理传输层, 通过协议转化, m_led_communication_msg 封装成 m_total_string Error_manager Led_protocol::led_communication_msg_encapsulate() { //1.填写指令的长度 unsigned short t_data_len = m_led_communication_msg.m_led_communication_cmd.m_total_string.length(); m_led_communication_msg.m_frame_configuration[12] = t_data_len; m_led_communication_msg.m_frame_configuration[13] = t_data_len>>8; //2.计算crc校验码, 需要使用包头和指令 std::string t_result_src = std::string((char*)m_led_communication_msg.m_frame_configuration, 14); t_result_src += m_led_communication_msg.m_led_communication_cmd.m_total_string; unsigned short t_crc = crc16((unsigned char *)t_result_src.c_str(), t_result_src.length()); m_led_communication_msg.m_frame_crc[0] = t_crc; m_led_communication_msg.m_frame_crc[1] = t_crc>>8; //3.字符转义, 需要使用包头和指令和crc校验码 t_result_src += std::string( (char*)m_led_communication_msg.m_frame_crc, 2); int t_result_src_length=t_result_src.length(); unsigned char t_result_dst[1024] = {0};//转义后的临时缓存, 长度上限1024 int t_result_dst_length=0; character_escape(t_result_dst, &t_result_dst_length, (unsigned char *)t_result_src.c_str(), &t_result_src_length); //4.汇总字符串 std::string str1 = std::string((char*)m_led_communication_msg.m_frame_head, 8); std::string str2 = std::string((char*)t_result_dst, t_result_dst_length); std::string str3 = std::string((char*)m_led_communication_msg.m_frame_tail, 1); m_led_communication_msg.m_total_string = str1 + str2 + str3; return Error_code::SUCCESS; } //led通信的物理传输层, 通过协议转化, m_led_communication_msg 封装成 m_total_string Error_manager Led_protocol::led_communication_msg_encapsulate(int area_index) { return led_communication_msg_encapsulate(); } //led通信协议的整体封装 Error_manager Led_protocol::led_communication_total_encapsulate() { if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size() <=0 ) { m_encapsulate_flag = false; m_led_communication_msg.m_total_string.clear(); return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR, " fun error m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.size() <=0"); } led_communication_area_encapsulate(); led_communication_cmd_encapsulate(); led_communication_msg_encapsulate(); m_encapsulate_flag = true; return Error_code::SUCCESS; } //led通信协议的整体封装 Error_manager Led_protocol::led_communication_total_encapsulate(int area_index) { if ( m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find(area_index) == m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.end() ) { m_encapsulate_flag = false; m_led_communication_msg.m_total_string.clear(); return Error_manager(Error_code::ERROR, Error_level::MINOR_ERROR, " fun error m_led_communication_msg.m_led_communication_cmd.m_led_communication_area_map.find() error "); } led_communication_area_encapsulate(area_index); led_communication_cmd_encapsulate(area_index); led_communication_msg_encapsulate(area_index); m_encapsulate_flag = true; return Error_code::SUCCESS; } //crc校验码 unsigned short Led_protocol::crc16(unsigned char * data,int size) { unsigned char data_t ; unsigned short crc,i,j; crc = i = j = 0; if(data == NULL) { return 0; } for(j=0;j> 1) ^ 0xA001; } else { crc >>= 1; } } } return crc; } //字符转义 void Led_protocol::character_escape(unsigned char * p_dst, int * p_dst_length, unsigned char * p_src, int * p_src_length) { /* 字符转义 ◆ 封帧中遇到 0xA5,则将之转义为 0xA6,0x02;如遇到 0xA6,则将之转义为 0xA6,0x01 。 ◆ 封帧中遇到 0x5A,则将之转义为 0x5B,0x02;如遇到 0x5B,则将之转义为 0x5B,0x01 。 ◆ 解帧过程如果遇到连续两个字节为 0xA6, 0x02 ,则反转义为 0xA5 。 ◆ 解帧过程如果遇到连续两个字节为 0xA6, 0x01 ,则反转义为 0xA6 。 ◆ 解帧过程如果遇到连续两个字节为 0x5B, 0x02 ,则反转义为 0x5A。 ◆ 解帧过程如果遇到连续两个字节为 0x5B, 0x01 ,则反转义为 0x5B。 注意:封帧过程中,所涉及校验的数据皆是转义之前的数据,所涉及的数据长度皆是转义之前的数据 长度。 */ if ( p_dst == NULL || p_src == NULL) { return; } int i=0; int j=0; for (i = 0; i < *p_src_length; ++i) { if ( p_src[i] == 0xA5 ) { p_dst[j] = 0xA6; p_dst[j+1] = 0x02; j+=2; } else if ( p_src[i] == 0xA6 ) { p_dst[j] = 0xA6; p_dst[j+1] = 0x01; j+=2; } else if ( p_src[i] == 0x5A ) { p_dst[j] = 0x5B; p_dst[j+1] = 0x02; j+=2; } else if ( p_src[i] == 0x5B ) { p_dst[j] = 0x5B; p_dst[j+1] = 0x01; j+=2; } else { p_dst[j] = p_src[i]; j++; } } *p_dst_length = j; return; } // ////led通信的物理传输层, 通过协议转化, m_led_communication_msg -->> m_led_communication_string //Error_manager Led_protocol::led_communication_encapsulate() //{ // unsigned char t_result_src[1024] = {0};//转义前的临时缓存, 长度上限1024 // unsigned char t_result_dst[1024] = {0};//转义后的临时缓存, 长度上限1024 // int t_result_src_length=0; // int t_result_dst_length=0; // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_frame_configuration, 14); // t_result_src_length += 14; // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_led_communication_cmd.m_total_string.c_str(), m_led_communication_msg.m_led_communication_cmd.m_total_string.length()); // t_result_src_length += m_led_communication_msg.m_led_communication_cmd.m_total_string.length(); // memcpy(t_result_src+t_result_src_length, m_led_communication_msg.m_frame_crc, 2); // t_result_src_length += 2; // // //字符转义 // character_escape(t_result_dst, &t_result_dst_length, t_result_src, &t_result_src_length); // // std::string str1 = std::string((char*)m_led_communication_msg.m_frame_head, 8); // std::string str2 = std::string((char*)t_result_dst, t_result_dst_length); // std::string str3 = std::string((char*)m_led_communication_msg.m_frame_tail, 1); // m_led_communication_msg.m_total_string = str1 + str2 + str3; // // return Error_code::SUCCESS; //} //