银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-9-26 | zgf | 初次建立 |
事务处理标识 | 协议标识 | 报文长度 | 设备标识 | 功能码 | 起始地址 | 寄存器数量 |
2byte | 2byte | 2byte | 1byte | 1byte | 2 byte | 2 byte |
事务处理标识 | 协议标识 | 报文长度 | 设备标识 | 功能码 | 数据长度 | 数据 |
2byte | 2byte | 2byte | 1byte | 1byte | 1byte | n byte |
1.主函数
int main(void) { /* USER CODE BEGIN 1 */ int cnt; short data; /* USER CODE END 1 */ /*MCU Configuration------------------------------------*/ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ i2c.initialize(); axp152.initialize(); axp152.set_dcdc1(3500);//[ARM & FPGA BK1/2/6 &OTHER] axp152.set_dcdc2(1200);//[FPGA INT & PLL D] axp152.set_aldo1(2500);//[FPGA PLL A] axp152.set_dcdc4(3300);//[POWER_OUTPUT] axp152.set_dcdc3(3300);//[FPGA BK4][Adjustable] axp152.set_aldo2(3300);//[FPGA BK3][Adjustable] axp152.set_dldo1(3300);//[FPGA BK7][Adjustable] axp152.set_dldo2(3300);//[FPGA BK5][Adjustable] /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); MX_ADC3_Init(); MX_ETH_Init(); /* USER CODE BEGIN 2 */ //LWIP初始化 NETMPU_Config(); lwip.initialize(); eth_tcps.initialize(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if((cnt ++ / 800000) % 2){ LED_RED_ON; }else{ LED_RED_OFF; } lwip.periodic_handle(); //根据定时器计数标志,每隔一秒,读取一次ADC的值 if(adc_read_flag ==1) { adc_read_flag = 0; my_adc.read(0); my_adc.read_mux(); } //将ADC采集的计算值,放大1000倍便于观察数据的正确性。计算公式请参考adc部分例程。 data = my_adc.value[0]*6000; hold_reg[0] = data >> 8; hold_reg[1] = data & 0xff; data = my_adc.value[1] * 2000; hold_reg[2] = data >> 8; hold_reg[3] = data & 0xff; data = my_adc.value[2]*2000; hold_reg[4] = data >> 8; hold_reg[5] = data & 0xff; data = my_adc.value[3]*2000; hold_reg[6] = data >> 8; hold_reg[7] = data & 0xff; data = my_adc.value[4]*2000; hold_reg[8] = data >> 8; hold_reg[9] = data & 0xff; data = my_adc.value[5]*500;·· hold_reg[10] = data >> 8; hold_reg[11] = data & 0xff; data = my_adc.value[6]*1000; hold_reg[12] = data >> 8; hold_reg[13] = data & 0xff; data = my_adc.value[7]*2000; hold_reg[14] = data >> 8; hold_reg[15] = data & 0xff; data = my_adc.value[8]*2000; hold_reg[16] = data >> 8; hold_reg[17] = data & 0xff; if(eth_tcps.receive_ok_flag == 1){ eth_tcps.receive_ok_flag = 0; modbus_tcp.process(eth_tcps.receive_buffer); } } /* USER CODE END 3 */ }
2.TCP数据发送函数
int send(struct tcp_pcb *tpcb,unsigned char *data,int len) { int ret_err; struct tcp_server_struct *es; memcpy(eth_tcps.send_buffer,data,len); es = tpcb->callback_arg; if(es != NULL){ //连接处于空闲可以发送数据 es->p = pbuf_alloc(PBUF_TRANSPORT,len,PBUF_POOL);//申请内存 pbuf_take(es->p,(char*)eth_tcps.send_buffer,len);//将eth_tcps.send_buffer[]中的数据拷贝到es->p_tx中 tcp_server_senddata(tpcb,es); //将eth_tcps.send_buffer[]里面复制给pbuf的数据发送出去 if(es->p)pbuf_free(es->p); //释放内存 ret_err=ERR_OK; }else{ tcp_abort(tpcb); //终止连接,删除pcb控制块 ret_err=ERR_ABRT; } return ret_err; }
3.Modbus TCP协议处理
int err; char discrete_input[32] = {0x55,0x55,0x55}; char coil[32] = {0x55,0x55,0x55}; char input_reg[20] = {0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10}; char hold_reg[512] = {0x01,0x02,0x03}; //--------------------------- Function --------------------------// static int process(unsigned char *modbus_recvbuf) { unsigned char receive_buffer_temp[100]; memcpy(receive_buffer_temp,modbus_recvbuf,12); memset(modbus_recvbuf,0,12); mb_rsq_pdu(receive_buffer_temp,12); return 0; } static int mb_rsq_pdu(unsigned char *receive_buffer_temp,int counter_temp) { if(receive_buffer_temp[0 + 6] == 0x01){ switch(receive_buffer_temp[1 + 6]){ case 1: function_1(receive_buffer_temp); break; case 2: function_2(receive_buffer_temp); break; case 3: function_3(receive_buffer_temp); break; case 4: function_4(receive_buffer_temp); break; case 5: function_5(receive_buffer_temp,counter_temp); break; case 6: function_6(receive_buffer_temp,counter_temp); break; default : mb_excep_rsq_pdu(receive_buffer_temp,1); break; } }else if(receive_buffer_temp[0 + 6] == 0){ broadcast(receive_buffer_temp); } return 0; } static int function_1(unsigned char *receive_buffer_temp) { int i; unsigned short cnt; unsigned short coil_num; unsigned short start_address; int temp = 0; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; coil_num = receive_buffer_temp[4 + 6] << 8| receive_buffer_temp[5 + 6]; if((start_address + coil_num) > 255){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } receive_buffer_temp[2 + 6] = ((coil_num % 8 )? (coil_num / 8 + 1) : (coil_num / 8)); cnt = receive_buffer_temp[2 + 6] + 5 - 2; if(coil_num % 8){ if(coil_num < 8){ for(i = 0;i < coil_num;i ++)temp |= 1 << i; receive_buffer_temp[3 + 6] = ((coil[start_address / 8]) >> (start_address % 8) | (coil[start_address / 8 + 1]) << (8 - (start_address % 8))) & temp; }else { for(i = 0;i < receive_buffer_temp[2 + 6] - 1;i++)receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8]) >> (start_address % 8) | (coil[i + start_address / 8 + 1]) << (8 - (start_address % 8)); receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8] << ((8 - (coil_num % 8 - start_address % 8) % 8)) & 0xff) >> (8 - (coil_num % 8)); } }else { for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[3 + i + 6] = (coil[i + start_address / 8]) >> (start_address % 8) | (coil[i + start_address / 8 + 1]) << (8 - (start_address % 8)); } receive_buffer_temp[4] = (cnt & 0xff00) >> 8; receive_buffer_temp[5] = (cnt & 0x00ff); cnt = cnt + 6; eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,cnt); return 0; } static int function_2(unsigned char *receive_buffer_temp) { int i; unsigned short cnt; unsigned short discrete_num; unsigned short start_address; int temp = 0; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; discrete_num = receive_buffer_temp[4 + 6] << 8| receive_buffer_temp[5 + 6]; if((start_address + discrete_num) > 255){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } receive_buffer_temp[2 + 6] = ((discrete_num % 8 )? (discrete_num / 8 + 1) : (discrete_num / 8)); cnt = receive_buffer_temp[2 + 6] + 5 - 2; if(discrete_num % 8){ if(discrete_num < 8){ for(i = 0;i < discrete_num;i ++)temp |= 1 << i; receive_buffer_temp[3 + 6] = ((discrete_input[start_address / 8]) >> (start_address % 8) | (discrete_input[start_address / 8 + 1]) << (8 - (start_address % 8))) & temp; }else { for(i = 0;i < receive_buffer_temp[2 + 6] - 1;i++)receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8]) >> (start_address % 8) | (discrete_input[i + start_address / 8 + 1]) << (8 - (start_address % 8)); receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8] << ((8 - (discrete_num % 8 - start_address % 8) % 8)) & 0xff) >> (8 - (discrete_num % 8)); } }else { for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[3 + i + 6] = (discrete_input[i + start_address / 8]) >> (start_address % 8) | (discrete_input[i + start_address / 8 + 1]) << (8 - (start_address % 8)); } receive_buffer_temp[4] = (cnt & 0xff00) >> 8; receive_buffer_temp[5] = (cnt & 0x00ff); cnt = cnt + 6; eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,cnt); return 0; } static int function_3(unsigned char *receive_buffer_temp) { int i; int cnt = 0; unsigned short int start_address; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; receive_buffer_temp[2 + 6] = receive_buffer_temp[5 + 6] * 2; if(receive_buffer_temp[2 + 6] > 48){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } if((start_address * 2 + receive_buffer_temp[2]) > 512){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } cnt = receive_buffer_temp[2 + 6] + 5 - 2; for(i = 0;i < receive_buffer_temp[2 + 6];i++){ receive_buffer_temp[i + 3 + 6] = hold_reg[start_address * 2 + i]; } receive_buffer_temp[4] = (cnt & 0xff00) >> 8; receive_buffer_temp[5] = (cnt & 0x00ff); cnt = cnt + 6; eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,cnt); return 0; } static int function_4(unsigned char *receive_buffer_temp) { int i; int cnt; unsigned short int start_address; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; receive_buffer_temp[2 + 6] = receive_buffer_temp[5 + 6] * 2; if((start_address * 2 + receive_buffer_temp[2 + 6]) > 20){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } cnt = receive_buffer_temp[2 + 6] + 5 - 2; for(i = 0;i < receive_buffer_temp[2 + 6];i++)receive_buffer_temp[i + 3 + 6] = input_reg[start_address * 2 + i]; receive_buffer_temp[4] = (cnt & 0xff00) >> 8; receive_buffer_temp[5] = (cnt & 0x00ff); cnt = cnt + 6; eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,cnt); return 0; } static int function_5(unsigned char *receive_buffer_temp,int counter_temp) { unsigned short start_address; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; if(start_address > 255){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } if((receive_buffer_temp[4 + 6] == 0xff) && (receive_buffer_temp[5 + 6] == 0x00)){ coil[(start_address / 8)] |= 1 << start_address % 8; }else if((receive_buffer_temp[4 + 6] == 0x00) && (receive_buffer_temp[5 + 6] == 0x00)){ coil[(start_address / 8)] &= ~(1 << start_address % 8); }else { mb_excep_rsq_pdu(receive_buffer_temp,3); } receive_buffer_temp[4] = (6 & 0xff00) >> 8; receive_buffer_temp[5] = (6 & 0x00ff); eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,counter_temp); return 0; } static int function_6(unsigned char *receive_buffer_temp,int counter_temp) { unsigned short start_address; start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; if(start_address > 255){ mb_excep_rsq_pdu(receive_buffer_temp,2); return 1; } hold_reg[start_address * 2] = receive_buffer_temp[4 + 6]; hold_reg[start_address * 2 + 1] = receive_buffer_temp[5 + 6]; receive_buffer_temp[4] = (6 & 0xff00) >> 8; receive_buffer_temp[5] = (6 & 0x00ff); eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,counter_temp); return 0; } static int mb_excep_rsq_pdu(unsigned char *receive_buffer_temp,int error_code) { receive_buffer_temp[1 + 6] |= 0x80; switch(error_code) { case 1: receive_buffer_temp[2 + 6] = 1; break; case 2: receive_buffer_temp[2 + 6] = 2; break; case 3: receive_buffer_temp[2 + 6] = 3; break; case 4: receive_buffer_temp[2 + 6] = 4; break; default : break; } receive_buffer_temp[4] = (3 & 0xff00) >> 8; receive_buffer_temp[5] = (3 & 0x00ff); eth_tcps.send(eth_tcps.tcppcbnew,receive_buffer_temp,9); return 0; } static int broadcast(unsigned char *receive_buffer_temp) { int start_address; switch(receive_buffer_temp[1 + 6]){ case 5: start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; if(start_address > 255){ return 1; } if((receive_buffer_temp[4 + 6] == 0xff) && (receive_buffer_temp[5 + 6] == 0x00)){ coil[(start_address / 8)] |= 1 << start_address % 8; }else if((receive_buffer_temp[4 + 6] == 0x00) && (receive_buffer_temp[5 + 6] == 0x00)){ coil[(start_address / 8)] &= ~(1 << start_address % 8); } break; case 6: start_address = (receive_buffer_temp[2 + 6] << 8) | receive_buffer_temp[3 + 6]; if(start_address > 255){ return 1; } hold_reg[start_address * 2] = receive_buffer_temp[4 + 6]; hold_reg[start_address * 2 + 1] = receive_buffer_temp[5 + 6]; break; } return 0; }