360 lines
8.7 KiB
C
360 lines
8.7 KiB
C
// #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;
|
||
}
|