/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-05-16 lijian the first version */ #include #define POLY 0x1021 // CRC-16-CCITT多项式 DATU_t DATU; rt_uint16_t CRC16_Calculate(rt_uint8_t *data, rt_uint8_t len) { rt_uint16_t CRC16in = 0xFFFF; rt_uint16_t CPoly = 0xA001; /*0x8005高低位交换*/ while (len--) { CRC16in ^= *(data++); for(rt_uint8_t i = 0;i < 8;i++) { if(CRC16in & 0x01) CRC16in = (CRC16in >> 1) ^ CPoly; else CRC16in = CRC16in >> 1; } } CRC16in = CRC16in % 256 * 256 + CRC16in / 256; /*调换高低Byte*/ return (CRC16in); } rt_uint8_t read_cmd(rt_uint8_t read_buf[], rt_uint8_t read_len) { uint8_t correct_header[] = { 0x44, 0x41, 0x54, 0x55 }; if (memcmp(read_buf, correct_header, sizeof(correct_header)) == 0){ if (read_buf[4] == 0x03) { return 3; } else if (read_buf[4] == 0x06){ return 6; } else{ return -2; } } else{ return -1; } } void datu_init() { rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_MASTER_SERIAL, RS485_SAMPLE_MASTER_BAUDRATE, RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_MASTER_PIN, RS485_SAMPLE_MASTER_LVL); if (hinst == RT_NULL) { rt_kprintf("create rs485 instance fail.\n"); return; } rs485_set_recv_tmo(hinst, 1000); if (rs485_connect(hinst) != RT_EOK) { rs485_destory(hinst); rt_kprintf("rs485 connect fail.\n"); return; } // rt_kprintf("Running."); rt_int8_t send_len; // rt_uint8_t send_buf[128]; rt_uint8_t send_buf[16] = { 'D', 'A', 'T', 'U', 0x01, 0x02, 0x03, 0x04, 0x05 }; rt_uint8_t read_buf[10]; rt_int8_t read_len; rt_uint8_t i; rt_int8_t rc; while (1) { /** 数据识别序列 数据内容 校验字 44 41 54 55 00 00 00 00 00 00 00 00 00 00 CRC B0,B1,B2,B3 B4--B7 B8,B9 B10,B11 B12,B13 B14,B15 D, A, T, U 主轴针数 面线1张力值 面线2张力值 传感器状态 B4--B13的16位CRC * */ rt_thread_mdelay(100); // || 有针数 if (DATU.send_data ) { rt_uint16_t crc = CRC16_Calculate(send_buf + 4, 10); // rt_kprintf("CRC %x\n ", crc); send_buf[14] = crc >> 8; send_buf[15] = crc & 0xFF; send_len = rs485_send(hinst, (void *) send_buf, sizeof(send_buf)); DATU.send_data =0; } if (DATU.log) { rt_kprintf("rs485 send %d datas : ", send_len); for (i = 0; i < send_len; i++) { rt_kprintf("%02X ", send_buf[i]); } rt_kprintf("\n"); send_len = 0; } // read_len = rs485_send_then_recv(hinst, (void *) send_buf, sizeof(send_buf), read_buf, sizeof(read_buf)); read_len = rs485_recv(hinst, (void *) read_buf, sizeof(read_buf)); if (read_len < 0) { if (DATU.log) { rt_kprintf("rs485 read datas error.\n"); } continue; } else if (read_len == 0) { if (DATU.log) { rt_kprintf("rs485 read timeout.\n"); } continue; } //read_buf[read_len] = 0; if (DATU.log) { rt_kprintf("rs485 read %d datas : ", read_len); for (i = 0; i < read_len; i++) { rt_kprintf("%2X ", read_buf[i]); } rt_kprintf("\n"); } //CRC校验 rt_uint16_t received_crc = (read_buf[7] << 8) | read_buf[8]; rt_kprintf("CRC %x\n ", received_crc); rt_uint16_t calculated_crc = CRC16_Calculate(read_buf+4, 3); rt_kprintf("CRC %x\n ", calculated_crc); if (calculated_crc == received_crc) { if (DATU.log) { rt_kprintf("read datas CRC OK\n"); } } else { if (DATU.log) { rt_kprintf("read datas CRC ERR\n"); } continue; } rc = read_cmd(read_buf, read_len); if (rc == -1) { if (DATU.log) { rt_kprintf("read header is not DATU.\n"); } continue; } else if (rc == -2) { if (DATU.log) { rt_kprintf("read cmd is not 0x03 / 0x06.\n"); } continue; } else if (rc == 3) { if (DATU.log) { rt_kprintf("read cmd is 0x03.\n"); } DATU.send_data =1; continue; } else if (rc == 6) { if (DATU.log) { rt_kprintf("read cmd is 0x06.\n"); rt_kprintf("read cmd is %d .\n",read_buf[6]); } switch (read_buf[6]) { case 1: //主轴针数清零 break; case 2: //闪灯 // IO_key(1, argv); break; case 3: //开锁1 break; case 4: //开锁2 break; case 5: //开锁3 break; case 6: //报警灯开 break; case 7: //报警灯关 break; default: break; } } } } void set_DATU_log(rt_uint8_t log) { DATU.log = log; }