// #include "stdio.h" // #include "stdlib.h" #include "SWM320.h" #include "debug.h" #include "uart_Net.h" /********************************************************** 行注释 内容:系统配置内容 **********************************************************/ //传送物理参数 static NET_PHY_PROP uartPhy = { .BandRate = 115200, .TransportDistance = 2000000, .CalMessageLen = UartBusMessageLenCal, }; //报文定义 //定义报文长度使用const,因为驱动需要知道到底长度是多少 #define SOURCE_ADDR_LEN 2 #define DEST_ADDR_LEN 2 #define DATE_LEN 18 #define CRC_LEN 1 typedef struct { u8 sourceAddress[SOURCE_ADDR_LEN]; //源地址 u8 destinationAddress[DEST_ADDR_LEN]; //目标地址 u8 date[DATE_LEN]; //数据 u8 crc[CRC_LEN]; // CRC校验 } NET_MSG; //设置地址 static NET_MSG msg = { .sourceAddress[0] = 0x00, .sourceAddress[1] = 0x01, }; // CRC设置 #define USE_CRC_8 1 /********************************************************** 行注释 内容:HAL层 **********************************************************/ /** * @brief 串口初始化 * */ static void SerialInit(void) { UART_InitStructure UART_initStruct; PORT_Init(PORTC, PIN4, FUNMUX0_UART1_RXD, 1); // GPIOA.2配置为UART0输入引脚 PORT_Init(PORTC, PIN5, FUNMUX1_UART1_TXD, 0); // GPIOA.3配置为UART0输出引脚 UART_initStruct.Baudrate = 115200; UART_initStruct.DataBits = UART_DATA_8BIT; UART_initStruct.Parity = UART_PARITY_NONE; UART_initStruct.StopBits = UART_STOP_1BIT; UART_initStruct.RXThreshold = 0; UART_initStruct.RXThresholdIEn = 1; UART_initStruct.TXThreshold = 3; UART_initStruct.TXThresholdIEn = 0; UART_initStruct.TimeoutTime = 1; // 10个字符时间内未接收到新的数据则触发超时中断 UART_initStruct.TimeoutIEn = 0; UART_Init(UART1, &UART_initStruct); UART_Open(UART1); } // uart发送的数据缓存 static u8 uartDate = 0; // uart接收的数据和发送的数据是否相同1:相同,0不同 static volatile u8 uartRight = 0; // uart是出于发送还是接收状态1:发送,0接收 static volatile u8 uartSend = 0; void UART1_Handler(void) { if (UART_INTRXThresholdStat(UART1) || UART_INTTimeoutStat(UART1)) { u32 chr; // Printf("x"); while (UART_IsRXFIFOEmpty(UART1) == 0) { if (UART_ReadByte(UART1, &chr) == 0) { if (uartSend == 1) { if ((u8)chr == uartDate) { uartRight = 1; Printf("%c", (u8)chr); } } else { } } } } } /** * @description: 读取UART数据 interface * @return {*} uart数据 */ static u8 NetRead() { } /** * @description: 写入UART数据 interface * @return {*} */ static void NetWrite(u8 data) { uartDate = data; uartRight = 0; UART_WriteByte(UART1, (u32)data); while (UART_IsTXBusy(UART1)) ; } /** * @description: NET实现软件定时器 * @param {void} *hdl 要执行的函数 * @param {void} *priv 要执行函数的参数 * @param {u8} time 定时时间(ms) * @return {*} */ static void NetSorftTimer(void *hdl, void *priv, u8 time) { } // #define NetPrint(format, ...) Printf(format, ##__VA_ARGS__) /*-----------------------------------------------------------分割线---------------------------------------------*/ /********************************************************** 行注释 内容:系统驱动代码 **********************************************************/ /** * @brief 计算uart报文段长度 * * @return u32 报文长度,bit */ u32 UartBusMessageLenCal(void *priv) { NET_PHY_PROP *tis = (NET_PHY_PROP *)priv; float distance = (float)tis->TransportDistance; float deltaTime = distance / (200000000) * 2; tis->MessageLenMin = (distance / (tis->BandRate) + 1); } #if (USE_CRC_8) // CRC 8 的除数是9位,但是最高位为1,不需要计算 const u8 CRC8 = 0x31; /********************************************************** 行注释 内容: 1. 计算机实现CRC方法: crc 8 算法分析 计算16数据 1011001100111010 00110001 结果 11010110 只计算u8数,后面补0 2 1011001100000000 00110001 11010111 结果 11101100 3.将后面的u8与计算结果亦或 11101100 00111010 11010110 发现可以还原 2. CRC加密还原方法 加密:数据直接调用函数加密 解密:数据最后一位加上CRC值,如果CRC结果=0则CRC校验通过 **********************************************************/ // void ptb(u8 data) // { // u8 str[10]; // itoa(data, str, 2); // printf("%s\n", str); // } /** * @brief * * @param data * @param len * @return u8 */ u8 CRC_8_ENC(u8 *data, u32 len) { u8 crc = 0; for (u32 i = 0; i < len; i++) { crc ^= *(data++); for (u32 j = 0; j < 8; j++) { if (crc & 0x80) { crc = crc << 1; crc ^= CRC8; } else { crc = crc << 1; } } } return crc; } #endif /** * @brief 发送函数基础 * * @param data 数据 * @param len 长度 * @param destAddr 目标地址 * @return u32 */ u32 NetSendBase(u8 *data, u32 len, u8 *destAddr) { /********************************************************** 行注释 内容:写入目的地址 **********************************************************/ for (u32 i = 0; i < DEST_ADDR_LEN; i++) { msg.destinationAddress[i] = destAddr[i]; } // NetPrint("dest addr write\n"); /********************************************************** 行注释 内容:拷贝数据,超出位填写0x00 **********************************************************/ for (u32 i = 0; i < DATE_LEN; i++) { if (i <= DATE_LEN) { msg.date[i] = data[i]; } else { msg.date[i] = 0; } } // NetPrint("data write\n"); /********************************************************** 行注释 内容:填充CRC计算结果 **********************************************************/ #if (USE_CRC_8) msg.crc[0] = CRC_8_ENC(msg.date, sizeof(msg.date)); #endif // NetPrint("crc cal\n"); /********************************************************** 行注释 内容:发送数据 **********************************************************/ u8 *dataTram = (u8 *)&msg; // NetPrint("start send\n"); uartSend = 1; for (u32 i = 0; i < sizeof(msg); i++) { NetWrite(dataTram[i]); u32 time = 1000; while (time--) { if (uartRight == 1) { break; } } if (uartRight == 0) { return MSG_SEND_MAY_ERR; } } uartSend = 0; return 0; } /** * @brief 总线发送错误的报文,通知其他设备发生了传输错误 * */ void NetSendErrPage(){ for (u32 i = 0; i < DATE_LEN/2; i++){ } } /** * @brief Net发送函数 * * @param data * @param len * @param destAddr * @return u32 */ u32 NetSend(u8 *data, u32 len, u8 *destAddr) { while (len) { if (len > DATE_LEN) { NetSendBase(data, DATE_LEN, destAddr); len -= DATE_LEN; data += DATE_LEN; } else { NetSendBase(data, len, destAddr); len = 0; } } } /** * @brief * * @param data * @param len */ void NetReceive(u8 *data, u32 len) { } /** * @brief 网络初始化 * */ u32 NetInit() { /********************************************************** 行注释 内容:检查报文段定义长度下限 **********************************************************/ uartPhy.CalMessageLen(&uartPhy); NetPrint("MessageLenMin= %d\n", uartPhy.MessageLenMin); if ((sizeof(NET_MSG) < uartPhy.MessageLenMin)) { NetPrint("ERROR:MSG_LEN_TOO_SHORT"); return MSG_LEN_TOO_SHORT; } /********************************************************** 行注释 内容:检查报文段定义长度上限 **********************************************************/ #if (USE_CRC_8) if (sizeof(NET_MSG) > 64) { NetPrint("ERROR:MSG_LEN_TOO_LONG"); return MSG_LEN_TOO_LONG; } #endif /********************************************************** 行注释 内容:串口初始化 **********************************************************/ SerialInit(); return 0; }