#include #include #include "debug.h" #include #include #include "interface_ethernet.h" #include "eth_cfg.h" #include "lwip/timeouts.h" #include "sdrv_eth.h" #include "app/app_param_manage.h" #include "app/app_differential_drive.h" //参数管理 #define MAX_BUFFER_SIZE (sizeof(((RequestContext *)0)->param_request->arr)) #define MAX_PACKET_SIZE 1024 // 定义最大包大小为1K Timer ethernet_timer_interface; Timer ethernet_timer_interface1; Timer ethernet_timer_interface2; struct udp_pcb *udpcb_1; struct udp_pcb *udpcb_2; struct udp_pcb *udpcb_3; struct udp_pcb *udpcb_4; struct udp_pcb *udpcb_5; bool eth_pool_rx = false; UnEthernetFault ethernet_fault_Info = { .bit_data.auto_count = 0, .bit_data.manual_count = 0, .bit_data.auto_state = 0, .bit_data.manual_state = 0, }; StrEthernetParameter ethernet_parameter = { .local_ip = {192,168,17,20}, .mask = {255,255,255,0}, .computer_ip = {192,168,17,3}, .local_communication_port = 8011, .Local_upper_port = 8000, .Local_download_port = 7811, .upper_ip = {192,168,17,3}, .download_ip = {192,168,17,183}, .target_upper_port = 8000, .target_download_port = 7811, .target_communication_port = 8011, }; static bool g_eth1_rx_pkt; static void eth_dma_rx_int_cb(struct net_driver_s *dev) { if (dev == &g_eth1_dev) g_eth1_rx_pkt = true; // printf("eth_dma_rx_int_cb\n"); } static void lwip_Ethernet(void *signal_id) { // uint32_t time_boot = getCurrentTime();//记录当前时间 (void)signal_id; // 标记变量为已使用,避免编译器警告 // 接收ETH帧,并传递给LWIP协议栈 // 如果使能接收中断,因为ISR里会disable接收中断,因此,这里对于 // 中断接收标志(g_eth1_rx_pkt)的处理过程中不会有 // 新的接收中断被响应,所以,这里不存在原子性问题。 if ((!eth_pool_rx && g_eth1_rx_pkt) || eth_pool_rx) { g_eth1_rx_pkt = false; dwc_eth_rx(&g_eth1_dev, eth_pool_rx); } // LWIP协议栈接口,用于做LWIP超时检测 sys_check_timeouts(); timerStart(ðernet_timer_interface1, 10,1); //10ms调用一次 // printf("lwipInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间 } //err_t //udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) int8_t UdpSendToData(uint8_t udpcbID, uint8_t *buf, uint16_t len, uint8_t *sip, uint16_t port) { struct pbuf *DesPuff = NULL; ip4_addr_t Desaddr; int8_t SendState = 0; //---------------------------------------------------------------------------------------------------- IP4_ADDR(&Desaddr,sip[0],sip[1],sip[2],sip[3]);//地址值转换 DesPuff = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL); /* 申请内存 */ pbuf_take(DesPuff, buf, len); /* 将g_lwip_demo_sendbuf中的数据打包进pbuf结构中 */ if(UDPCB_1 == udpcbID) { SendState = udp_sendto(udpcb_1, DesPuff, &Desaddr, port); } else if(UDPCB_2 == udpcbID) { SendState = udp_sendto(udpcb_2, DesPuff, &Desaddr, port); } else if(UDPCB_3 == udpcbID) { SendState = udp_sendto(udpcb_3, DesPuff, &Desaddr, port); } else if(UDPCB_3 == udpcbID) { SendState = udp_sendto(udpcb_3, DesPuff, &Desaddr, port); } else if(UDPCB_4 == udpcbID) { SendState = udp_sendto(udpcb_4, DesPuff, &Desaddr, port); } else if(UDPCB_5 == udpcbID) { SendState = udp_sendto(udpcb_5, DesPuff, &Desaddr, port); } else { } pbuf_free(DesPuff); /* 释放内存 */ return SendState; } // udpcbID UDP索引 //recv 回调函数 //port 绑定端口 void UDP_Echo_Init(uint8_t udpcbID, udp_recv_fn recv, uint16_t port) { //------------------------------------------ if(UDPCB_1 == udpcbID) { /* 新建一个控制块*/ udpcb_1 = udp_new(); ASSERT(udpcb_1); /* 绑定端口号 */ udp_bind(udpcb_1, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_1, recv, (void *)udpcbID); } else if(UDPCB_2 == udpcbID) { /* 新建一个控制块*/ udpcb_2 = udp_new(); ASSERT(udpcb_2); /* 绑定端口号 */ udp_bind(udpcb_2, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_2, recv, (void *)udpcbID); } else if(UDPCB_3 == udpcbID) { /* 新建一个控制块*/ udpcb_3 = udp_new(); ASSERT(udpcb_3); /* 绑定端口号 */ udp_bind(udpcb_3, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_3, recv, (void *)udpcbID); } else if(UDPCB_4 == udpcbID) { /* 新建一个控制块*/ udpcb_4 = udp_new(); ASSERT(udpcb_4); /* 绑定端口号 */ udp_bind(udpcb_4, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_4, recv, (void *)udpcbID); } else if(UDPCB_5 == udpcbID) { /* 新建一个控制块*/ udpcb_5 = udp_new(); ASSERT(udpcb_5); /* 绑定端口号 */ udp_bind(udpcb_5, IP_ADDR_ANY, port); /* 注册接收数据回调函数 */ udp_recv(udpcb_5, recv, (void *)udpcbID); } else { } } void udp_Callback_1(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *buf = (uint8_t *)(p->payload); uint16_t i = 0; uint16_t len = 0; uint16_t udp_temp = 0; //------------------------------------------------------------------------------ if( (0xFF == buf[0] ) && ( 0xBB == buf[1] ) )//自主计算机手动遥控器或者远程遥控器 { ethernet_fault_Info.bit_data.manual_count ++; if( (p->len) >= sizeof(UnManualComputerInput) )//如果读取长度超过,就取最小长度 { len = sizeof(UnManualComputerInput); } else { len = p->len; } for(i = 0; i < len; i++) { un_manual_computer_input.arr[i] = buf[i]; } publishMessage(&un_manual_computer_input, 1); // p->len = len; // printf("Manualrecive len:%d\n",len); // udp_sendto(upcb, p, addr, port); } else if( (0xFF == buf[0] ) && (0xCC == buf[1] ) )//自主计算器 自动 { ethernet_fault_Info.bit_data.auto_count ++; if( (p->len) >= sizeof(UnAutoComputerInput) )//如果读取长度超过,就取最小长度 { len = sizeof(UnAutoComputerInput); } else { len = p->len; } // unsigned int frame_header : 16; // 帧头 固定值0xFFCC // unsigned int frame_type : 16; // 帧类型 固定值0x0001 // unsigned int frame_length : 8; // 帧长 固定值0x19 // unsigned int heartbeat : 8; // 心跳 按帧累加 // unsigned int set_speed : 16; // 设定速度 系数0.01,正为前进,负为后退 单位m/s // unsigned int set_curvature : 16; // 设定曲率 系数0.0001,正为左转,负为右转 // unsigned int latitude : 32; // 纬度 系数10^-7,431234567表示43.1234567度 // unsigned int longitude : 32; // 经度 系数10^-7,431234567表示43.1234567度 // unsigned int altitude : 32; // 高度 单位mm // unsigned int heading : 16; // 航向 车辆航向,35999表示359.99度 // unsigned int crc : 8; // CRC 按字节累加之和,溢出取低8位 for(i = 0; i < len; i++) { un_auto_computer_input.arr[i] = buf[i]; } udp_temp = ((un_auto_computer_input.bit_data.set_speed << 8) | (un_auto_computer_input.bit_data.set_speed >> 8));//设定速度 20240928 修改高低位交换 un_auto_computer_input.bit_data.set_speed = udp_temp; udp_temp = ((un_auto_computer_input.bit_data.set_curvature << 8) | (un_auto_computer_input.bit_data.set_curvature >> 8));//设定曲率 un_auto_computer_input.bit_data.set_curvature = udp_temp; publishMessage(&un_auto_computer_input, 1); // p->len = len; // printf("Autorecive len:%d\n",len); // udp_sendto(upcb, p, addr, port); } else { } pbuf_free(p); } void udp_Callback_2(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *buf = (uint8_t *)(p->payload); uint8_t ip_addr[4] = {0,0,0,0}; //------------------------------------------------------------------------------------------------ ip_addr[0] = addr->addr & 0xff; /* IADDR4 */ ip_addr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */ ip_addr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */ ip_addr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */ ethernet_parameter.target_upper_port = port;//保存接收到的端口和IP,下次发送对应的IP和端口 ethernet_parameter.upper_ip[0] = ip_addr[0]; ethernet_parameter.upper_ip[1] = ip_addr[1]; ethernet_parameter.upper_ip[2] = ip_addr[2]; ethernet_parameter.upper_ip[3] = ip_addr[3]; if( (0x80 == buf[0]) && (0x00 == buf[1]) ) { memcpy((uint8_t *)&(un_request_frame.arr[0]),buf, sizeof(UnRequestFrame)); publishMessage(&un_request_frame, 1); } pbuf_free(p); } void udp_Callback_4(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *buf = (uint8_t *)(p->payload); uint8_t ip_addr[4] = {0,0,0,0}; //------------------------------------------------------------------------------------------------ //20250822 增加保存刷写上位机IP ip_addr[0] = addr->addr & 0xff; /* IADDR4 */ ip_addr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */ ip_addr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */ ip_addr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */ ethernet_parameter.download_ip[0] = ip_addr[0]; ethernet_parameter.download_ip[1] = ip_addr[1]; ethernet_parameter.download_ip[2] = ip_addr[2]; ethernet_parameter.download_ip[3] = ip_addr[3]; boot_eth_flag = true; FrameHeader = ( (buf[0] << 8) | (buf[1]) ); printf("FrameHeader %d\n",FrameHeader); pbuf_free(p); } void udp_Callback_5(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint8_t *buf = (uint8_t *)(p->payload); //------------------------------------------------------------------------------------------------ if(FEEDDOG_HEADER == ( (buf[0] << 8) | (buf[1]) )) { WDTReFresh_flag = true;//更新喂狗标志 printf("Feed dog flag received %d\n",getCurrentTime()); } pbuf_free(p); } //100ms 调用一次 void ethernetTimerProcess(void) { static uint8_t ethernet_timer = 0; static uint8_t ethernet_temp[4] = {0,0,0,0};//中间判断值 uint8_t temp = 0; ethernet_timer ++; if(ethernet_timer >= 5)//500ms判断一次 { ethernet_timer = 0; //自主计算机故障判断------------------------------------------------------------ if(ethernet_fault_Info.bit_data.auto_count == ethernet_temp[0])//数据一样表示故障 { ethernet_fault_Info.bit_data.auto_state = FAULT; } else { ethernet_fault_Info.bit_data.auto_state = NORMAL; ethernet_temp[0] = ethernet_fault_Info.bit_data.auto_count;//数据更新 } if(ethernet_fault_Info.bit_data.auto_state != ethernet_temp[1]) { ethernet_temp[1] = ethernet_fault_Info.bit_data.auto_state; temp ++; } //手动故障判断------------------------------------------------------------ if(ethernet_fault_Info.bit_data.manual_count == ethernet_temp[2])//数据一样表示故障 { ethernet_fault_Info.bit_data.manual_state = FAULT; } else { ethernet_fault_Info.bit_data.manual_state = NORMAL; ethernet_temp[2] = ethernet_fault_Info.bit_data.manual_count;//数据更新 } if(ethernet_fault_Info.bit_data.manual_state != ethernet_temp[3]) { ethernet_temp[3] = ethernet_fault_Info.bit_data.manual_state; temp ++; } } publishMessage(ðernet_fault_Info, 1);// 状态变化 发送信号 } static void vehicleInfOoutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_vehicle_Info_output), sizeof(un_vehicle_Info_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } static void motorStatusOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_motor_status_output), sizeof(un_motor_status_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } static void pidOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_pid_output), sizeof(un_pid_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } static void remoteControlOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_remote_control_output), sizeof(un_remote_control_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } static void manualControlOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_manual_control_output),sizeof(un_manual_control_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } static void autoControlOutput(void *signal_id) { (void)signal_id; // 标记变量为已使用,避免编译器警告 UdpSendToData(UDPCB_2,(uint8_t *)(&un_auto_control_output), sizeof(un_auto_control_output), (uint8_t *)ðernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port); } //以太网 发送 void ethernetSendAll(void *signal_id) { static uint8_t computer_output_cnt = 0; uint32_t crc_temp = 0; uint8_t i = 0; uint16_t Rg_Tmp = 0; float Rg_FloatTmp = 0; static uint8_t eth_cnt = 0; static uint8_t app_output_cnt = 0; uint8_t BOOT_Arr[2] = {0x01,0x02};//上电发送app帧给上位机用 //------------------------------------------------------------------------- //自主计算机以太网50ms发送 20210811修改为100ms发送 //20210827修改为高位在前低位再后与自主计算机保持一致 computer_output_cnt ++; if(computer_output_cnt >= 1) { computer_output_cnt = 0; //按字节累加和,注意不是信号 20210826修改按照字节累加 // printf("left_motor_speed = %f\n",diff_data.left_motor_speed); // printf("right_motor_speed = %f\n",diff_data.right_motor_speed); un_computer_output.bit_data.frame_header = 0xCCFF; un_computer_output.bit_data.frame_type = 0x1100; un_computer_output.bit_data.frame_length = 0x0B; un_computer_output.bit_data.accumulated = eth_cnt ++; Rg_FloatTmp = (diff_data.left_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米 Rg_FloatTmp = Rg_FloatTmp*100;//,最后需要扩大100倍 ,系数0.01 Rg_Tmp = (uint16_t)((int16_t)(Rg_FloatTmp));//最后转换为无符号型); //20231012修改轮速发送 20231226-3号车修改方向 un_computer_output.bit_data.speed = ((Rg_Tmp << 8) | (Rg_Tmp >> 8));//高位在前,地位灾后 Rg_FloatTmp = (diff_data.right_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米 Rg_FloatTmp = Rg_FloatTmp*100;//,最后需要扩大100倍 ,系数0.01 Rg_Tmp = (uint16_t)((int16_t)(Rg_FloatTmp));//最后转换为无符号型); //20231012修改轮速发送 20231226-3号车修改方向 un_computer_output.bit_data.curvature = ((Rg_Tmp << 8) | (Rg_Tmp >> 8));//高位在前,地位灾后 crc_temp = 0; for(i = 0; i<10 ;i++)//长度固定 { crc_temp = crc_temp + (un_computer_output.arr[i]); } un_computer_output.bit_data.crc = (uint8_t)crc_temp; UdpSendToData(UDPCB_1,(uint8_t *)(&un_computer_output.arr[0]), 11, (uint8_t *)ðernet_parameter.computer_ip[0], COMMUNICATION_PORT); UdpSendToData(UDPCB_4,(uint8_t *)(&un_computer_output.arr[0]), 11, (uint8_t *)ðernet_parameter.computer_ip[0], COMMUNICATION_PORT); } if(app_output_cnt < 10)//20250109 100ms 发送10帧app帧。解决以太网没有初始化完成就发送的丢帧问题 { app_output_cnt ++; UdpSendToData(UDPCB_4, BOOT_Arr, 2, (uint8_t *)ðernet_parameter.download_ip[0], BOOT_TX_PORT); } } // 以太网定时器信号处理函数 static void ethernetInterfaceTimerProcess(void *signal_id) { uint32_t time_boot = getCurrentTime();//记录当前时间 (void)signal_id; // 标记变量为已使用,避免编译器警告 ethernetSendAll(signal_id); ethernetTimerProcess();//故障判断 timerStart(ðernet_timer_interface, 100,1); //100ms调用一次 // printf("ethernetInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间 } static unsigned char receive_buffer[MAX_BUFFER_SIZE]; //参数管理回调 void udp_Callback_3(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { static unsigned int received_size = 0; uint8_t *buf = (uint8_t *)(p->payload); // 检查是否是新的帧头 if ((0x80 == buf[1]) && (0xFF == buf[0])) { // 重置接收过程 received_size = 0; printf("检测到新的帧头,重置接收过程\n"); } // 检查是否有足够的空间来存储新数据 if (received_size + p->len <= MAX_BUFFER_SIZE) { printf("p->len %d :\n" , p->len); memcpy(receive_buffer + received_size, buf, p->len); received_size += p->len; // 检查是否接收到完整的数据 if (received_size >= sizeof(request_context.param_request->arr)) { printf("received_size : %d :\n" , received_size); for(u16_t i = 0; i< sizeof(request_context.param_request->arr); i++) { request_context.param_request->arr[i] = receive_buffer[i]; } memcpy(request_context.param_request->arr, receive_buffer, sizeof(request_context.param_request->arr)); request_context.sender_ip = (unsigned int)addr->addr; request_context.sender_port = port; // 打印 request_context.param_request->arr 的内容 // printf("接收到的 param_request->arr 内容:\n"); // for (size_t i = 0; i < sizeof(request_context.param_request->arr); ++i) // { // printf("%02X ", request_context.param_request->arr[i]); // if ((i + 1) % 1024 == 0 || i == sizeof(request_context.param_request->arr) - 1) // { // printf("\n"); // feedWatchdog(); // } // } publishMessage(&request_context, 1); printf("received_size:%d \n" , received_size); // 重置接收缓冲区 received_size = 0; printf("接收到完整数据,处理完毕\n"); } } else { // 缓冲区溢出,重置接收 received_size = 0; printf("接收缓冲区溢出,数据丢弃\n"); } unsigned int tmp_count = pbuf_free(p); printf("pbuf_free已经释放!tmp_count :%d \n" , tmp_count); p = NULL; } void OnParamSend(void *data) { uint8_t ip_addr[4] = {0,0,0,0}; RequestContext *signal = (RequestContext *)(data); ip_addr[0] = signal->sender_ip & 0xff; /* IADDR4 */ ip_addr[1] = (signal->sender_ip >> 8) & 0xff; /* IADDR3 */ ip_addr[2] = (signal->sender_ip >> 16) & 0xff; /* IADDR2 */ ip_addr[3] = (signal->sender_ip >> 24) & 0xff; /* IADDR1 */ uint32_t total_size = sizeof(signal->param_request->arr); uint32_t sent_size = 0; while (sent_size < total_size) { uint32_t remaining = total_size - sent_size; uint32_t packet_size = (remaining > MAX_PACKET_SIZE) ? MAX_PACKET_SIZE : remaining; UdpSendToData(UDPCB_3, (uint8_t *)(signal->param_request->arr) + sent_size, packet_size, ip_addr, signal->sender_port); sent_size += packet_size; // 添加小延迟,避免包丢失 udelay(1000); } printf("数据发送完成!%d \n", sent_size); } void ethernetRequest(void *signal_id) { static uint8_t ethernetRequestcnt = 0; uint8_t request_ip[4] = {192,168,17,88}; uint16_t request_port = 8080; uint8_t request_buf[200] = {0}; static uint8_t RequestStaACC0 = 0; static uint8_t RequestStaACC1 = 0; static uint8_t RequestStaACC2 = 0; static uint8_t RequestStaACC3 = 0; uint16_t RgExchangeTemp = 0; uint32_t Rg32ExchangeTemp = 0; uint32_t TempAcc = 0; uint8_t i = 0; ethernetRequestcnt ++; if(ethernetRequestcnt >= 10) { ethernetRequestcnt = 0; //车辆状态 un_vehicle_Info_output.bit_data.frame_header = 0xCCAA;//帧头 un_vehicle_Info_output.bit_data.frame_type = 0x2000;//帧类型 un_vehicle_Info_output.bit_data.frame_length = 0x2900;//帧长 un_vehicle_Info_output.bit_data.accumulated = RequestStaACC0++;//累加值 TempAcc = 0; for (i = 0; i < 40; i++)//累加前40个字节 { TempAcc = TempAcc + (uint32_t)(un_vehicle_Info_output.arr[i]); } un_vehicle_Info_output.bit_data.crc = (uint8_t)TempAcc;//累加值 //电机状态 un_motor_status_output.bit_data.frame_header = 0xCCAA;//帧头 un_motor_status_output.bit_data.frame_type = 0x2100;//帧类型 un_motor_status_output.bit_data.frame_length = 0x2200;//帧长 un_motor_status_output.bit_data.accumulated = RequestStaACC1++;//累加值 RgExchangeTemp = ( (uint16_t)getParam("maxTorq") + 300 ) *100 ; // un_motor_status_output.bit_data.left_torque_limit = ((RgExchangeTemp << 8) | (RgExchangeTemp >> 8));//左侧扭矩限制 // un_motor_status_output.bit_data.right_torque_limit = ((RgExchangeTemp << 8) | (RgExchangeTemp >> 8));//右侧扭矩限制 // un_motor_status_output.bit_data.left_power_in = (((uint16_t)getParam("feedPwr") << 8) | ((uint16_t)getParam("feedPwr") >> 8));//左侧馈电功率 // un_motor_status_output.bit_data.right_power_in = (((uint16_t)getParam("feedPwr") << 8) | ((uint16_t)getParam("feedPwr") >> 8));//右侧馈电功率 // un_motor_status_output.bit_data.left_power_out = (((uint16_t)getParam("dispPwr") << 8) | ((uint16_t)getParam("dispPwr") >> 8));//左侧放电功率 // un_motor_status_output.bit_data.right_power_out = (((uint16_t)getParam("dispPwr") << 8) | ((uint16_t)getParam("dispPwr") >> 8));//右侧放电功率 TempAcc = 0; for (i = 0; i < 32; i++)//累加前31个字节 { TempAcc = TempAcc + (uint32_t)(un_motor_status_output.arr[i]); un_motor_status_output.bit_data.checksum = (uint8_t)TempAcc;//累加值 } //PID un_pid_output.bit_data.frame_header = 0xCCAA;//帧头 un_pid_output.bit_data.frame_type = 0x2200;//帧类型 un_pid_output.bit_data.frame_length = 0x3800;//帧长 un_pid_output.bit_data.accumulated = RequestStaACC2++;//累加值 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kp")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_straight_p = Rg32ExchangeTemp;//遥控直行P参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_ki")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_straight_i = Rg32ExchangeTemp;//遥控直行I参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_straight_d = Rg32ExchangeTemp;//遥控直行D参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_il")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_straight_p = Rg32ExchangeTemp;//自主直行P参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_ol")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_straight_i = Rg32ExchangeTemp;//自主直行I参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_straight_d = Rg32ExchangeTemp;//自主直行D参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_kp")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_turn_p = Rg32ExchangeTemp;//遥控转弯P参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_ki")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_turn_i = Rg32ExchangeTemp;//遥控转弯I参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_kd")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.rc_turn_d = Rg32ExchangeTemp;//遥控转弯D参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_il")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_turn_p = Rg32ExchangeTemp;//自主转弯P参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_ol")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_turn_i = Rg32ExchangeTemp;//自主转弯I参数 Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000); Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) ); un_pid_output.bit_data.auto_turn_d = Rg32ExchangeTemp;//自主转弯I参数 TempAcc = 0; for (i = 0; i < 55; i++)//累加前40个字节 { TempAcc = TempAcc + (uint32_t)(un_pid_output.arr[i]); } un_pid_output.bit_data.checksum = (uint8_t)TempAcc;//累加值 //遥控 un_remote_control_output.bit_data.frame_header = 0xCCAA;//帧头 un_remote_control_output.bit_data.frame_type = 0x2400;//帧类型 un_remote_control_output.bit_data.frame_length = 0x1400;//帧长 un_remote_control_output.bit_data.accumulated = RequestStaACC3++;//累加值 //RCH_3 TempAcc = 0; for (i = 0; i < 17; i++)//累加前40个字节 { TempAcc = TempAcc + (uint32_t)(un_remote_control_output.arr[i]); } un_remote_control_output.bit_data.crc = (uint8_t)TempAcc;//累加值 //手动控制 un_manual_control_output.bit_data.frame_header = 0xBBFF; un_manual_control_output.bit_data.frame_type = 0x2500; un_manual_control_output.bit_data.frame_length = 0x0F; TempAcc = 0; for (i = 0; i < 14; i++)//累加前40个字节 { TempAcc = TempAcc + (uint32_t)(un_manual_control_output.arr[i]); } un_manual_control_output.bit_data.crc_2 = (uint8_t)TempAcc;//累加值 //自主控制 un_auto_control_output.bit_data.frame_header = 0xCCFF; un_auto_control_output.bit_data.frame_type = 0x2600; un_auto_control_output.bit_data.frame_length = 0x1B; TempAcc = 0; for (i = 0; i < 27; i++)//累加前40个字节 { TempAcc = TempAcc + (uint32_t)(un_auto_control_output.arr[i]); } un_auto_control_output.bit_data.crc = (uint8_t)TempAcc;//累加值 memcpy(request_buf,(uint8_t *)(&un_vehicle_Info_output),sizeof(un_vehicle_Info_output)); memcpy(&request_buf[sizeof(un_vehicle_Info_output)],(uint8_t *)(&un_motor_status_output),sizeof(un_motor_status_output)); memcpy(&request_buf[sizeof(un_vehicle_Info_output) + sizeof(un_motor_status_output)],(uint8_t *)(&un_pid_output),sizeof(un_pid_output)); memcpy(&request_buf[sizeof(un_vehicle_Info_output) + sizeof(un_motor_status_output) + sizeof(un_pid_output)],(uint8_t *)(&un_remote_control_output),sizeof(un_remote_control_output)); memcpy(&request_buf[sizeof(un_vehicle_Info_output) + sizeof(un_motor_status_output) + sizeof(un_pid_output) + sizeof(un_remote_control_output)],(uint8_t *)(&un_manual_control_output),sizeof(un_manual_control_output)); memcpy(&request_buf[sizeof(un_vehicle_Info_output) + sizeof(un_motor_status_output) + sizeof(un_pid_output) + sizeof(un_remote_control_output) + sizeof(un_manual_control_output)],(uint8_t *)(&un_auto_control_output),sizeof(un_auto_control_output)); UdpSendToData(UDPCB_2,request_buf,sizeof(un_vehicle_Info_output) + sizeof(un_motor_status_output) + sizeof(un_pid_output) + sizeof(un_remote_control_output) + sizeof(un_manual_control_output) + sizeof(un_auto_control_output), request_ip, request_port); } timerStart(ðernet_timer_interface2, 1,1); //10ms调用一次 } // APP模块的初始化 void ethernetInterfaceInit(void) { //----------------------------------- if (!eth_pool_rx) { // 使能DMA Rx中断。Tx未使用中断,因为ETH速率很高, // Tx中断处理耗时反而可能拖慢发送速度。 dwc_eth_enable_dma_rx_int(&g_eth1_dev, eth_dma_rx_int_cb); } timerInit(ðernet_timer_interface1); timerInit(ðernet_timer_interface); // timerInit(ðernet_timer_interface2); // 订阅定时器信号,用于定时采集 subscribe(ðernet_timer_interface, ethernetInterfaceTimerProcess); subscribe(ðernet_timer_interface1, lwip_Ethernet); // subscribe(ðernet_timer_interface2, ethernetRequest); subscribe(&un_vehicle_Info_output, vehicleInfOoutput); subscribe(&un_motor_status_output, motorStatusOutput); subscribe(&un_pid_output, pidOutput); subscribe(&un_remote_control_output, remoteControlOutput); subscribe(&un_manual_control_output, manualControlOutput); subscribe(&un_auto_control_output, autoControlOutput); // 订阅消息,使用静态成员函数作为回调 subscribe(&request_send, OnParamSend); timerStart(ðernet_timer_interface, 100,1); //100ms调用一次 timerStart(ðernet_timer_interface1, 10,1); //10ms调用一次 // timerStart(ðernet_timer_interface2, 1,1); //10ms调用一次 printf( "ethernetInterface: initial OK %d\n",getCurrentTime()); }