初始版本
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2018, Huada Semiconductor Co.,Ltd All rights reserved.
|
||||
*
|
||||
* This software is owned and published by:
|
||||
* Huada Semiconductor Co.,Ltd ("HDSC").
|
||||
*
|
||||
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
|
||||
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
|
||||
*
|
||||
* This software contains source code for use with HDSC
|
||||
* components. This software is licensed by HDSC to be adapted only
|
||||
* for use in systems utilizing HDSC components. HDSC shall not be
|
||||
* responsible for misuse or illegal use of this software for devices not
|
||||
* supported herein. HDSC is providing this software "AS IS" and will
|
||||
* not be responsible for issues arising from incorrect user implementation
|
||||
* of the software.
|
||||
*
|
||||
* Disclaimer:
|
||||
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
|
||||
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
|
||||
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
|
||||
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
|
||||
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
|
||||
* WARRANTY OF NONINFRINGEMENT.
|
||||
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
|
||||
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
|
||||
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
|
||||
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
|
||||
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
|
||||
* SAVINGS OR PROFITS,
|
||||
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
|
||||
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
|
||||
* FROM, THE SOFTWARE.
|
||||
*
|
||||
* This software may be replicated in part or whole for the licensed use,
|
||||
* with the restriction that this Disclaimer and Copyright notice must be
|
||||
* included with each copy of this software, whether used in part or whole,
|
||||
* at all times.
|
||||
*/
|
||||
/******************************************************************************/
|
||||
/** \file ddl_device.h
|
||||
**
|
||||
** Device define
|
||||
** @link SampleGroup Some description @endlink
|
||||
**
|
||||
** - 2018-04-15
|
||||
**
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __DDL_DEVICE_H__
|
||||
#define __DDL_DEVICE_H__
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
** \brief Global device series definition
|
||||
**
|
||||
** \note
|
||||
******************************************************************************/
|
||||
#define DDL_MCU_SERIES DDL_DEVICE_SERIES_HC32L17X
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
** \brief Global package definition
|
||||
**
|
||||
** \note This definition is used for device package settings
|
||||
******************************************************************************/
|
||||
#define DDL_MCU_PACKAGE DDL_DEVICE_PACKAGE_HC_K
|
||||
|
||||
#endif /* __DDL_DEVICE_H__ */
|
||||
|
||||
/*******************************************************************************
|
||||
* EOF (not truncated)
|
||||
******************************************************************************/
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef __ALGORITHM_H
|
||||
#define __ALGORITHM_H
|
||||
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define CRC16_BASE 0xA001
|
||||
|
||||
|
||||
// 峰值谷值检查结果结构体
|
||||
typedef struct {
|
||||
bool peaks_positive; // 所有峰值是否大于0
|
||||
bool valleys_negative; // 所有谷值是否小于0
|
||||
int peak_count; // 检测到的峰值数量
|
||||
int valley_count; // 检测到的谷值数量
|
||||
} PeakValleyCheck;
|
||||
|
||||
// 趋势分析结果结构体
|
||||
typedef struct {
|
||||
double slope; // 线性斜率
|
||||
int sign_changes; // 符号变化次数
|
||||
char trend_type; // 趋势类型
|
||||
char steepness; // 陡峭度
|
||||
} TrendResult;
|
||||
|
||||
PeakValleyCheck check_peaks_valleys(int data[], int length);
|
||||
TrendResult analyze_trend(int data[], int length);
|
||||
float calculateAverage(int *arr, int size);
|
||||
double slope(int32_t *x_data, int32_t *y_data, int n) ;
|
||||
long long power(int base, unsigned int exponent);
|
||||
int IntFilter_16t(int16_t *Data, uint8_t Cnt, uint8_t FilterCnt);
|
||||
int IntFilter_32t(int32_t *Data, uint8_t Cnt, uint8_t FilterCnt);
|
||||
uint32_t IntFilter_u32t(uint32_t *Data, uint8_t Cnt, uint8_t FilterCnt);
|
||||
float IntFilter_Float(float *Data, uint8_t Cnt, uint8_t FilterCnt);
|
||||
uint32_t AverageFilter_u32t(uint32_t *Data, uint8_t Cnt);
|
||||
int AverageFilter_32t(int32_t *Data, uint8_t Cnt);
|
||||
void Fitting_Polynomial(double *AD, double *Actual, uint8_t Cnt);
|
||||
float get_K(uint8_t count , int32_t *dataCol_X, int32_t *dataRow_Y);
|
||||
int8_t TrendAnalyse(int32_t *Data, uint8_t Cnt, int32_t VPT);
|
||||
void Waveform_Up(int32_t *Data, uint8_t dCnt, uint8_t pCnt, int32_t *vlue);
|
||||
void Waveform_Down(int32_t *Data, uint8_t dCnt, uint8_t pCnt, int32_t *vlue);
|
||||
bool count_most_greater(int32_t *arr, uint8_t size, int32_t target);
|
||||
bool count_greater(int32_t *arr, uint8_t size, int32_t target);
|
||||
bool count_smaller(int32_t *arr, uint8_t size, int32_t target);
|
||||
uint16_t CRC_Modbus(uint16_t wBase, uint8_t *para, uint16_t length);
|
||||
uint8_t CRC_Sum(uint8_t *_pbuff, uint16_t _cmdLen);
|
||||
bool isAllZero(uint8_t *arr, int size);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
/* 传感器通用通讯协议V1.0*/
|
||||
|
||||
#ifndef __SGCP_H
|
||||
#define __SGCP_H
|
||||
#include "bsp.h"
|
||||
|
||||
#define WORK_MODE 1 //工作模式选择,0、本机为查询模式,1、本机为上报模式(低功耗)
|
||||
#define SGCP_SELECT 1 //协议选择,0、本机为单个主设备接多个子设备,1、本机为单个主设备不接子设备,2、本机为单个子设备
|
||||
#define LocalDataLen sizeof(SGCP.DevData.LaserTracing)//本机设备数据长度
|
||||
#define LocalType LASER_TRACING //本机设备类型
|
||||
#define CommWay LORA //本机通讯方式
|
||||
#define DeviceSign MASTER //本机设备标志
|
||||
#define AddNumber (0x000017 + DeviceSign)//本机地址编号,数字部分对应唯一地址编号
|
||||
//09 00 01 00 00 00
|
||||
|
||||
typedef struct {//网关与主设备固定帧
|
||||
uint8_t Header;
|
||||
uint8_t GWAddr[6];
|
||||
uint8_t MDAddr[6];
|
||||
uint8_t Cmd;
|
||||
uint16_t PayloadLen;
|
||||
}__attribute__ ((packed))GatewayFrameHeader_t,*GatewayFrameHeader;
|
||||
|
||||
typedef struct {//主设备与子设备固定帧
|
||||
uint8_t Header;
|
||||
uint8_t Addr;
|
||||
uint8_t Cmd;
|
||||
uint8_t PayloadLen;
|
||||
}__attribute__ ((packed))SubsetFrameHeader_t,*SubsetFrameHeader;
|
||||
|
||||
typedef struct {//内部指令固定帧
|
||||
uint8_t Header;
|
||||
uint8_t MAC[6];
|
||||
uint8_t Cmd;
|
||||
uint8_t PayloadLen;
|
||||
}__attribute__ ((packed))InsideFrameHeader_t,*InsideFrameHeader;
|
||||
|
||||
typedef struct {//主设备固定包头
|
||||
uint8_t BatLevel; //电池电量
|
||||
int8_t RSSI; //信号强度
|
||||
int8_t Nsr; //信噪比
|
||||
}__attribute__ ((packed))MasterDev_T,*MasterDevDp;
|
||||
|
||||
typedef struct {//0x0006 三维连续变形
|
||||
int16_t PitchAngle; //俯仰角 (范围±900)单位0.1°
|
||||
int16_t RollAngle; //横滚角 (范围±900)单位0.1°
|
||||
int16_t YawAngle; //偏航角 (范围0~3600)单位0.1°
|
||||
}__attribute__ ((packed))ContDefor3D_T,*ContDefor3DDp;
|
||||
|
||||
typedef struct {//0x0007 通讯单元
|
||||
MasterDev_T MasterDev;
|
||||
}__attribute__ ((packed))CommUnit_T,*CommUnitDp;
|
||||
|
||||
typedef struct {//0x0008 三维应力
|
||||
int16_t PitchAngle; //俯仰角(范围±900)单位0.1°
|
||||
int16_t RollAngle; //横滚角(范围±900)单位0.1°
|
||||
int16_t YawAngle; //偏航角(范围0~3600)单位0.1°
|
||||
int32_t Strain1; //X轴应力值(范围±10MPa,单位Pa)
|
||||
int32_t Strain2; //Y轴应力值(范围±10MPa,单位Pa)
|
||||
int32_t Strain3; //Z轴应力值(范围±10MPa,单位Pa)
|
||||
}__attribute__ ((packed))Force3D_T,*Force3DDp;
|
||||
|
||||
typedef struct {//0x0009 激光示踪
|
||||
MasterDev_T MasterDev;
|
||||
int16_t PitchAngle; //俯仰角 (范围±900)单位0.1°
|
||||
int16_t RollAngle; //横滚角 (范围±900)单位0.1°
|
||||
int16_t YawAngle; //偏航角 (范围0~3600)单位0.1°
|
||||
}__attribute__ ((packed))LaserTracing_T,*LaserTracingDp;
|
||||
|
||||
typedef struct {//0x000E 裂缝仪
|
||||
int16_t XwiseDist; //横向位移量(范围0~150mm)
|
||||
int16_t LgthwysDist; //纵向位移距离(范围0~150mm)
|
||||
int16_t RotationDist; //旋转位移距离(范围0~150mm)
|
||||
}__attribute__ ((packed))Crack_T,*CrackDp;
|
||||
|
||||
typedef struct {
|
||||
ContDefor3D_T ContDefor3D;
|
||||
CommUnit_T CommUnit;
|
||||
Force3D_T Force3D;
|
||||
Crack_T Crack;
|
||||
LaserTracing_T LaserTracing;
|
||||
}__attribute__ ((packed))DeviceData_T,*DeviceDp; //设备数据
|
||||
|
||||
/*接收子设备数据状态机*/
|
||||
typedef enum {
|
||||
SUB_STATUS_IDLE,
|
||||
SUB_STATUS_BROADCAST_CALI,
|
||||
SUB_STATUS_READMASTER_DATA,
|
||||
SUB_STATUS_READSUBSET_DATA,
|
||||
SUB_STATUS_WAIT_READSUBSET,
|
||||
SUB_STATUS_MASTER_QUERY,
|
||||
SUB_STATUS_SUBSET_QUERY,
|
||||
SUB_STATUS_WAIT_SUBSET_QUERY,
|
||||
SUB_STATUS_BROADCAST_SET_COLTIME,
|
||||
SUB_STATUS_BROADCAST_SYNC_TIME,
|
||||
}SubStatus_m;
|
||||
|
||||
/*接收网关数据状态机*/
|
||||
typedef enum {
|
||||
GW_STATUS_IDLE,
|
||||
GW_STATUS_WAIT_SUBIDLE,
|
||||
GW_STATUS_LOGIN,
|
||||
GW_STATUS_WAIT_LOGIN,
|
||||
GW_STATUS_CALI,
|
||||
GW_STATUS_READ_SENSOR,
|
||||
GW_STATUS_SET_COL_TIME,
|
||||
GW_STATUS_SYNC_TIME,
|
||||
GW_STATUS_UPLOAD_SENSOR,//主动上报模式时会使用该状态
|
||||
GW_STATUS_WAIT_UPLOAD,//主动上报模式时会使用该状态
|
||||
GW_STATUS_LASER_STARES,//激光状态回应
|
||||
}GWStatus_m;
|
||||
/*接收主设备数据状态机*/
|
||||
typedef enum {
|
||||
MAS_STATUS_IDLE,
|
||||
MAS_STATUS_CALI,
|
||||
MAS_STATUS_READ_SENSOR,
|
||||
MAS_STATUS_DEVICE_INQUIRE,
|
||||
MAS_STATUS_SET_COL_TIME,
|
||||
MAS_STATUS_SYNC_TIME,
|
||||
}MasStatus_m;
|
||||
/*内部指令数据状态机*/
|
||||
typedef enum {
|
||||
IN_STATUS_IDLE,
|
||||
IN_STATUS_UPDATE,
|
||||
IN_STATUS_ALTER_485ADDR,
|
||||
}InStatus_m;
|
||||
/*网关到主设备命令集*/
|
||||
typedef enum {
|
||||
GWTOMD_CMD_LOGIN = 0x00, //0x00,设备注册
|
||||
GWTOMD_CMD_CALI = 0x01, //0x01, 校准指令
|
||||
GWTOMD_CMD_READ_UPLOAD_SENSOR = 0x02, //0x02,读取数据指令or上传数据指令
|
||||
GWTOMD_CMD_SET_COL_TIME = 0x05, //0x05,设置采集时间间隔
|
||||
GWTOMD_CMD_SYNC_TIME = 0x06, //0x06,时间同步
|
||||
GWTOMD_CMD_SET_LASER = 0x08,//打开or关闭激光
|
||||
}GWTOMD_CMD_M;
|
||||
|
||||
/*主设备到子设备命令集*/
|
||||
typedef enum {
|
||||
MDTOSD_CMD_CALI = 0x01, //0x01, 校准指令
|
||||
MDTOSD_CMD_READ_DATA = 0x02, //0x02,读取数据指令
|
||||
MDTOSD_CMD_INQUIRE = 0x03, //0x03, 设备查询指令
|
||||
MDTOSD_CMD_SET_COL_TIME = 0x05, //0x05,设置采集时间间隔
|
||||
MDTOSD_CMD_SYNC_TIME = 0x06, //0x06,时间同步
|
||||
}MDTOSD_CMD_M;
|
||||
/*内部指令命令集*/
|
||||
typedef enum {
|
||||
INSIDE_CMD_UPDATE = 0x81, //0x81,升级程序下发请求,由主机发起,从机应答
|
||||
INSIDE_CMD_ALTER_485ADDR = 0x04, //0x04, 设置设备485地址
|
||||
}INSIDE_CMD_M;
|
||||
/*设备类型*/
|
||||
typedef enum {
|
||||
NUL, //0x0000 空设备
|
||||
FORCE_6D, //0x0001 六维应力
|
||||
OSMOTIC_PRESSURE, //0x0002 渗透压
|
||||
ELASTIC_WAVEGUIDE, //0x0003 弹性波导
|
||||
DIELECTRIC_MASS, //0x0004 介电质普
|
||||
_0x0005, //0x0005 保留
|
||||
CONT_DEFOR_3D, //0x0006 三维连续变形
|
||||
COMM_UNIT, //0x0007 通讯单元
|
||||
FORCE_3D, //0x0008 三维应力
|
||||
LASER_TRACING, //0x0009 激光示踪
|
||||
_0x000A, //0x000A 保留
|
||||
_0x000B, //0x000B 保留
|
||||
_0x000C, //0x000C 保留
|
||||
MULTI_PARAMETER_FUSION, //0x000D 多参数融合
|
||||
CRACK_DETECTION, //0x000E 裂缝仪
|
||||
_0x000F, //0x000F 保留
|
||||
ATTITUDE_MONITOR, //0x0010 姿态检测
|
||||
LASER_DISPLACE, //0x0011 激光位移
|
||||
REBAR_STRESS, //0x0012 钢筋应力
|
||||
ANCHOR_ROD_STRESS, //0x0013 锚杆轴力
|
||||
SURFACE_STRESS, //0x0014 表面应力
|
||||
PRESSURE, //0x0015 压力
|
||||
MICROWAVE_DISPLACE, //0x0016 微波测距
|
||||
}DEVICE_TYPE_M;
|
||||
/*通讯方式*/
|
||||
typedef enum {
|
||||
LORA = 0x01, //0x01 LORA通讯
|
||||
RS485 = 0x02, //0x02 RS485通讯
|
||||
RS232 = 0x03, //0x03 RS232通讯
|
||||
CAN = 0x04, //0x04 CAN通讯
|
||||
_4G = 0x05, //0x05 _4G通讯
|
||||
BLE = 0x06, //0x06 BLE通讯
|
||||
WIFI = 0x07, //0x07 WIFI通讯
|
||||
UART = 0x08, //0x08 UART通讯
|
||||
}COMM_WAY_M;
|
||||
/*设备标志*/
|
||||
typedef enum {
|
||||
MASTER = 0x000000, //0x000000 主设备
|
||||
SUBSET = 0x800000, //0x800000 子设备
|
||||
}DEVICE_SIGN_M;
|
||||
typedef struct {
|
||||
__IO GWTOMD_CMD_M rCmdGWToMD; //网关下发命令
|
||||
__IO GWTOMD_CMD_M sCmdMDToGW; //主设备返回命令
|
||||
__IO uint16_t rPayLen;
|
||||
__IO bool HeaderFrame;
|
||||
__IO uint8_t RxLen;
|
||||
uint8_t RxBuff[256];
|
||||
}GWTOMD_Rx_T;
|
||||
|
||||
typedef struct {
|
||||
__IO MDTOSD_CMD_M rCmdSDToMD; //子设备返回命令
|
||||
__IO MDTOSD_CMD_M sCmdMDToSD; //主设备下发命令
|
||||
__IO uint8_t rPayLen;
|
||||
__IO bool HeaderFrame;
|
||||
__IO uint8_t RxLen;
|
||||
uint8_t RxBuff[256];
|
||||
}MDTOSD_Rx_T;
|
||||
|
||||
typedef struct {
|
||||
uint32_t LpUart0Delay1mSCnt;
|
||||
uint32_t LoraDelay1mSCnt;
|
||||
uint32_t Uart1Delay1mSCnt;
|
||||
uint32_t GW1mSDelayCnt;
|
||||
uint32_t SD1mSDelayCnt;
|
||||
uint32_t In1mSDelayCnt;
|
||||
|
||||
GWTOMD_Rx_T GWRS485Rx;
|
||||
uint8_t GatewayBuffLen;
|
||||
uint8_t GatewayBuff[256];
|
||||
uint8_t GatewayRevTimeoutCnt; //网关串口接收超时计数
|
||||
|
||||
MDTOSD_Rx_T SDRS485Rx;
|
||||
uint8_t SubsetBuffLen;
|
||||
uint8_t SubsetBuff[256];
|
||||
uint8_t SubsetRevTimeoutCnt; //子设备串口接收超时计数
|
||||
|
||||
uint8_t InsidePayLen;
|
||||
uint8_t InsideBuffLen;
|
||||
uint8_t InsideBuff[256];
|
||||
uint8_t InsidePay[256];
|
||||
|
||||
SubStatus_m SubStatus;
|
||||
SubStatus_m NextSubStatus;
|
||||
GWStatus_m GWStatus;
|
||||
GWStatus_m NextGWStatus;
|
||||
MasStatus_m MasStatus;
|
||||
InStatus_m InStatus;
|
||||
|
||||
DeviceData_T DevData;
|
||||
|
||||
bool SubsetCaliOk; //子设备校准标志位
|
||||
bool MasterCaliOk; //主设备标校标志位
|
||||
|
||||
uint8_t ReadDataAdd; //获取数据地址
|
||||
uint16_t DeviceDataLen; //在线设备采集到的数据长度总和
|
||||
uint8_t DeviceDataBuff[512]; //在线设备采集到的数据缓存(主设备的数据永远排在最前面)
|
||||
uint8_t DeviceData[512]; //在线设备采集到的数据(主设备的数据永远排在最前面)
|
||||
bool SubsetReadDataOk; //子设备读取数据成功标志位
|
||||
bool DeviceReadDataOk; //设备读取数据完成标志位
|
||||
|
||||
uint8_t DeviceN; //在线设备数量(最多32个子设备,1个主设备)
|
||||
uint8_t Dev485Addr; //在线设备485地址(最多32个子设备,1个主设备)
|
||||
uint8_t Dev485Addrs[16]; //在线设备485地址缓存,0位为0x00广播地址
|
||||
uint8_t DeviceMAC[16][6]; //在线设备的唯一MAC地址(主设备的MAC永远排在最前面)
|
||||
bool SubsetMACOk; //在线子设备MAC获取成功标志位
|
||||
bool DeviceMACOk; //在线设备获取完成标志位
|
||||
|
||||
bool CollTimeSetOk; //采集时间设置成功标志位
|
||||
uint8_t CollTimeAdd; //设置采集时间地址
|
||||
|
||||
bool SyncTimeOk; //时间同步成功标志位
|
||||
uint8_t SyncTimeAdd; //时间同步设备地址
|
||||
|
||||
bool BroadCmd; //广播命令
|
||||
|
||||
bool LoginOk; //注册成功标志位
|
||||
bool LoginMess;
|
||||
|
||||
bool UploadOk; //上传成功标志位
|
||||
bool UploadMess;
|
||||
|
||||
bool Gateway_IRQ_Status; //网关接收中断
|
||||
bool Subset_IRQ_Status; //子设备接收中断
|
||||
bool TimingAcquisition; //采集传感器数据
|
||||
|
||||
/**激光示踪私有**/
|
||||
bool LaserOnOff; //打开与关闭激光标志位
|
||||
}SGCP_t;
|
||||
extern SGCP_t SGCP;
|
||||
|
||||
void SGCP1mSRoutine(void);
|
||||
|
||||
void GwRevLoopHandler(void);
|
||||
void MasRevLoopHandler(void);
|
||||
void SubRevLoopHandler(void);
|
||||
void InRevLoopHandler(void);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef __UPDATE_H
|
||||
#define __UPDATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bsp.h"
|
||||
#include "UartDebug.h"
|
||||
|
||||
#define APP_START_FLAG 0x55AA5A5A
|
||||
#define APP_UPDATE_FLAG 0xA5A5AA55
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x200ul
|
||||
#define FLASH_BASE ((uint32_t)0x00000000)
|
||||
#define FLASH_SIZE (256u * FLASH_SECTOR_SIZE)
|
||||
|
||||
#define SRAM_BASE ((uint32_t)0x20000000)
|
||||
#define RAM_SIZE 0x2000ul
|
||||
|
||||
#define BOOT_ADDRESS FLASH_BASE
|
||||
#define BOOT_SIZE (20 * FLASH_SECTOR_SIZE)
|
||||
#define DEV_MAC_ADDRESS (BOOT_ADDRESS + BOOT_SIZE) //0x00002800
|
||||
#define DEV_MAC_SIZE FLASH_SECTOR_SIZE
|
||||
#define APP_ADDRESS (DEV_MAC_ADDRESS + DEV_MAC_SIZE)
|
||||
|
||||
#define BOOT_PARA_ADDRESS (0x0001FC00)//(FLASH_BASE + BOOT_SIZE)
|
||||
#define BOOT_PARA_SIZE (FLASH_SECTOR_SIZE)
|
||||
|
||||
typedef struct {
|
||||
uint32_t AppFlag;
|
||||
uint32_t UpdateFlag;
|
||||
uint32_t PackageCnt;
|
||||
uint32_t AppSize;
|
||||
uint32_t Crc32Check;
|
||||
}BootPara_t, *BootPara;
|
||||
|
||||
//主机下发升级请求载荷结构体
|
||||
typedef struct {
|
||||
uint16_t PackageNum;
|
||||
uint32_t AppSize;
|
||||
uint32_t AppCrc32;
|
||||
}__attribute__ ((packed))UpDataRequset_t, *UDReq;
|
||||
|
||||
//帧头结构体
|
||||
typedef struct {
|
||||
uint8_t Header;
|
||||
uint8_t DevMac[6];
|
||||
uint8_t Cmd;
|
||||
uint8_t PayloadLen;
|
||||
}__attribute__((packed))UpdateFrameHeader_t,*pUpdateFrameHeader;
|
||||
|
||||
|
||||
//输入接口函数定义,需根据接口重新定义
|
||||
#define U_DBG_LOG(...) DBG_LOG(__VA_ARGS__)
|
||||
#define U_DELAY_MS(x) delay_ms(x)
|
||||
#define U_SYSTEM_TESET() SystemReset()
|
||||
#define SAVE_BOOT_PARA(addr) FlashWrite(BOOT_PARA_ADDRESS, addr, sizeof(BLPara) / 4)
|
||||
#define READ_BOOT_PARA(addr) FlashRead(BOOT_PARA_ADDRESS, addr, sizeof(BLPara) / 4)
|
||||
|
||||
//输出接口
|
||||
void Update(uint8_t *PayLoad);
|
||||
void UpdateInit(void);
|
||||
#endif
|
||||
@@ -0,0 +1,271 @@
|
||||
#ifndef _BSP_H
|
||||
#define _BSP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "gpio.h"
|
||||
#include "spi.h"
|
||||
|
||||
/*模块启用与关闭*/
|
||||
#define USE_DEBUG 1 //调试串口选择,0、关闭,1、启用
|
||||
#define USE_VBAT_AD 1 //电池电压AD获取选择,0、关闭,1、启用
|
||||
#define USE_WDT 1 //看门狗选择,0、关闭,1启用
|
||||
#define USE_EXFALSE 0 //外部FALSE存储选择,0、关闭,1、启用
|
||||
#define USE_LED 1 //状态灯选择,0、关闭,1、启用
|
||||
#define USE_RTC 1 //RTC时钟开关,0、关闭,1、开启
|
||||
|
||||
#define USE_LPUART0 1 //LPUART0开关,0、关闭,1、启用
|
||||
#define USE_UART0 1 //UART0开关,0、关闭,1、启用
|
||||
#define USE_UART1 0 //UART0开关,0、关闭,1、启用
|
||||
#define USE_I2C0 1 //I2C0开关,0、关闭,1、启用
|
||||
#define USE_I2C1 1 //I2C1开关,0、关闭,1、启用
|
||||
#define USE_SPI0 1 //SPI1开关,0、关闭,1、启用
|
||||
#define USE_SPI1 0 //SPI1开关,0、关闭,1、启用
|
||||
|
||||
#define USE_BOOTLOADER 1 //BOOTLOADER开关,0、关闭,1、启用
|
||||
#define USE_LORA_CH 1 //0为测试通道
|
||||
|
||||
//<<---------------------------- MCU -------------------------------->>
|
||||
//< UART0
|
||||
#define UART0_TX_PORT GpioPortA
|
||||
#define UART0_TX_PIN GpioPin9
|
||||
#define UART0_TX_AF GpioAf1
|
||||
|
||||
#define UART0_RX_PORT GpioPortA
|
||||
#define UART0_RX_PIN GpioPin10
|
||||
#define UART0_RX_AF GpioAf1
|
||||
|
||||
//< UART1
|
||||
#define UART1_TX_PORT GpioPortF
|
||||
#define UART1_TX_PIN GpioPin0
|
||||
#define UART1_TX_AF GpioAf3
|
||||
|
||||
#define UART1_RX_PORT GpioPortF
|
||||
#define UART1_RX_PIN GpioPin1
|
||||
#define UART1_RX_AF GpioAf3
|
||||
|
||||
//< 低功耗串口
|
||||
#define LPUart0_TxPortx GpioPortB //低功耗串口0通道
|
||||
#define LPUART0_TxPinx GpioPin10 //配置PB10为LPUART0_Tx
|
||||
#define LPUART0_TX_AF GpioAf4
|
||||
|
||||
#define LPUart0_RxPortx GpioPortB //低功耗串口0通道
|
||||
#define LPUART0_RxPinx GpioPin11 //配置PB11为LPUART0_Rx
|
||||
#define LPUART0_RX_AF GpioAf3
|
||||
|
||||
//< SPI0
|
||||
#define SPI0_NSS_PORTx GpioPortA //NSSIO口
|
||||
#define SPI0_NSS_PINx GpioPin15 //配置PA04为NSS
|
||||
#define SET_SPI0_NSS() Gpio_SetIO(SPI0_NSS_PORTx, SPI0_NSS_PINx) //NSS拉高
|
||||
#define CLR_SPI0_NSS() Gpio_ClrIO(SPI0_NSS_PORTx, SPI0_NSS_PINx) //NSS拉低
|
||||
#define SPI0_NSS_AF GpioAf1
|
||||
|
||||
#define SPI0_SCK_PORTx GpioPortB //SCKIO口
|
||||
#define SPI0_SCK_PINx GpioPin3 //配置PA05为SCK
|
||||
#define SET_SPI0_SCK() Gpio_SetIO(SPI0_SCK_PORTx, SPI0_SCK_PINx) //SCK拉高
|
||||
#define CLR_SPI0_SCK() Gpio_ClrIO(SPI0_SCK_PORTx, SPI0_SCK_PINx) //SCK拉低
|
||||
#define SPI0_SCK_AF GpioAf1
|
||||
|
||||
#define SPI0_MISO_PORTx GpioPortB //MISOIO口
|
||||
#define SPI0_MISO_PINx GpioPin4 //配置PA06为MISO
|
||||
#define SET_SPI0_MISO() Gpio_SetIO(SPI0_MISO_PORTx, SPI0_MISO_PINx) //MISO拉高
|
||||
#define CLR_SPI0_MISO() Gpio_ClrIO(SPI0_MISO_PORTx, SPI0_MISO_PINx) //MISO拉低
|
||||
#define SPI0_MISO_AF GpioAf1
|
||||
|
||||
#define SPI0_MOSI_PORTx GpioPortB //MOSIIO口
|
||||
#define SPI0_MOSI_PINx GpioPin5 //配置PA07为MOSI
|
||||
#define SET_SPI0_MOSI() Gpio_SetIO(SPI0_MOSI_PORTx, SPI0_MOSI_PINx) //MOSI拉高
|
||||
#define CLR_SPI0_MOSI() Gpio_ClrIO(SPI0_MOSI_PORTx, SPI0_MOSI_PINx) //MOSI拉低
|
||||
#define SPI0_MOSI_AF GpioAf1
|
||||
|
||||
//< SPI1
|
||||
#define SPI1_NSS_PORTx GpioPortB //NSSIO口
|
||||
#define SPI1_NSS_PINx GpioPin12 //配置PB12为NSS
|
||||
#define SET_SPI1_NSS() Gpio_SetIO(SPI1_NSS_PORTx, SPI1_NSS_PINx) //NSS拉高
|
||||
#define CLR_SPI1_NSS() Gpio_ClrIO(SPI1_NSS_PORTx, SPI1_NSS_PINx) //NSS拉低
|
||||
#define SPI1_NSS_AF GpioAf1
|
||||
|
||||
#define SPI1_SCK_PORTx GpioPortB //SCKIO口
|
||||
#define SPI1_SCK_PINx GpioPin3 //配置PB13为SCK
|
||||
#define SET_SPI1_SCK() Gpio_SetIO(SPI1_SCK_PORTx, SPI1_SCK_PINx) //SCK拉高
|
||||
#define CLR_SPI1_SCK() Gpio_ClrIO(SPI1_SCK_PORTx, SPI1_SCK_PINx) //SCK拉低
|
||||
#define SPI1_SCK_AF GpioAf1
|
||||
|
||||
#define SPI1_MISO_PORTx GpioPortB //MISOIO口
|
||||
#define SPI1_MISO_PINx GpioPin4 //配置PB14为MISO
|
||||
#define SET_SPI1_MISO() Gpio_SetIO(SPI1_MISO_PORTx, SPI1_MISO_PINx) //MISO拉高
|
||||
#define CLR_SPI1_MISO() Gpio_ClrIO(SPI1_MISO_PORTx, SPI1_MISO_PINx) //MISO拉低
|
||||
#define SPI1_MISO_AF GpioAf1
|
||||
|
||||
#define SPI1_MOSI_PORTx GpioPortB //MOSIIO口
|
||||
#define SPI1_MOSI_PINx GpioPin5 //配置PB15为MOSI
|
||||
#define SET_SPI1_MOSI() Gpio_SetIO(SPI1_MOSI_PORTx, SPI1_MOSI_PINx) //MOSI拉高
|
||||
#define CLR_SPI1_MOSI() Gpio_ClrIO(SPI1_MOSI_PORTx, SPI1_MOSI_PINx) //MOSI拉低
|
||||
#define SPI1_MOSI_AF GpioAf1
|
||||
|
||||
//< I2C0
|
||||
#define I2C0_SCL_PORTx GpioPortF //SCL的GPIO通道
|
||||
#define I2C0_SCL_PINx GpioPin1 //SCL的通道位
|
||||
#define I2C0_SCL_AF GpioAf1
|
||||
#define SET_I2C0_SCL() Gpio_SetIO(I2C0_SCL_PORTx, I2C0_SCL_PINx)
|
||||
#define CLR_I2C0_SCL() Gpio_ClrIO(I2C0_SCL_PORTx, I2C0_SCL_PINx)
|
||||
|
||||
#define I2C0_SDA_PORTx GpioPortF //SDA的GPIO通道
|
||||
#define I2C0_SDA_PINx GpioPin0 //SDA的通道位
|
||||
#define I2C0_SDA_AF GpioAf1
|
||||
#define SET_I2C0_SDA() Gpio_SetIO(I2C0_SDA_PORTx, I2C0_SDA_PINx)
|
||||
#define CLR_I2C0_SDA() Gpio_ClrIO(I2C0_SDA_PORTx, I2C0_SDA_PINx)
|
||||
|
||||
//< I2C1
|
||||
#define I2C1_SCL_PORTx GpioPortA //SCL的GPIO通道
|
||||
#define I2C1_SCL_PINx GpioPin11 //SCL的通道位
|
||||
#define I2C1_SCL_AF GpioAf3
|
||||
#define SET_I2C1_SCL() Gpio_SetIO(I2C1_SCL_PORTx, I2C1_SCL_PINx)
|
||||
#define CLR_I2C1_SCL() Gpio_ClrIO(I2C1_SCL_PORTx, I2C1_SCL_PINx)
|
||||
|
||||
#define I2C1_SDA_PORTx GpioPortA //SDA的GPIO通道
|
||||
#define I2C1_SDA_PINx GpioPin12 //SDA的通道位
|
||||
#define I2C1_SDA_AF GpioAf3
|
||||
#define SET_I2C1_SDA() Gpio_SetIO(I2C1_SDA_PORTx, I2C1_SDA_PINx)
|
||||
#define CLR_I2C1_SDA() Gpio_ClrIO(I2C1_SDA_PORTx, I2C1_SDA_PINx)
|
||||
|
||||
//<<---------------------------- 485 -------------------------------->>
|
||||
//< LPUart0
|
||||
#define RS485_CTRL_PORTx GpioPortB //RS485_1通信控制
|
||||
#define RS485_CTRL_PINx GpioPin1 //配置PB02为RS485_1_CTRL
|
||||
#define RS485_CTRL_TX() Gpio_SetIO(RS485_CTRL_PORTx, RS485_CTRL_PINx) //RS485_1_CTRL拉高发送
|
||||
#define RS485_CTRL_RX() Gpio_ClrIO(RS485_CTRL_PORTx, RS485_CTRL_PINx) //RS485_1_CTRL拉低接收
|
||||
|
||||
//<<---------------------------- LED -------------------------------->>
|
||||
//< LED_State
|
||||
#define LED_STATE_PORTx GpioPortF //状态指示灯IO通道
|
||||
#define LED_STATE_PINx GpioPin7 //状态指示灯脚位
|
||||
#define LED_ON() Gpio_SetIO(LED_STATE_PORTx, LED_STATE_PINx);//状态指示灯亮
|
||||
#define LED_OFF() Gpio_ClrIO(LED_STATE_PORTx, LED_STATE_PINx);//状态指示灯灭
|
||||
|
||||
//<<---------------------------- LORA --> SPI0 -------------------------------->>
|
||||
//< LORA --> DIO0
|
||||
#define LORA_DIO0_PORTx GpioPortB //LORA_DIO0口
|
||||
#define LORA_DIO0_PINx GpioPin7 //配置PA01为DIO0
|
||||
#define GET_LORA_DIO0() Gpio_GetInputIO(LORA_DIO0_PORTx, LORA_DIO0_PINx) //获取LORA_DIO0电平状态
|
||||
//< LORA --> DIO1
|
||||
#define LORA_DIO1_PORTx GpioPortB //LORA_DIO0口
|
||||
#define LORA_DIO1_PINx GpioPin0 //配置PA01为DIO0
|
||||
#define GET_LORA_DIO1() Gpio_GetInputIO(LORA_DIO1_PORTx, LORA_DIO1_PINx) //获取LORA_DIO0电平状态
|
||||
|
||||
//< LORA --> RST
|
||||
#define LORA_RST_PORTx GpioPortB //LORA_RST口
|
||||
#define LORA_RST_PINx GpioPin6 //配置PA00为RST
|
||||
#define SET_LORA_RST() Gpio_SetIO(LORA_RST_PORTx, LORA_RST_PINx) //LORA复位脚拉高
|
||||
#define CLR_LORA_RST() Gpio_ClrIO(LORA_RST_PORTx, LORA_RST_PINx) //LORA复位脚拉低
|
||||
|
||||
//<<---------------------------- LSM6DSLTR --> I2C0 -------------------------------->>
|
||||
//< ACC_INT1
|
||||
#define LSM6DSLTR_INT1_PORTx GpioPortC //LSM6DSLTR中断1IO通道
|
||||
#define LSM6DSLTR_INT1_PINx GpioPin15 //配置PB01为ACC_INT1
|
||||
#define GET_LSM6DSLTR_INT1() Gpio_GetInputIO(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx) //获取ACC_INT1电平状态
|
||||
|
||||
//< ACC_INT2
|
||||
#define LSM6DSLTR_INT2_PORTx GpioPortC //LSM6DSLTR中断1IO通道
|
||||
#define LSM6DSLTR_INT2_PINx GpioPin13 //配置PA08为ACC_INT2
|
||||
#define GET_LSM6DSLTR_INT2() Gpio_GetInputIO(LSM6DSLTR_INT2_PORTx, LSM6DSLTR_INT2_PINx) //获取ACC_INT2电平状态
|
||||
|
||||
//<<---------------------------- MMC5983MA --> I2C0 -------------------------------->>
|
||||
//< MMC0_INT
|
||||
#define MMC5983MA_INT_PORTx GpioPortC //MMC5983MA中断IO通道
|
||||
#define MMC5983MA_INT_PINx GpioPin14 //配置PB00为MMC_INT
|
||||
#define GET_MMC5983MA_INT() Gpio_GetInputIO(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx) //获取ACC_INT2电平状态
|
||||
|
||||
//<<---------------------------- LASER -------------------------------->>
|
||||
//< LASER1
|
||||
#define LASER1_ON_OFF_PORTx GpioPortB
|
||||
#define LASER1_ON_OFF_PINx GpioPin14
|
||||
#define LASER1_ON() Gpio_SetIO(LASER1_ON_OFF_PORTx, LASER1_ON_OFF_PINx) //LORA复位脚拉高
|
||||
#define LASER1_OFF() Gpio_ClrIO(LASER1_ON_OFF_PORTx, LASER1_ON_OFF_PINx) //LORA复位脚拉低
|
||||
//< LASER2
|
||||
#define LASER2_ON_OFF_PORTx GpioPortB
|
||||
#define LASER2_ON_OFF_PINx GpioPin13
|
||||
#define LASER2_ON() Gpio_SetIO(LASER2_ON_OFF_PORTx, LASER2_ON_OFF_PINx) //LORA复位脚拉高
|
||||
#define LASER2_OFF() Gpio_ClrIO(LASER2_ON_OFF_PORTx, LASER2_ON_OFF_PINx) //LORA复位脚拉低
|
||||
//< LASER3
|
||||
#define LASER3_ON_OFF_PORTx GpioPortB
|
||||
#define LASER3_ON_OFF_PINx GpioPin12
|
||||
#define LASER3_ON() Gpio_SetIO(LASER3_ON_OFF_PORTx, LASER3_ON_OFF_PINx) //LORA复位脚拉高
|
||||
#define LASER3_OFF() Gpio_ClrIO(LASER3_ON_OFF_PORTx, LASER3_ON_OFF_PINx) //LORA复位脚拉低
|
||||
|
||||
//<<------------------------------ ADC ---------------------------------->>
|
||||
#define AD_ON_OFF_PORTx GpioPortA
|
||||
#define AD_ON_OFF_PINx GpioPin3
|
||||
#define AD_ON() Gpio_SetIO(AD_ON_OFF_PORTx, AD_ON_OFF_PINx) //LORA复位脚拉高
|
||||
#define AD_OFF() Gpio_ClrIO(AD_ON_OFF_PORTx, AD_ON_OFF_PINx) //LORA复位脚拉低
|
||||
|
||||
#define VBAT_PORTx GpioPortA
|
||||
#define VBAT_PINx GpioPin4
|
||||
#define VBAT_ADC_PORTx AdcExInputCH4//采样通道
|
||||
#define VBAT_CAL 3.5 //电池电压校准
|
||||
|
||||
//< 电池电压
|
||||
extern float VBAT_8V4;
|
||||
extern uint8_t VBAT_Percentage;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t CollectTime; //数据采集时间间隔,设置范围30*N秒,1<=N<=240,(默认5分钟,N=10)
|
||||
uint16_t ReportInterval; //上报时间间隔,设置范围,30*N秒,10<=N<=1440(默认20分钟,N=40)
|
||||
uint8_t ERInterval; //紧急上报时间间隔,设置范围,30*N秒,2<=N<=10(默认2分钟,N=4)
|
||||
uint8_t ERTime; //紧急上报时长,设置范围,30*N秒,20<=N<=240(默认20分钟,N=40)
|
||||
uint32_t TimeStamp; //网关返回RTC时间戳
|
||||
}__attribute__((packed))LayoutPara_t,*LayoutPara;//上位机下发的配置参数
|
||||
|
||||
typedef struct {
|
||||
int16_t PitchZero; //俯仰角零点
|
||||
int16_t RollZero; //横滚角零点
|
||||
int16_t YawZero; //偏航角零点
|
||||
}__attribute__ ((packed))CalibratePara_t, *CalibratePara;
|
||||
|
||||
typedef struct {
|
||||
LayoutPara_t Layout;
|
||||
CalibratePara_t CaliPara;
|
||||
uint32_t RS485Addr; //本机485地址
|
||||
uint32_t FactoryFlag;//出厂标志位
|
||||
}AppPara_T, *pAppPara;
|
||||
#define APP_PARA_ADDRESS (0x0001FE00)
|
||||
#define SAVE_APP_PARA(addr) FlashWrite(APP_PARA_ADDRESS, addr, sizeof(App.Para) / 4)
|
||||
#define READ_APP_PARA(addr) FlashRead(APP_PARA_ADDRESS, addr, sizeof(App.Para) / 4)
|
||||
|
||||
void BspInit(void);
|
||||
void EnterDeepSleep(void);
|
||||
void DBGUartSendByte(uint8_t sData);
|
||||
void DBGUartSend(uint8_t *sData, int sLen);
|
||||
void LPUart0SendArray(uint8_t *sData, uint8_t sLen);
|
||||
void Uart1SendArray(uint8_t *sData, uint8_t sLen);
|
||||
|
||||
uint32_t GetSysTick(void);
|
||||
void delay_ms(uint32_t ms);
|
||||
void Delay(uint32_t time);
|
||||
void RTCInit(uint8_t sec);
|
||||
void LPTimer0_ON(uint16_t _100ms);
|
||||
void LPTimer0_OFF(void);
|
||||
void WakeUpInit(void);
|
||||
void FeedDog(void);
|
||||
uint32_t TimeTs(void);
|
||||
void TimeShow(uint32_t dwStamp);
|
||||
void TimeSync(time_t ts);
|
||||
void PrintfMess(void);
|
||||
void SystemReset(void);
|
||||
uint8_t Spi0SendReceive(uint8_t sData);
|
||||
uint8_t Spi1SendReceive(uint8_t sData);
|
||||
void FlashWrite(uint32_t Addr, uint32_t *wData, int wLen);
|
||||
void FlashRead(uint32_t Addr, uint32_t *rData, int rLen);
|
||||
|
||||
void ADCLoopHandler(void);
|
||||
void LORA_RxCallBack(uint8_t *rBuff, uint8_t rlen);
|
||||
|
||||
void GlobalIntEnable(void);
|
||||
void GlobalIntDisable(void);
|
||||
void LORAIntEnable(void);
|
||||
void LORAIntDisable(void);
|
||||
void ACCandMMCIntEnable(void);
|
||||
void ACCandMMCIntDisable(void);
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
#include "bsp.h"
|
||||
#include "UartDebug.h"
|
||||
#include "Imu.h"
|
||||
|
||||
#define X 0
|
||||
#define Y 1
|
||||
#define Z 2
|
||||
#define XYZ 3
|
||||
|
||||
#define SYSTEM_TIMING_LOGIN (86400 / 30) //系统定时注册时间(一天86400秒)
|
||||
#define ERR_TIMING_LOGIN (1800 / 30) //注册错误重新注册时间(半个小时1800秒)
|
||||
|
||||
#define TEST_TIME (60*60*1000)
|
||||
|
||||
#define ERINTERVAL_VPT 10 //紧急上报阈值,单位0.1°
|
||||
#define ERINTERVAL_VPT 10 //紧急上报阈值,单位0.1°
|
||||
|
||||
typedef struct {//传感器原始数据
|
||||
float acce[XYZ];
|
||||
float gy[XYZ];
|
||||
float mag[XYZ];
|
||||
}__attribute__ ((packed))SensorData_T,*SensorDp;//传感器数据
|
||||
|
||||
typedef struct {//转换的数据
|
||||
int16_t Pitch; //俯仰角偏斜 (范围±900)单位0.1°
|
||||
int16_t Roll; //横滚角偏斜 (范围±900)单位0.1°
|
||||
int16_t Yaw; //偏航角偏斜 (范围0~3600)单位0.1°
|
||||
// int16_t Temp; //温度值
|
||||
// int32_t AD; //AD值
|
||||
}__attribute__ ((packed))ConvertedData_T, *ConvertedDp;
|
||||
|
||||
typedef struct {// 姿态角数据
|
||||
Rad_T Rad;
|
||||
Deg_T Deg;
|
||||
}__attribute__ ((packed))AHRSData_T,*AHRSDp;
|
||||
|
||||
/*主程序状态机*/
|
||||
typedef enum {
|
||||
APP_STATUS_IDLE,
|
||||
APP_STATUS_SLEEP,
|
||||
APP_STATUS_ON,
|
||||
APP_STATUS_OFF,
|
||||
APP_STATUS_ACTION,
|
||||
APP_STATUS_WAIT_LOGIN,
|
||||
APP_STATUS_WAIT_UPLOAD,
|
||||
}AppStatus_m;
|
||||
|
||||
/*数据读取状态机*/
|
||||
typedef enum {
|
||||
READDATA_STATUS_IDLE,
|
||||
READDATA_STATUS_UPDAING,
|
||||
READDATA_STATUS_WAIT_UPDAING,
|
||||
READDATA_STATUS_DATA_HANDLE,
|
||||
}ReadDataStatus_m;
|
||||
|
||||
typedef struct {
|
||||
AppStatus_m Status;//状态
|
||||
ReadDataStatus_m RDStatus;//读取数据状态
|
||||
|
||||
uint32_t TD1mSDelayCnt;
|
||||
uint8_t FeedDogDlyCnt;
|
||||
uint32_t ReadData1mSDelayCnt;
|
||||
uint32_t SysResetTimeCnt;
|
||||
|
||||
SensorData_T Sensor;
|
||||
AppPara_T Para;
|
||||
AHRSData_T AHRSData;
|
||||
ConvertedData_T ConvertedData;
|
||||
|
||||
uint32_t RepeLoginCount; //24h重复注册计数
|
||||
uint8_t Login30MinCount; //注册30分定时计数
|
||||
uint8_t Login2Min30SCount; //注册100ms~2分+30s定时计数
|
||||
bool Login_RTC; //注册30分定时器启动标志位
|
||||
bool Login_LPTimer0; //注册100ms~2分+30s定时器启动标志位
|
||||
bool LoginFlag; //注册标志位
|
||||
|
||||
uint16_t Coll_N; //数据采集时间计数
|
||||
uint16_t Repor_N; //上报时间计数
|
||||
uint16_t ERInterval_N; //紧急上报时间间隔计数
|
||||
uint8_t ERTime_N; //紧急上报时间计数
|
||||
bool ERFlag; //紧急上报标志位
|
||||
|
||||
bool UploadFlag; //上传数据标志位
|
||||
uint8_t Upload45S10SCount; //上传数据超时计数
|
||||
bool Upload_LPTimer0; //上传100~10000ms+45秒定时器启动标志位
|
||||
|
||||
bool MagRead_EndFlag;
|
||||
bool AccRead_EndFlag;
|
||||
bool UpdateOk; //数据更新标志位
|
||||
|
||||
bool CaliFlag; //标校标志位
|
||||
|
||||
int16_t Nonce; //随机数
|
||||
|
||||
uint32_t TestTimeCnt;
|
||||
uint8_t Tcnt;
|
||||
bool LaserFlag;
|
||||
}AppDetect_t;
|
||||
|
||||
extern AppDetect_t App;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,783 @@
|
||||
#include "bsp.h"
|
||||
#include "Algorithm.h"
|
||||
#include "UartDebug.h"
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: check_peaks_valleys_ratio
|
||||
* 功能描述: 检查数据的峰值是否大于0,谷值是否小于0(忽略0值)
|
||||
* 参 数: data, 数据
|
||||
length, 数据长度
|
||||
* 返 回 值: 结果返回峰值谷值检查结果结构体
|
||||
*****************************************************************************************/
|
||||
PeakValleyCheck check_peaks_valleys(int data[], int length) {
|
||||
PeakValleyCheck result = {true, true, 0, 0};
|
||||
|
||||
// 如果数据长度小于3,无法形成有效的峰值/谷值
|
||||
if (length < 3) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
// 跳过开头的0值
|
||||
while (i < length && data[i] == 0) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// 遍历数据点
|
||||
while (i < length) {
|
||||
// 1. 寻找下一个非零点作为起点
|
||||
int start = i;
|
||||
while (i < length && data[i] == 0) {
|
||||
i++;
|
||||
}
|
||||
if (i >= length) break;
|
||||
|
||||
// 2. 寻找当前非零段的结束点
|
||||
int end = i;
|
||||
while (end < length && data[end] != 0) {
|
||||
end++;
|
||||
}
|
||||
end--; // 指向最后一个非零点
|
||||
|
||||
// 3. 在当前非零段中检测峰值和谷值
|
||||
for (int j = i; j <= end; j++) {
|
||||
// 跳过边界点
|
||||
if (j == i || j == end) continue;
|
||||
|
||||
// 检查是否为峰值(大于左右相邻的非零点)
|
||||
if (data[j] > data[j-1] && data[j] > data[j+1]) {
|
||||
result.peak_count++;
|
||||
if (data[j] <= 0) {
|
||||
result.peaks_positive = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否为谷值(小于左右相邻的非零点)
|
||||
if (data[j] < data[j-1] && data[j] < data[j+1]) {
|
||||
result.valley_count++;
|
||||
if (data[j] >= 0) {
|
||||
result.valleys_negative = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移动到下一段
|
||||
i = end + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: analyze_trend
|
||||
* 功能描述: 趋势分析函数
|
||||
* 参 数: data, 数据
|
||||
length, 数据长度
|
||||
* 返 回 值: 结果返回趋势分析结构体
|
||||
*****************************************************************************************/
|
||||
TrendResult analyze_trend(int data[], int length) {
|
||||
TrendResult result = {0};
|
||||
#if 1
|
||||
// 0. 检查有效数据长度
|
||||
if (length < 2) {
|
||||
DBG_LOG("Data deficient\r\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 1. 计算线性回归斜率
|
||||
double sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
double x = i; // 时间序列 (0,1,2,...)
|
||||
double y = data[i];
|
||||
sum_x += x;
|
||||
sum_y += y;
|
||||
sum_xy += x * y;
|
||||
sum_x2 += x * x;
|
||||
}
|
||||
|
||||
double numerator = length * sum_xy - sum_x * sum_y;
|
||||
double denominator = length * sum_x2 - sum_x * sum_x;
|
||||
|
||||
// 处理分母为零的情况
|
||||
if (fabs(denominator) > 1e-10) {
|
||||
result.slope = numerator / denominator;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
// 2. 计算振荡特征(差分符号变化次数)
|
||||
int sign_changes = 0;
|
||||
int prev_sign = 0; // 0=未初始化, 1=正, -1=负
|
||||
|
||||
for (int i = 1; i < length; i++) {
|
||||
int diff = data[i] - data[i-1];
|
||||
int curr_sign = (diff > 0) ? 1 : (diff < 0) ? -1 : 0;
|
||||
|
||||
if (curr_sign != 0) {
|
||||
if (prev_sign != 0 && curr_sign != prev_sign) {
|
||||
sign_changes++;
|
||||
}
|
||||
prev_sign = curr_sign;
|
||||
}
|
||||
}
|
||||
result.sign_changes = sign_changes;
|
||||
#endif
|
||||
#if 0
|
||||
// 3. 动态计算阈值(基于数据长度)
|
||||
int oscillation_threshold = (int)(0.4 * (length - 1)); // 40%的变化率
|
||||
double slope_threshold = 0.05 * (length / 20.0); // 长度标准化
|
||||
#endif
|
||||
#if 0
|
||||
// 4. 趋势判断
|
||||
if (sign_changes >= oscillation_threshold) {
|
||||
//DBG_LOG("Oscillating trend\r\n");//振荡趋势
|
||||
result.trend_type = 0;
|
||||
} else if (fabs(result.slope) < slope_threshold) {
|
||||
//DBG_LOG("Smooth trend\r\n");//平稳趋势
|
||||
result.trend_type = 1;
|
||||
} else if (result.slope > 0) {
|
||||
//DBG_LOG("Up trend\r\n");//上升趋势
|
||||
result.trend_type = 2;
|
||||
} else {
|
||||
//DBG_LOG("Down trend\r\n");//下降趋势
|
||||
result.trend_type = 3;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
// 5. 陡峭判断
|
||||
double abs_slope = fabs(result.slope);
|
||||
if (abs_slope > 0.8) {
|
||||
//DBG_LOG("Steeply");//陡峭
|
||||
result.sign_changes = 0;
|
||||
} else if (abs_slope > 0.3) {
|
||||
//DBG_LOG("Obvious");//明显
|
||||
result.sign_changes = 1;
|
||||
} else if (abs_slope > 0.1) {
|
||||
//DBG_LOG("Mild");//温和
|
||||
result.sign_changes = 2;
|
||||
} else {
|
||||
//DBG_LOG("gentle");//平缓
|
||||
result.sign_changes = 3;
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: calculateAverage
|
||||
* 功能描述: 计算平均值
|
||||
* 参 数: arr, 数据
|
||||
size, 数据长度
|
||||
* 返 回 值: 结果返回 long long 防溢出
|
||||
*****************************************************************************************/
|
||||
float calculateAverage(int *arr, int size)
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
sum += arr[i]; // 累加数组中的每个元素
|
||||
}
|
||||
return (float)sum / size; // 返回平均值
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: slope
|
||||
* 功能描述: 计算斜率
|
||||
* 参 数: x_data, x轴数据
|
||||
y_data, y轴数据
|
||||
* 返 回 值: 结果返回 long long 防溢出
|
||||
*****************************************************************************************/
|
||||
double slope(int32_t *x_data, int32_t *y_data, int n)
|
||||
{
|
||||
double sum_x = 0, sum_y = 0, sum_xx = 0, sum_xy = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
sum_x += x_data[i];
|
||||
sum_y += y_data[i];
|
||||
sum_xx += pow(x_data[i] - calculateAverage(x_data, n), 2);
|
||||
sum_xy += (x_data[i] - calculateAverage(x_data, n)) * (y_data[i] - calculateAverage(y_data, n));
|
||||
}
|
||||
|
||||
return sum_xy / sum_xx;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: power
|
||||
* 功能描述: 快速幂算法
|
||||
* 参 数: base, 滤波数据
|
||||
exponent, 滤波数据长度
|
||||
* 返 回 值: 结果返回 long long 防溢出
|
||||
*****************************************************************************************/
|
||||
long long power(int base, unsigned int exponent) {
|
||||
long long result = 1;
|
||||
while (exponent > 0) {
|
||||
if (exponent % 2 == 1) {
|
||||
result *= base; // 指数为奇数时累乘
|
||||
}
|
||||
base *= base; // 底数平方
|
||||
exponent /= 2; // 指数折半
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: IntFilter_16t
|
||||
* 功能描述: 16位数据中值滤波函数
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
FilterCnt, 滤除的数据长度,必须为2的倍数
|
||||
* 返 回 值: 滤波后的16位数据
|
||||
*****************************************************************************************/
|
||||
int IntFilter_16t(int16_t *Data, uint8_t Cnt, uint8_t FilterCnt)
|
||||
{
|
||||
int32_t sum = 0;
|
||||
int32_t temp;
|
||||
|
||||
if(Cnt < 2)
|
||||
return *Data;
|
||||
|
||||
for(int j=0; j<Cnt-1; j++) {
|
||||
for(int i=0; i<Cnt-j-1; i++) {
|
||||
if(Data[i] > Data[i+1]) {
|
||||
temp = Data[i];
|
||||
Data[i] = Data[i+1];
|
||||
Data[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int count = FilterCnt / 2; count < Cnt - FilterCnt / 2; count++)
|
||||
sum += Data[count];
|
||||
return (sum / (Cnt - FilterCnt));
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: IntFilter_32t
|
||||
* 功能描述: 32位数据中值滤波函数
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
FilterCnt, 滤除的数据长度,必须为2的倍数
|
||||
* 返 回 值: 滤波后的32位数据
|
||||
*****************************************************************************************/
|
||||
int IntFilter_32t(int32_t *Data, uint8_t Cnt, uint8_t FilterCnt)
|
||||
{
|
||||
int32_t sum = 0;
|
||||
int32_t temp;
|
||||
|
||||
if(Cnt < 2)
|
||||
return *Data;
|
||||
|
||||
for(int j=0; j<Cnt-1; j++) {
|
||||
for(int i=0; i<Cnt-j-1; i++) {
|
||||
if(Data[i] > Data[i+1]) {
|
||||
temp = Data[i];
|
||||
Data[i] = Data[i+1];
|
||||
Data[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int count = FilterCnt / 2; count < Cnt - FilterCnt / 2; count++)
|
||||
sum += Data[count];
|
||||
return (sum / (Cnt - FilterCnt));
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: IntFilter_u32t
|
||||
* 功能描述: 32位无符号位数据中值滤波函数
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
FilterCnt, 滤除的数据长度,必须为2的倍数
|
||||
* 返 回 值: 滤波后的32位数据
|
||||
*****************************************************************************************/
|
||||
uint32_t IntFilter_u32t(uint32_t *Data, uint8_t Cnt, uint8_t FilterCnt)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint32_t temp;
|
||||
|
||||
if(Cnt < 2)
|
||||
return *Data;
|
||||
|
||||
for(int j=0; j<Cnt-1; j++) {
|
||||
for(int i=0; i<Cnt-j-1; i++) {
|
||||
if(Data[i] > Data[i+1]) {
|
||||
temp = Data[i];
|
||||
Data[i] = Data[i+1];
|
||||
Data[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int count = FilterCnt / 2; count < Cnt - FilterCnt / 2; count++)
|
||||
sum += Data[count];
|
||||
return (sum / (Cnt - FilterCnt));
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: IntFilter_Float
|
||||
* 功能描述: 32位浮点数数据中值滤波函数
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
FilterCnt, 滤除的数据长度,必须为2的倍数
|
||||
* 返 回 值: 滤波后的32位数据
|
||||
*****************************************************************************************/
|
||||
float IntFilter_Float(float *Data, uint8_t Cnt, uint8_t FilterCnt)
|
||||
{
|
||||
float sum = 0;
|
||||
float temp;
|
||||
|
||||
if(Cnt < 2)
|
||||
return *Data;
|
||||
|
||||
for(int j=0; j<Cnt-1; j++) {
|
||||
for(int i=0; i<Cnt-j-1; i++) {
|
||||
if(Data[i] > Data[i+1]) {
|
||||
temp = Data[i];
|
||||
Data[i] = Data[i+1];
|
||||
Data[i+1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int count = FilterCnt / 2; count < Cnt - FilterCnt / 2; count++)
|
||||
sum += Data[count];
|
||||
return (sum / (Cnt - FilterCnt));
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AverageFilter_u32t
|
||||
* 功能描述: 32位数据均值滤波函数,去除了最大值和最小值
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
* 返 回 值: 滤波后的32位数据
|
||||
*****************************************************************************************/
|
||||
uint32_t AverageFilter_u32t(uint32_t *Data, uint8_t Cnt)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint32_t temp;
|
||||
uint32_t max = Data[0];
|
||||
uint32_t min = Data[0];
|
||||
|
||||
if(Cnt == 0)
|
||||
return 0;
|
||||
|
||||
if(Cnt == 1)
|
||||
return Data[0];
|
||||
|
||||
if(Cnt == 2)
|
||||
{
|
||||
sum = Data[0] + Data[1];
|
||||
return sum / 2;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Cnt; i++)//找出最大值
|
||||
{
|
||||
if (Data[i] > max)
|
||||
{
|
||||
max = Data[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Cnt; i++)//找出最小值
|
||||
{
|
||||
if (Data[i] < min)
|
||||
{
|
||||
min = Data[i];
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < Cnt; i++){//求和
|
||||
sum += Data[i];
|
||||
}
|
||||
|
||||
return (sum - max - min) / (Cnt - 2);
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AverageFilter_32t
|
||||
* 功能描述: 32位数据均值滤波函数,去除了最大值和最小值
|
||||
* 参 数: Data, 滤波数据
|
||||
Cnt, 滤波数据长度
|
||||
* 返 回 值: 滤波后的32位数据
|
||||
*****************************************************************************************/
|
||||
int AverageFilter_32t(int32_t *Data, uint8_t Cnt)
|
||||
{
|
||||
int32_t sum = 0;
|
||||
int32_t max = Data[0];
|
||||
int32_t min = Data[0];
|
||||
|
||||
if(Cnt == 0)
|
||||
return 0;
|
||||
|
||||
if(Cnt == 1)
|
||||
return Data[0];
|
||||
|
||||
if(Cnt == 2)
|
||||
{
|
||||
sum = Data[0] + Data[1];
|
||||
return sum / 2;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Cnt; i++)//找出最大值
|
||||
{
|
||||
if (Data[i] > max)
|
||||
{
|
||||
max = Data[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < Cnt; i++)//找出最小值
|
||||
{
|
||||
if (Data[i] < min)
|
||||
{
|
||||
min = Data[i];
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < Cnt; i++){//求和
|
||||
sum += Data[i];
|
||||
}
|
||||
|
||||
return (sum - max - min) / (Cnt - 2);
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: Fitting_Polynomial
|
||||
* 功能描述: 根据数组AD[], Actual[]列出的一组数据,用最小二乘法求它的拟合曲线,默认3阶
|
||||
近似解析表达式为y = a3*x^3 + a2*x^2 + a1*x + a0;
|
||||
* 参 数: AD, AD芯片采样值
|
||||
Actual, 实际标校值
|
||||
Cnt, 拟合数据个数
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
void Fitting_Polynomial(double *AD, double *Actual, uint8_t Cnt)
|
||||
{
|
||||
static const uint8_t rank_ = 3;//拟合阶数3
|
||||
double atemp[2 * (rank_ + 1)], b[rank_ + 1], a[rank_ + 1][rank_ + 1];
|
||||
int i, j, k;
|
||||
|
||||
for(i = 0; i < Cnt; i++){
|
||||
atemp[1] += AD[i];
|
||||
atemp[2] += pow(AD[i], 2);
|
||||
atemp[3] += pow(AD[i], 3);
|
||||
atemp[4] += pow(AD[i], 4);
|
||||
atemp[5] += pow(AD[i], 5);
|
||||
atemp[6] += pow(AD[i], 6);
|
||||
b[0] += Actual[i];
|
||||
b[1] += AD[i] * Actual[i];
|
||||
b[2] += pow(AD[i], 2) * Actual[i];
|
||||
b[3] += pow(AD[i], 3) * Actual[i];
|
||||
}
|
||||
|
||||
atemp[0] = Cnt;
|
||||
|
||||
for(i = 0; i < rank_ + 1; i++){ //构建线性方程组系数矩阵,b[]不变
|
||||
k = i;
|
||||
for(j = 0; j < rank_ + 1; j++) a[i][j] = atemp[k++];
|
||||
}
|
||||
|
||||
//以下为高斯列主元消去法解线性方程组
|
||||
for(k = 0; k < rank_ + 1 - 1; k++){ //n - 1列
|
||||
int column = k;
|
||||
double mainelement = a[k][k];
|
||||
|
||||
for(i = k; i < rank_ + 1; i++) //找主元素
|
||||
if(fabs(a[i][k]) > mainelement){
|
||||
mainelement = fabs(a[i][k]);
|
||||
column = i;
|
||||
}
|
||||
for(j = k; j < rank_ + 1; j++){ //交换两行
|
||||
double atemp = a[k][j];
|
||||
a[k][j] = a[column][j];
|
||||
a[column][j] = atemp;
|
||||
}
|
||||
double btemp = b[k];
|
||||
b[k] = b[column];
|
||||
b[column] = btemp;
|
||||
|
||||
for(i = k + 1; i < rank_ + 1; i++){ //消元过程
|
||||
double Mik = a[i][k] / a[k][k];
|
||||
for(j = k; j < rank_ + 1; j++) a[i][j] -= Mik * a[k][j];
|
||||
b[i] -= Mik * b[k];
|
||||
}
|
||||
}
|
||||
|
||||
b[rank_ + 1 - 1] /= a[rank_ + 1 - 1][rank_ + 1 - 1]; //回代过程
|
||||
for(i = rank_ + 1 - 2; i >= 0; i--){
|
||||
double sum = 0;
|
||||
for(j = i + 1; j < rank_ + 1; j++) sum += a[i][j] * b[j];
|
||||
b[i] = (b[i] - sum) / a[i][i];
|
||||
}//高斯列主元消去法结束
|
||||
|
||||
DBG_LOG("P(x) = %.16fx^3%+.16fx^2%+.16fx%+.16f\r\n", b[3], b[2], b[1], b[0]);
|
||||
|
||||
// App.Para.Cali.FitCoef[0] = b[0];
|
||||
// App.Para.Cali.FitCoef[1] = b[1];
|
||||
// App.Para.Cali.FitCoef[2] = b[2];
|
||||
// App.Para.Cali.FitCoef[3] = b[3];
|
||||
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: get_K
|
||||
* 功能描述: 斜率计算
|
||||
* 参 数: count,数据个数 数组行(列)的个数 数组的行列数目相等
|
||||
dataCol_X[count],数据的列数据
|
||||
dataRow_Y[count],数据的行数据
|
||||
* 返 回 值: k 斜率
|
||||
*****************************************************************************************/
|
||||
float get_K(uint8_t count , int32_t *dataCol_X, int32_t *dataRow_Y)
|
||||
{
|
||||
float k = 0;//斜率
|
||||
float aveCol_X = 0;//列的平均值x
|
||||
float aveRow_Y = 0;//行的平均值y
|
||||
int32_t sum_XY = 0;//行列的总和xy
|
||||
int32_t sumRow_Y = 0;//行的总和y
|
||||
int32_t sumCol_X = 0;//列的总和x
|
||||
int32_t sumCol_X2 = 0;//列的总和x^2
|
||||
|
||||
for(uint16_t i = 0 ; i < count ; i++)
|
||||
{
|
||||
sumCol_X += dataCol_X[i];//求列x的总和
|
||||
sumRow_Y += dataRow_Y[i];//求行y的总和
|
||||
sumCol_X2 += dataCol_X[i] * dataCol_X[i];//求x^2的总和
|
||||
sum_XY += (dataCol_X[i] * dataRow_Y[i]);//求xy的总和
|
||||
}
|
||||
|
||||
aveCol_X = 1.0 * sumCol_X / count;//求平均值
|
||||
aveRow_Y = 1.0 * sumRow_Y / count;
|
||||
|
||||
k = (sum_XY - aveCol_X * aveRow_Y * count) / //根据公式求斜率
|
||||
(sumCol_X2 - aveCol_X * aveCol_X * count);
|
||||
|
||||
return k;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: TrendAnalyse
|
||||
* 功能描述: 判断数组中的值的总体趋势
|
||||
* 参 数: Data,
|
||||
Cnt,
|
||||
VPT,
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
int8_t TrendAnalyse(int32_t *Data, uint8_t Cnt, int32_t VPT)
|
||||
{
|
||||
int8_t zero = 0,plus = 0, minus = 0, Trend = 0xEE;
|
||||
|
||||
if(Cnt < 2)
|
||||
return Trend;
|
||||
|
||||
for(uint8_t i = 1; i < Cnt; i++)
|
||||
{
|
||||
if((Data[i] - Data[i - 1]) <= VPT && ((Data[i] - Data[i - 1]) >= (-VPT)))
|
||||
{
|
||||
zero++;
|
||||
}
|
||||
else if((Data[i] - Data[i - 1]) > VPT)
|
||||
{
|
||||
plus++;
|
||||
}
|
||||
else if((Data[i] - Data[i - 1]) < VPT)
|
||||
{
|
||||
minus++;
|
||||
}
|
||||
}
|
||||
if(zero > (Cnt-(Cnt / 5)))
|
||||
Trend = 0;//振荡趋势
|
||||
else if(plus > (Cnt-(Cnt/ 5)))
|
||||
Trend = 1;//上升趋势
|
||||
else if(minus > (Cnt-(Cnt/ 5)))
|
||||
Trend = -1;//下降趋势
|
||||
|
||||
return Trend;//总趋势
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: Waveform_Up
|
||||
* 功能描述: 找出一段波形的波峰值
|
||||
dCnt, 波形数据长度
|
||||
pCnt, 要查找波峰数
|
||||
vlue, 返回的波峰值
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
void Waveform_Up(int32_t *Data, uint8_t dCnt, uint8_t pCnt, int32_t *vlue)
|
||||
{
|
||||
uint8_t peak[pCnt];
|
||||
for(uint8_t i = 0, j = 0; i < dCnt; i++)//找出峰值地址
|
||||
{
|
||||
if(Data[i] < Data[i + 1] && Data[i + 1] > Data[i + 2])
|
||||
{
|
||||
peak[j++] = i;
|
||||
}
|
||||
if(j == pCnt)
|
||||
break;
|
||||
}
|
||||
for(uint8_t i = 0; i < pCnt; i++)
|
||||
{
|
||||
vlue[i] = Data[peak[i]];
|
||||
}
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: Waveform_Down
|
||||
* 功能描述: 找出一段波形的波谷值
|
||||
dCnt, 波形数据长度
|
||||
pCnt, 要查找波谷数
|
||||
vlue, 返回的波谷值
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
void Waveform_Down(int32_t *Data, uint8_t dCnt, uint8_t pCnt, int32_t *vlue)
|
||||
{
|
||||
uint8_t peak[pCnt];
|
||||
for(uint8_t i = 0, j = 0; i < dCnt; i++)//找出峰值地址
|
||||
{
|
||||
if(Data[i] > Data[i + 1] && Data[i + 1] < Data[i + 2])
|
||||
{
|
||||
peak[j++] = i;
|
||||
}
|
||||
if(j == pCnt)
|
||||
break;
|
||||
}
|
||||
for(uint8_t i = 0; i < pCnt; i++)
|
||||
{
|
||||
vlue[i] = Data[peak[i]];
|
||||
}
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: count_most_greater
|
||||
* 功能描述: 判断数组中的值是否大部分大于 target
|
||||
* 参 数: arr,
|
||||
size,
|
||||
target,
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
bool count_most_greater(int32_t *arr, uint8_t size, int32_t target)
|
||||
{
|
||||
uint8_t cnt = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (arr[i] < target)
|
||||
cnt++;
|
||||
if(cnt > (size - (size / 5)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: count_greater
|
||||
* 功能描述: 判断数组中的值是否全部大于 target
|
||||
* 参 数: arr,
|
||||
size,
|
||||
target,
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
bool count_greater(int32_t *arr, uint8_t size, int32_t target)
|
||||
{
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (arr[i] < target)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: count_smaller
|
||||
* 功能描述: 判断数组中的值是否全部小于 target
|
||||
* 参 数: arr,
|
||||
size,
|
||||
target,
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
bool count_smaller(int32_t *arr, uint8_t size, int32_t target)
|
||||
{
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (arr[i] > target)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: CRC_Modbus
|
||||
* 功能描述: CRC16计算函数
|
||||
* 参 数: wBase, 多项式
|
||||
Para,校验数据入口
|
||||
Data, 校验数据长度入口
|
||||
* 返 回 值: crc16校验值
|
||||
*****************************************************************************************/
|
||||
uint16_t CRC_Modbus(uint16_t wBase, uint8_t *para, uint16_t length)
|
||||
{
|
||||
uint16_t crc = 0xffff;
|
||||
|
||||
uint16_t index,i;
|
||||
|
||||
for(index = 0 ; index < length;index++) {
|
||||
crc ^= para[index];
|
||||
for(i = 0; i < 8; i++) {
|
||||
if(crc & 1) {
|
||||
crc >>= 1;
|
||||
crc ^= wBase;
|
||||
}
|
||||
else
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: CRC_Sum
|
||||
* 功能描述: 从第二个字节开始,求和取反
|
||||
* 参 数: _pbuff,校验数据入口
|
||||
_cmdLen,校验数据长度入口
|
||||
* 返 回 值: cmd_sum,校验值(一个字节)
|
||||
*****************************************************************************************/
|
||||
uint8_t CRC_Sum(uint8_t *_pbuff, uint16_t _cmdLen)
|
||||
{
|
||||
uint8_t cmd_sum=0;
|
||||
uint16_t i;
|
||||
|
||||
for(i=1;i<_cmdLen;i++)//从1开始,跳过第一个字节
|
||||
{
|
||||
cmd_sum += _pbuff[i];
|
||||
}
|
||||
cmd_sum = (~cmd_sum);
|
||||
|
||||
return cmd_sum;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: isAllZero
|
||||
* 功能描述: 判断一个数组的值是否全部为0
|
||||
* 参 数: arr,数组
|
||||
size,长度
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
bool isAllZero(uint8_t *arr, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (arr[i] != 0) {
|
||||
return false; // 如果数组中有一个元素不为0,则返回false
|
||||
}
|
||||
}
|
||||
return true; // 遍历完数组后,若所有元素都为0,则返回true
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: HexToAscii
|
||||
* 功能描述: 16进制转ASCII码
|
||||
* 参 数: HexData,16进制数组
|
||||
ASCData,ASCII码
|
||||
sLen,数据长度
|
||||
* 返 回 值: true或false
|
||||
*****************************************************************************************/
|
||||
void HexToAscii(uint8_t *HexData, char *ASCData, uint8_t sLen)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
for(int i = 0; i < sLen; i++) {
|
||||
temp = (HexData[i] >> 4) & 0x0f;
|
||||
if(temp < 10)
|
||||
temp += '0';
|
||||
else
|
||||
temp = (temp - 10) + 'A';
|
||||
|
||||
ASCData[i * 2] = temp;
|
||||
|
||||
temp = HexData[i] & 0x0f;
|
||||
if(temp < 10)
|
||||
temp += '0';
|
||||
else
|
||||
temp = (temp - 10) + 'A';
|
||||
|
||||
ASCData[i * 2 + 1] = temp;
|
||||
}
|
||||
ASCData[sLen * 2] = '\r';
|
||||
ASCData[sLen * 2 + 1] = '\n';
|
||||
ASCData[sLen * 2 + 2] = 0;
|
||||
}
|
||||
|
||||
|
||||
+2227
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,48 @@
|
||||
#include "Update.h"
|
||||
#include "UartDebug.h"
|
||||
|
||||
static BootPara_t BLPara;
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: Update
|
||||
* 功能描述: 固件升级,此函数在解析到升级指令是调用
|
||||
* 参 数: PayLoad 协议负载,需去除帧头等信息,只传负载数据
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
void Update(uint8_t *PayLoad)
|
||||
{
|
||||
UpDataRequset_t Req;
|
||||
|
||||
memcpy(&Req, PayLoad, sizeof(UpDataRequset_t));
|
||||
BLPara.AppSize = Req.AppSize;
|
||||
BLPara.Crc32Check = Req.AppCrc32;
|
||||
BLPara.PackageCnt = Req.PackageNum;
|
||||
BLPara.AppFlag = 0;
|
||||
BLPara.UpdateFlag = APP_UPDATE_FLAG;
|
||||
|
||||
U_DBG_LOG("Receive upgrade command:\r\n");
|
||||
U_DBG_LOG("PackageNum: %d\r\n", BLPara.PackageCnt);
|
||||
U_DBG_LOG("AppSize: %d\r\n", BLPara.AppSize);
|
||||
U_DBG_LOG("AppCrc32: 0x%08x\r\n", BLPara.Crc32Check);
|
||||
U_DBG_LOG("System Reset!\r\n");
|
||||
|
||||
SAVE_BOOT_PARA((uint32_t *)&BLPara);
|
||||
U_DELAY_MS(200);
|
||||
U_SYSTEM_TESET();
|
||||
}
|
||||
|
||||
/*****************************************************************************************
|
||||
* 函数名称: UpdateInit
|
||||
* 功能描述: 升级参数初始化,需要在程序启动,外设初试完后调用
|
||||
* 参 数: 无
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
void UpdateInit(void)
|
||||
{
|
||||
READ_BOOT_PARA((uint32_t *)&BLPara);
|
||||
if(BLPara.AppFlag != APP_START_FLAG) {
|
||||
BLPara.AppFlag = APP_START_FLAG;
|
||||
SAVE_BOOT_PARA((uint32_t *)&BLPara);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,937 @@
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include "sysctrl.h"
|
||||
#include "gpio.h"
|
||||
#include "flash.h"
|
||||
#include "bsp.h"
|
||||
#include "lpuart.h"
|
||||
#include "uart.h"
|
||||
#include "lpm.h"
|
||||
#include "lptim.h"
|
||||
#include "spi.h"
|
||||
#include "reset.h"
|
||||
#include "wdt.h"
|
||||
#include "rtc.h"
|
||||
#include "i2c.h"
|
||||
#include "bgr.h"
|
||||
#include "adc.h"
|
||||
#include "UartDebug.h"
|
||||
|
||||
#include "lsm6dsl_app.h"
|
||||
#include "mmc5983.h"
|
||||
#include "sx127x.h"
|
||||
|
||||
extern void LPUartRx_CallBack(uint8_t Rx);
|
||||
extern void Uart1Rx_CallBack(uint8_t Rx);
|
||||
extern void DebugUartIRQ(uint8_t Data);
|
||||
extern void SysTick_CallBack(void);
|
||||
extern void RtcIRQHander(void);
|
||||
extern void LPTimer0IRQHander(void);
|
||||
extern void LORA_RxCallBack(uint8_t *rBuff, uint8_t rlen);
|
||||
|
||||
static __IO uint32_t SysTickCnt = 0;
|
||||
static volatile uint32_t u32AdcRestult;
|
||||
|
||||
static void SystemClkDivInit(void)//系统时钟分频设置
|
||||
{
|
||||
//时钟分频设置
|
||||
Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
|
||||
Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
|
||||
}
|
||||
static void SystemClkInit(en_sysctrl_rch_freq_t enRchFreq)//时钟初始化
|
||||
{
|
||||
///< RCH时钟不同频率的切换,需要先将时钟切换到RCL
|
||||
Sysctrl_SetRCLTrim(SysctrlRclFreq38400);
|
||||
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle64);
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
|
||||
|
||||
/*内部高速时钟初始化 24MHZ*/
|
||||
/*Sysctrl_SetRCHTrim(enRchFreq);
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
|
||||
//< HCLK不超过24M:此处设置FLASH读等待周期为0 cycle
|
||||
Flash_WaitCycle(FlashWaitCycle0);
|
||||
|
||||
Sysctrl_SysClkSwitch(SysctrlClkRCH);//系统时钟源选择
|
||||
*/
|
||||
|
||||
/*内部高速时钟初始化 48MHZ*/
|
||||
stc_sysctrl_pll_cfg_t stcPLLCfg;
|
||||
|
||||
///< 加载目标频率的RCH的TRIM值
|
||||
Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
|
||||
///< 使能RCH
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
|
||||
|
||||
stcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; //RCH 4MHz
|
||||
stcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; //PLL 输出
|
||||
stcPLLCfg.enPllClkSrc = SysctrlPllRch; //输入时钟源选择RCH
|
||||
stcPLLCfg.enPllMul = SysctrlPllMul12; //4MHz x 12 = 48MHz
|
||||
Sysctrl_SetPLLFreq(&stcPLLCfg);
|
||||
|
||||
///< 当使用的时钟源HCLK大于24M:设置FLASH 读等待周期为1 cycle(默认值也为1 cycle)
|
||||
Flash_WaitCycle(FlashWaitCycle1);
|
||||
|
||||
///< 使能PLL
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);
|
||||
///< 时钟切换到PLL
|
||||
Sysctrl_SysClkSwitch(SysctrlClkPLL);
|
||||
|
||||
/*外部低速晶振初始化 32.768KHz*/
|
||||
/* Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);
|
||||
Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkXTL, TRUE);
|
||||
*/
|
||||
}
|
||||
static void SystemRCLInit(void)
|
||||
{
|
||||
Sysctrl_SetRCLTrim(SysctrlRclFreq38400); ///< 配置RCL时钟为38400kHz
|
||||
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE); ///< 使能RCL时钟
|
||||
}
|
||||
|
||||
static void Uart0Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t stcGpioCfg;
|
||||
stc_uart_cfg_t stcCfg;
|
||||
DDL_ZERO_STRUCT(stcGpioCfg);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
///<TX
|
||||
stcGpioCfg.enDir = GpioDirOut;
|
||||
Gpio_Init(UART0_TX_PORT, UART0_TX_PIN, &stcGpioCfg);
|
||||
Gpio_SetAfMode(UART0_TX_PORT, UART0_TX_PIN, GpioAf1);
|
||||
|
||||
//<RX
|
||||
stcGpioCfg.enDir = GpioDirIn;
|
||||
stcGpioCfg.enPu = GpioPuEnable;
|
||||
Gpio_Init(UART0_RX_PORT, UART0_RX_PIN, &stcGpioCfg);
|
||||
Gpio_SetAfMode(UART0_RX_PORT, UART0_RX_PIN, GpioAf1);
|
||||
|
||||
DDL_ZERO_STRUCT(stcCfg);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);
|
||||
|
||||
///<UART 初始化
|
||||
stcCfg.enStopBit = UartMsk1bit; ///<1停止位
|
||||
stcCfg.enMmdorCk = UartMskEven; ///<偶校验
|
||||
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<PCLK获取
|
||||
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<采样分频
|
||||
stcCfg.stcBaud.u32Baud = 500000; ///<波特率
|
||||
stcCfg.enRunMode = UartMskMode1; ///<工作模式
|
||||
Uart_Init(M0P_UART0, &stcCfg);
|
||||
|
||||
///<UART 中断使能
|
||||
Uart_ClrStatus(M0P_UART0, UartRC); ///<清接收中断请求
|
||||
Uart_ClrStatus(M0P_UART0, UartTC); ///<清发送中断请求
|
||||
//Uart_EnableIrq(M0P_UART1,UartTxIrq); ///<使能发送中断
|
||||
Uart_EnableIrq(M0P_UART0, UartRxIrq); ///<使能接收中断
|
||||
EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE); ///<系统中断使能
|
||||
}
|
||||
|
||||
static void Uart1Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t stcGpioCfg;
|
||||
stc_uart_cfg_t stcCfg;
|
||||
DDL_ZERO_STRUCT(stcGpioCfg);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
///<TX
|
||||
stcGpioCfg.enDir = GpioDirOut;
|
||||
Gpio_Init(UART1_TX_PORT, UART1_TX_PIN, &stcGpioCfg);
|
||||
Gpio_SetAfMode(UART1_TX_PORT, UART1_TX_PIN, GpioAf3);
|
||||
|
||||
//<RX
|
||||
stcGpioCfg.enDir = GpioDirIn;
|
||||
stcGpioCfg.enPu = GpioPuEnable;
|
||||
Gpio_Init(UART1_RX_PORT, UART1_RX_PIN, &stcGpioCfg);
|
||||
Gpio_SetAfMode(UART1_RX_PORT, UART1_RX_PIN, GpioAf3);
|
||||
|
||||
DDL_ZERO_STRUCT(stcCfg);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE);
|
||||
|
||||
///<UART 初始化
|
||||
stcCfg.enStopBit = UartMsk1bit; ///<1停止位
|
||||
//stcCfg.enMmdorCk = UartMskEven; ///<偶校验
|
||||
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<PCLK获取
|
||||
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<采样分频
|
||||
stcCfg.stcBaud.u32Baud = 115200; ///<波特率
|
||||
stcCfg.enRunMode = UartMskMode1; ///<工作模式
|
||||
Uart_Init(M0P_UART1, &stcCfg);
|
||||
|
||||
///<UART 中断使能
|
||||
Uart_ClrStatus(M0P_UART1, UartRC); ///<清接收中断请求
|
||||
Uart_ClrStatus(M0P_UART1, UartTC); ///<清发送中断请求
|
||||
//Uart_EnableIrq(M0P_UART1,UartTxIrq); ///<使能发送中断
|
||||
Uart_EnableIrq(M0P_UART1, UartRxIrq); ///<使能接收中断
|
||||
EnableNvic(UART1_3_IRQn, IrqLevel3, TRUE); ///<系统中断使能
|
||||
}
|
||||
static void LpUart0Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t stcGpioCfg;
|
||||
stc_lpuart_cfg_t stcCfg;
|
||||
DDL_ZERO_STRUCT(stcGpioCfg);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
///<TX
|
||||
stcGpioCfg.enDir = GpioDirOut;
|
||||
Gpio_Init(LPUart0_TxPortx,LPUART0_TxPinx,&stcGpioCfg);
|
||||
Gpio_SetAfMode(LPUart0_TxPortx,LPUART0_TxPinx,GpioAf4); //配置PB10为LPUART0_TX
|
||||
|
||||
//<RX
|
||||
stcGpioCfg.enDir = GpioDirIn;
|
||||
Gpio_Init(LPUart0_RxPortx,LPUART0_RxPinx,&stcGpioCfg);
|
||||
Gpio_SetAfMode(LPUart0_RxPortx,LPUART0_RxPinx,GpioAf3); //配置PB11为LPUART0_RX
|
||||
|
||||
DDL_ZERO_STRUCT(stcCfg);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralLpUart0,TRUE);
|
||||
|
||||
///<LPUART 初始化
|
||||
stcCfg.enStopBit = LPUart1bit; ///<1停止位
|
||||
//stcCfg.enMmdorCk = LPUartEven; ///<偶校验
|
||||
stcCfg.stcBaud.enSclkSel = LPUartMskRcl; ///<传输时钟源
|
||||
stcCfg.stcBaud.u32Sclk = 38400; ///<PCLK获取
|
||||
stcCfg.stcBaud.enSclkDiv = LPUartMsk4Or8Div; ///<采样分频
|
||||
stcCfg.stcBaud.u32Baud = 9600; ///<波特率
|
||||
stcCfg.enRunMode = LPUartMskMode1; ///<工作模式
|
||||
LPUart_Init(M0P_LPUART0, &stcCfg);
|
||||
|
||||
///<LPUART 中断使能
|
||||
LPUart_ClrStatus(M0P_LPUART0,LPUartRC); ///<清接收中断请求
|
||||
LPUart_ClrStatus(M0P_LPUART0,LPUartTC); ///<清发送中断请求
|
||||
//LPUart_EnableIrq(M0P_LPUART0,LPUartTxIrq); ///<使能发送中断
|
||||
LPUart_EnableIrq(M0P_LPUART0,LPUartRxIrq); ///<使能接收中断
|
||||
EnableNvic(LPUART0_IRQn,IrqLevel3,TRUE); ///<系统中断使能
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: AdcInit
|
||||
* 功能描述: ADC初始化
|
||||
* 参 数: 无
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
static void AdcInit(void)
|
||||
{
|
||||
///< 开启ADC/BGR GPIO外设时钟
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
|
||||
Gpio_SetAnalogMode(VBAT_PORTx, VBAT_PINx); //PA04 (AIN4)
|
||||
|
||||
stc_adc_cfg_t stcAdcCfg;
|
||||
|
||||
DDL_ZERO_STRUCT(stcAdcCfg);
|
||||
|
||||
///< 开启ADC/BGR外设时钟
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
|
||||
|
||||
Bgr_BgrEnable(); ///< 开启BGR
|
||||
|
||||
///< ADC 初始化配置
|
||||
stcAdcCfg.enAdcMode = AdcSglMode; ///<采样模式-单次
|
||||
stcAdcCfg.enAdcClkDiv = AdcMskClkDiv8; ///<采样分频-1
|
||||
stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle12Clk; ///<采样周期数-12
|
||||
stcAdcCfg.enAdcRefVolSel = AdcMskRefVolSelAVDD; ///<参考电压选择-AVDD
|
||||
stcAdcCfg.enAdcOpBuf = AdcMskBufEnable; ///<OP BUF配置-关
|
||||
stcAdcCfg.enInRef = AdcMskInRefDisable; ///<内部参考电压使能-关
|
||||
stcAdcCfg.enAdcAlign = AdcAlignRight; ///<转换结果对齐方式-右
|
||||
Adc_Init(&stcAdcCfg);
|
||||
|
||||
Adc_CfgSglChannel(VBAT_ADC_PORTx); // 配置单次采样通道
|
||||
Adc_SGL_Always_Start(); // 启动单次一直采样
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: Battery_Level_Percent_Table
|
||||
* 功能描述: 电池电量百分比转换
|
||||
* 参 数: voltage,采集到的电压
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
static float Battery_Level_Percent_Table[37] = {9000, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900,
|
||||
10000, 10100, 10200, 10300, 10400, 10500, 10600, 10700, 10800, 10900,
|
||||
11000, 11100, 11200, 11300, 11400, 11500, 11600, 11700, 11800, 11900,
|
||||
12000, 12100, 12200, 12300, 12400, 12500, 12600};
|
||||
static int Percentage(float voltage)
|
||||
{
|
||||
if(voltage < Battery_Level_Percent_Table[0])
|
||||
return 0;
|
||||
|
||||
for(uint8_t i = 0; i < 37; i++)
|
||||
{
|
||||
if(voltage <= Battery_Level_Percent_Table[i])
|
||||
{
|
||||
return (int)((Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[0]) / (Battery_Level_Percent_Table[36] - Battery_Level_Percent_Table[0]) * 100);
|
||||
}
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* 函数名称: ADC_IRQHandler
|
||||
* 功能描述: ADC采集中断,放在主循环内一直循环采集
|
||||
* 参 数: 无
|
||||
* 返 回 值: 无
|
||||
*****************************************************************************************/
|
||||
float VBAT_12V;//< ADC采集到的电压
|
||||
uint8_t VBAT_Percentage;//电池电压百分比
|
||||
void ADCLoopHandler(void)
|
||||
{
|
||||
if(Adc_GetIrqStatus(AdcMskIrqSgl))//ADC中断状态获取
|
||||
{
|
||||
VBAT_12V = (Adc_GetSglResult() * VBAT_CAL);//< 获取实际电压
|
||||
VBAT_Percentage = Percentage(VBAT_12V);//获取百分比
|
||||
//DBG_LOG("VBAT_Percentage:%d\n",VBAT_Percentage);
|
||||
Adc_ClrIrqStatus(AdcMskIrqSgl);//清除ADC中断状态
|
||||
}
|
||||
}
|
||||
void RTCInit(uint8_t sec)
|
||||
{
|
||||
stc_rtc_initstruct_t RtcInitStruct;
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE); //RTC模块时钟打开
|
||||
RtcInitStruct.rtcAmpm = RtcPm; //24小时制
|
||||
RtcInitStruct.rtcClksrc = RtcClkRcl; //外部低速时钟
|
||||
RtcInitStruct.rtcPrdsel.rtcPrdsel = RtcPrdx; //周期中断类型PRDX
|
||||
RtcInitStruct.rtcPrdsel.rtcPrdx = sec * 2 - 1; //周期中断时间间隔 30秒
|
||||
|
||||
Rtc_ReadDateTime(&RtcInitStruct.rtcTime);
|
||||
if(RtcInitStruct.rtcTime.u8Year < 0x23 || RtcInitStruct.rtcTime.u8Year > 0x99 || RtcInitStruct.rtcTime.u8Month > 0x12) {
|
||||
RtcInitStruct.rtcTime.u8Second = 0x30;
|
||||
RtcInitStruct.rtcTime.u8Minute = 0x38;
|
||||
RtcInitStruct.rtcTime.u8Hour = 0x08;
|
||||
RtcInitStruct.rtcTime.u8Day = 0x02;
|
||||
RtcInitStruct.rtcTime.u8DayOfWeek = 0x06;
|
||||
RtcInitStruct.rtcTime.u8Month = 0x09;
|
||||
RtcInitStruct.rtcTime.u8Year = 0x23;
|
||||
}
|
||||
RtcInitStruct.rtcCompen = RtcCompenEnable;
|
||||
RtcInitStruct.rtcCompValue = 0; //补偿值 根据实际情况进行补偿
|
||||
Rtc_Init(&RtcInitStruct);
|
||||
Rtc_AlmIeCmd(TRUE); //使能闹钟中断
|
||||
EnableNvic(RTC_IRQn, IrqLevel3, TRUE); //使能RTC中断向量
|
||||
Rtc_Cmd(TRUE); //使能RTC开始计数
|
||||
Rtc_StartWait(); //启动RTC计数,如果要立即切换到低功耗,需要执行此函数
|
||||
}
|
||||
/******************************************************************************
|
||||
* 函数名称: LPTimer0Init
|
||||
* 功能描述: 低功耗定时器0初始化
|
||||
* 参 数: sTime 定时中断秒时间
|
||||
* 返 回 值: 无
|
||||
******************************************************************************/
|
||||
void LPTimer0Init(uint16_t _100ms)
|
||||
{
|
||||
Lptim_Cmd(M0P_LPTIMER0, FALSE);
|
||||
|
||||
stc_lptim_cfg_t stcLptCfg;
|
||||
DDL_ZERO_STRUCT(stcLptCfg);
|
||||
|
||||
///< 使能LPTIM0 外设时钟
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralLpTim0, TRUE);
|
||||
|
||||
stcLptCfg.enPrs = LptimPrsDiv256;
|
||||
stcLptCfg.enGate = LptimGateLow;
|
||||
stcLptCfg.enGatep = LptimGatePLow;
|
||||
stcLptCfg.enTcksel = LptimRcl;
|
||||
stcLptCfg.enTogen = LptimTogEnLow;
|
||||
stcLptCfg.enCt = LptimTimerFun; //警示器功能
|
||||
stcLptCfg.enMd = LptimMode1; //工作模式为模式1:无自动重装载16位计数器/定时器
|
||||
stcLptCfg.u16Arr = 0x10000 - (_100ms * 13); //预装载寄存器值
|
||||
Lptim_Init(M0P_LPTIMER0, &stcLptCfg);
|
||||
|
||||
Lptim_ClrItStatus(M0P_LPTIMER0); //清除中断标志位
|
||||
Lptim_ConfIt(M0P_LPTIMER0, TRUE); //允许LPTIMER中断
|
||||
EnableNvic(LPTIM_0_1_IRQn, IrqLevel3, TRUE);
|
||||
|
||||
Lptim_Cmd(M0P_LPTIMER0, TRUE);
|
||||
}
|
||||
void LPTimer0_ON(uint16_t _100ms)
|
||||
{
|
||||
LPTimer0Init(_100ms);
|
||||
}
|
||||
void LPTimer0_OFF(void)
|
||||
{
|
||||
EnableNvic(LPTIM_0_1_IRQn, IrqLevel3, FALSE);
|
||||
Lptim_Cmd(M0P_LPTIMER0, FALSE);
|
||||
}
|
||||
static void GPIOInit(void)
|
||||
{
|
||||
stc_gpio_cfg_t GpioInitStruct;
|
||||
|
||||
DDL_ZERO_STRUCT(GpioInitStruct);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
//未使用或引出的脚设为输入上拉
|
||||
GpioInitStruct.enDir = GpioDirIn;
|
||||
GpioInitStruct.enPu = GpioPuEnable;
|
||||
|
||||
Gpio_Init(GpioPortA, GpioPin0, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin1, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin2, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin5, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin6, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin7, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortA, GpioPin8, &GpioInitStruct);
|
||||
|
||||
Gpio_Init(GpioPortB, GpioPin2, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortB, GpioPin8, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortB, GpioPin9, &GpioInitStruct);
|
||||
Gpio_Init(GpioPortB, GpioPin15, &GpioInitStruct);
|
||||
|
||||
Gpio_Init(GpioPortF, GpioPin6, &GpioInitStruct);
|
||||
//end
|
||||
|
||||
/********************************** GPIO输出 ****************************************/
|
||||
GpioInitStruct.enDir = GpioDirOut; ///< 端口方向配置->输出
|
||||
GpioInitStruct.enDrv = GpioDrvH; ///< 端口驱动能力配置->高驱动能力
|
||||
GpioInitStruct.enPu = GpioPuDisable; ///< 端口上下拉配置->无
|
||||
GpioInitStruct.enPd = GpioPdDisable;
|
||||
GpioInitStruct.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭
|
||||
GpioInitStruct.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB
|
||||
GpioInitStruct.bOutputVal = false; ///< 端口默认输出配置->低电平
|
||||
//< RS485控制引脚
|
||||
Gpio_Init(RS485_CTRL_PORTx,RS485_CTRL_PINx,&GpioInitStruct);
|
||||
//< 激光控制引脚
|
||||
Gpio_Init(LASER1_ON_OFF_PORTx,LASER1_ON_OFF_PINx,&GpioInitStruct);
|
||||
Gpio_Init(LASER2_ON_OFF_PORTx,LASER2_ON_OFF_PINx,&GpioInitStruct);
|
||||
Gpio_Init(LASER3_ON_OFF_PORTx,LASER3_ON_OFF_PINx,&GpioInitStruct);
|
||||
|
||||
GpioInitStruct.bOutputVal = true; ///< 端口默认输出配置->高电平
|
||||
//< LORA --> RST
|
||||
Gpio_Init(LORA_RST_PORTx,LORA_RST_PINx,&GpioInitStruct);
|
||||
//< LED_State
|
||||
Gpio_Init(LED_STATE_PORTx,LED_STATE_PINx,&GpioInitStruct);
|
||||
|
||||
/********************************** GPIO输入 ****************************************/
|
||||
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
|
||||
GpioInitStruct.enPu = GpioPuDisable; ///< 端口上下拉配置->无
|
||||
GpioInitStruct.enPd = GpioPdDisable;
|
||||
GpioInitStruct.enOD = GpioOdDisable;
|
||||
|
||||
//< LORA --> DIO0
|
||||
Gpio_Init(LORA_DIO0_PORTx,LORA_DIO0_PINx,&GpioInitStruct);
|
||||
//< LORA --> DIO0
|
||||
Gpio_Init(LORA_DIO1_PORTx,LORA_DIO1_PINx,&GpioInitStruct);
|
||||
//< ACC_INT1
|
||||
Gpio_Init(LSM6DSLTR_INT1_PORTx,LSM6DSLTR_INT1_PINx,&GpioInitStruct);
|
||||
//< ACC_INT2
|
||||
Gpio_Init(LSM6DSLTR_INT2_PORTx,LSM6DSLTR_INT2_PINx,&GpioInitStruct);
|
||||
//< MMC_INT
|
||||
Gpio_Init(MMC5983MA_INT_PORTx,MMC5983MA_INT_PINx,&GpioInitStruct);
|
||||
GlobalIntEnable();
|
||||
}
|
||||
void GlobalIntEnable(void)//全局中断使能
|
||||
{
|
||||
EnableNvic(PORTB_IRQn, IrqLevel3, TRUE);
|
||||
EnableNvic(PORTC_E_IRQn, IrqLevel3, TRUE);
|
||||
}
|
||||
void GlobalIntDisable(void)//全局中断失能
|
||||
{
|
||||
EnableNvic(PORTB_IRQn, IrqLevel3, FALSE);
|
||||
EnableNvic(PORTC_E_IRQn, IrqLevel3, FALSE);
|
||||
}
|
||||
void LORAIntEnable(void)//LORA中断使能
|
||||
{
|
||||
Gpio_EnableIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx, GpioIrqRising);//LORA_DIO0
|
||||
Gpio_EnableIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx, GpioIrqRising);//LORA_DIO1
|
||||
}
|
||||
void LORAIntDisable(void)//LORA中断失能
|
||||
{
|
||||
Gpio_DisableIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx, GpioIrqRising);
|
||||
Gpio_DisableIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx, GpioIrqRising);
|
||||
}
|
||||
void ACCandMMCIntEnable(void)//加速度和地磁中断使能
|
||||
{
|
||||
Gpio_EnableIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx, GpioIrqRising);//ACC_Int1
|
||||
Gpio_EnableIrq(LSM6DSLTR_INT2_PORTx, LSM6DSLTR_INT2_PINx, GpioIrqRising);//ACC_Int2
|
||||
Gpio_EnableIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx, GpioIrqRising);//MMC_Int
|
||||
}
|
||||
void ACCandMMCIntDisable(void)//加速度和地磁中断失能
|
||||
{
|
||||
Gpio_DisableIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx, GpioIrqRising);//ACC_Int1
|
||||
Gpio_DisableIrq(LSM6DSLTR_INT2_PORTx, LSM6DSLTR_INT2_PINx, GpioIrqRising);//ACC_Int2
|
||||
Gpio_DisableIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx, GpioIrqRising);//MMC_Int
|
||||
}
|
||||
|
||||
static void SPI0Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t GpioInitStruct;
|
||||
stc_spi_cfg_t SpiInitStruct;
|
||||
|
||||
DDL_ZERO_STRUCT(GpioInitStruct);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
/************************** SPI0配置:主机-->LORA *******************************/
|
||||
GpioInitStruct.enDir = GpioDirOut;
|
||||
|
||||
Gpio_Init(SPI0_NSS_PORTx,SPI0_NSS_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI0_NSS_PORTx,SPI0_NSS_PINx,SPI0_NSS_AF); //配置SPI0_NSS
|
||||
|
||||
Gpio_Init(SPI0_SCK_PORTx,SPI0_SCK_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI0_SCK_PORTx,SPI0_SCK_PINx,SPI0_SCK_AF); //配置SPI0_SCK
|
||||
|
||||
Gpio_Init(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,SPI0_MOSI_AF); //配置SPI0_MOSI
|
||||
|
||||
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
|
||||
|
||||
Gpio_Init(SPI0_MISO_PORTx,SPI0_MISO_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI0_MISO_PORTx, SPI0_MISO_PINx,SPI0_MISO_AF); //配置SPI0_MISO
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi0,TRUE); ///< 打开SPI0外设时钟
|
||||
Reset_RstPeripheral0(ResetMskSpi0); ///<复位模块
|
||||
|
||||
//SPI0模块配置:主机
|
||||
SpiInitStruct.enSpiMode = SpiMskMaster; //配置位主机模式
|
||||
SpiInitStruct.enPclkDiv = SpiClkMskDiv4; //波特率:PCLK/4
|
||||
SpiInitStruct.enCPHA = SpiMskCphasecond; //第二边沿采样
|
||||
SpiInitStruct.enCPOL = SpiMskcpolhigh; //极性为高
|
||||
Spi_Init(M0P_SPI0, &SpiInitStruct);
|
||||
}
|
||||
|
||||
static void SPI1Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t GpioInitStruct;
|
||||
stc_spi_cfg_t SpiInitStruct;
|
||||
|
||||
DDL_ZERO_STRUCT(GpioInitStruct);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
/************************** SPI1配置:主机-->LORA *******************************/
|
||||
GpioInitStruct.enDir = GpioDirOut;
|
||||
|
||||
Gpio_Init(SPI1_NSS_PORTx,SPI1_NSS_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI1_NSS_PORTx,SPI1_NSS_PINx,SPI1_NSS_AF); //配置SPI1_NSS
|
||||
|
||||
Gpio_Init(SPI1_SCK_PORTx,SPI1_SCK_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI1_SCK_PORTx,SPI1_SCK_PINx,SPI1_SCK_AF); //配置SPI1_SCK
|
||||
|
||||
Gpio_Init(SPI1_MOSI_PORTx,SPI1_MOSI_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI1_MOSI_PORTx,SPI1_MOSI_PINx,SPI1_MOSI_AF); //配置SPI1_MOSI
|
||||
|
||||
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
|
||||
|
||||
Gpio_Init(SPI1_MISO_PORTx,SPI1_MISO_PINx,&GpioInitStruct);
|
||||
Gpio_SetAfMode(SPI1_MISO_PORTx, SPI1_MISO_PINx,SPI1_MISO_AF); //配置SPI1_MISO
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi1,TRUE); ///< 打开SPI0外设时钟
|
||||
Reset_RstPeripheral0(ResetMskSpi1); ///<复位模块
|
||||
|
||||
//SPI1模块配置:主机
|
||||
SpiInitStruct.enSpiMode = SpiMskMaster; //配置位主机模式
|
||||
SpiInitStruct.enPclkDiv = SpiClkMskDiv2; //波特率:PCLK/2
|
||||
SpiInitStruct.enCPHA = SpiMskCphasecond; //第二边沿采样
|
||||
SpiInitStruct.enCPOL = SpiMskcpolhigh; //极性为高
|
||||
Spi_Init(M0P_SPI1, &SpiInitStruct);
|
||||
}
|
||||
|
||||
uint8_t Spi0SendReceive(uint8_t sData)
|
||||
{
|
||||
return Spi_RWByte(M0P_SPI0, sData);
|
||||
}
|
||||
|
||||
uint8_t Spi1SendReceive(uint8_t sData)
|
||||
{
|
||||
return Spi_RWByte(M0P_SPI1, sData);
|
||||
}
|
||||
static void I2C0Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t stcGpioCfg;
|
||||
stc_i2c_cfg_t stcI2cCfg;
|
||||
|
||||
DDL_ZERO_STRUCT(stcI2cCfg);
|
||||
DDL_ZERO_STRUCT(stcGpioCfg);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //开启GPIO时钟门控
|
||||
|
||||
stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出
|
||||
stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出
|
||||
stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能
|
||||
stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止
|
||||
stcGpioCfg.bOutputVal = TRUE;
|
||||
|
||||
Gpio_Init(I2C0_SCL_PORTx, I2C0_SCL_PINx, &stcGpioCfg); ///< 端口初始化
|
||||
Gpio_SetAfMode(I2C0_SCL_PORTx, I2C0_SCL_PINx, I2C0_SCL_AF);
|
||||
|
||||
Gpio_Init(I2C0_SDA_PORTx, I2C0_SDA_PINx, &stcGpioCfg);
|
||||
Gpio_SetAfMode(I2C0_SDA_PORTx, I2C0_SDA_PINx, I2C0_SDA_AF);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c0,TRUE); ///< 开启I2C0时钟门控
|
||||
|
||||
stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
|
||||
stcI2cCfg.u32Baud = 400000; ///< 1MHz
|
||||
stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
|
||||
stcI2cCfg.u8SlaveAddr = 0xD5; ///< 从地址,主模式无效
|
||||
stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
|
||||
I2C_Init(M0P_I2C0, &stcI2cCfg); ///< 模块初始化
|
||||
}
|
||||
|
||||
static void I2C1Init(void)
|
||||
{
|
||||
stc_gpio_cfg_t stcGpioCfg;
|
||||
stc_i2c_cfg_t stcI2cCfg;
|
||||
|
||||
DDL_ZERO_STRUCT(stcI2cCfg);
|
||||
DDL_ZERO_STRUCT(stcGpioCfg);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //开启GPIO时钟门控
|
||||
|
||||
stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出
|
||||
stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出
|
||||
stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能
|
||||
stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止
|
||||
stcGpioCfg.bOutputVal = TRUE;
|
||||
|
||||
Gpio_Init(I2C1_SCL_PORTx, I2C1_SCL_PINx, &stcGpioCfg); ///< 端口初始化
|
||||
Gpio_SetAfMode(I2C1_SCL_PORTx, I2C1_SCL_PINx, I2C1_SCL_AF);
|
||||
|
||||
Gpio_Init(I2C1_SDA_PORTx, I2C1_SDA_PINx, &stcGpioCfg);
|
||||
Gpio_SetAfMode(I2C1_SDA_PORTx, I2C1_SDA_PINx, I2C1_SDA_AF);
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c1,TRUE); ///< 开启I2C1时钟门控
|
||||
|
||||
stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
|
||||
stcI2cCfg.u32Baud = 400000; ///< 1MHz
|
||||
stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
|
||||
stcI2cCfg.u8SlaveAddr = 0xD5; ///< 从地址,主模式无效
|
||||
stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
|
||||
I2C_Init(M0P_I2C1, &stcI2cCfg); ///< 模块初始化
|
||||
}
|
||||
|
||||
|
||||
static void WdtInit(void)
|
||||
{
|
||||
#if (USE_WDT == 1)
|
||||
///< 开启WDT外设时钟
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);
|
||||
///< WDT 初始化
|
||||
Wdt_Init(WdtResetEn, WdtT52s4);
|
||||
Wdt_Start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlashWrite(uint32_t Addr, uint32_t *wData, int wLen)
|
||||
{
|
||||
while(Ok != Flash_SectorErase(Addr));
|
||||
for(int i = 0; i < wLen; i++) {
|
||||
Flash_WriteWord(Addr + i * 4, wData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void FlashRead(uint32_t Addr, uint32_t *rData, int rLen)
|
||||
{
|
||||
uint32_t u32Addr = Addr;
|
||||
for(int i = 0; i < rLen; i++) {
|
||||
rData[i] = *((volatile uint32_t*)(u32Addr + i * 4));
|
||||
}
|
||||
}
|
||||
void FeedDog(void)
|
||||
{
|
||||
#if (USE_WDT == 1)
|
||||
Wdt_Feed();
|
||||
#endif
|
||||
}
|
||||
static uint8_t BCDToDec(uint8_t bcd)
|
||||
{
|
||||
return ((bcd >> 4)& 0x0f) * 10 + (bcd & 0x0f);
|
||||
}
|
||||
|
||||
static uint8_t DecToBCD(uint8_t Dec)
|
||||
{
|
||||
return (Dec / 10) << 4 | (Dec % 10);
|
||||
}
|
||||
|
||||
void TimeGet(struct tm *cTime)
|
||||
{
|
||||
stc_rtc_time_t RtcDateTime;
|
||||
|
||||
Rtc_ReadDateTime(&RtcDateTime);
|
||||
cTime->tm_year = BCDToDec(RtcDateTime.u8Year) + 100;
|
||||
cTime->tm_mon = BCDToDec(RtcDateTime.u8Month) - 1;
|
||||
cTime->tm_mday = BCDToDec(RtcDateTime.u8Day);
|
||||
cTime->tm_hour = BCDToDec(RtcDateTime.u8Hour) + 8;
|
||||
cTime->tm_min = BCDToDec(RtcDateTime.u8Minute);
|
||||
cTime->tm_sec = BCDToDec(RtcDateTime.u8Second);
|
||||
cTime->tm_isdst = 0;
|
||||
}
|
||||
|
||||
uint32_t TimeTs(void)
|
||||
{
|
||||
struct tm cTime;
|
||||
|
||||
TimeGet(&cTime);
|
||||
time_t cTimet = mktime(&cTime);
|
||||
return cTimet;
|
||||
}
|
||||
|
||||
void TimeShow(uint32_t dwStamp)
|
||||
{
|
||||
struct tm *stime;
|
||||
stime = localtime(&dwStamp);
|
||||
DBG_LOG("%d/",stime->tm_year + 1900);
|
||||
DBG_LOG("%d/",stime->tm_mon + 1);
|
||||
DBG_LOG("%d ",stime->tm_mday);
|
||||
DBG_LOG("%d:",stime->tm_hour);
|
||||
DBG_LOG("%d:",stime->tm_min);
|
||||
DBG_LOG("%d\r\n",stime->tm_sec);
|
||||
}
|
||||
|
||||
void TimeSync(time_t ts)
|
||||
{
|
||||
struct tm *td;
|
||||
stc_rtc_time_t RtcDateTime;
|
||||
|
||||
td = localtime(&ts);
|
||||
|
||||
RtcDateTime.u8Year = DecToBCD(td->tm_year - 100);
|
||||
RtcDateTime.u8Month = DecToBCD(td->tm_mon + 1);
|
||||
RtcDateTime.u8Day = DecToBCD(td->tm_mday);
|
||||
RtcDateTime.u8DayOfWeek = DecToBCD(td->tm_wday);
|
||||
RtcDateTime.u8Hour = DecToBCD(td->tm_hour);
|
||||
RtcDateTime.u8Minute = DecToBCD(td->tm_min);
|
||||
RtcDateTime.u8Second = DecToBCD(td->tm_sec);
|
||||
|
||||
Rtc_SetTime(&RtcDateTime);
|
||||
}
|
||||
|
||||
void PrintfMess(void)
|
||||
{
|
||||
DBG_LOG("\r\n");
|
||||
uint32_t CT = TimeTs();
|
||||
TimeShow(CT);
|
||||
#if(USE_LED == 1)
|
||||
LED_ON();
|
||||
#endif
|
||||
#if(USE_VBAT_AD == 1)
|
||||
DBG_LOG("VBAT_Percentage:%d\r\n",VBAT_Percentage);
|
||||
#endif
|
||||
}
|
||||
void DBGUartSendByte(uint8_t sData)
|
||||
{
|
||||
Uart_SendDataPoll(M0P_UART0, sData);
|
||||
}
|
||||
|
||||
void LPUart0SendArray(uint8_t *sData, uint8_t sLen)
|
||||
{
|
||||
RS485_CTRL_TX();
|
||||
for(int i = 0; i < sLen; i++) {
|
||||
LPUart_SendData(M0P_LPUART0, sData[i]);
|
||||
}
|
||||
RS485_CTRL_RX();
|
||||
}
|
||||
|
||||
uint32_t GetSysTick(void)
|
||||
{
|
||||
return SysTickCnt;
|
||||
}
|
||||
void delay_us(uint32_t uS)//24MHz一个nop延时0.5us,12MHz延时1us
|
||||
{
|
||||
uS *= 2;
|
||||
while(uS--)
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
void delay_ms(uint32_t mS)
|
||||
{
|
||||
volatile uint32_t cTick, mTick;
|
||||
|
||||
cTick = GetSysTick();
|
||||
while(1){
|
||||
mTick = GetSysTick();
|
||||
if(mTick - cTick >= mS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SysTick_IRQHandler(void)
|
||||
{
|
||||
SysTickCnt++;
|
||||
SysTick_CallBack();
|
||||
}
|
||||
|
||||
void PortA_IRQHandler(void)
|
||||
{
|
||||
|
||||
}
|
||||
void PortB_IRQHandler(void)
|
||||
{
|
||||
//LORA DIO0
|
||||
if(TRUE == Gpio_GetIrqStatus(LORA_DIO0_PORTx, LORA_DIO0_PINx)) {
|
||||
Gpio_ClearIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx);
|
||||
Sx1276LoRaLoopHandler(); //lora
|
||||
}
|
||||
//LORA DIO1
|
||||
if(TRUE == Gpio_GetIrqStatus(LORA_DIO1_PORTx, LORA_DIO1_PINx)) {
|
||||
Gpio_ClearIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx);
|
||||
}
|
||||
}
|
||||
|
||||
void PortC_IRQHandler(void)
|
||||
{
|
||||
//加速度INT1
|
||||
if(TRUE == Gpio_GetIrqStatus(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx)) {
|
||||
Gpio_ClearIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx);
|
||||
Lsm6dsInt1CallBack();
|
||||
}
|
||||
|
||||
//地磁INT
|
||||
if(TRUE == Gpio_GetIrqStatus(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx)) {
|
||||
Gpio_ClearIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx);
|
||||
MMC5983IntCallBack();
|
||||
}
|
||||
}
|
||||
///<LPUART0 中断服务函数
|
||||
void LpUart0_IRQHandler(void)
|
||||
{
|
||||
if(LPUart_GetStatus(M0P_LPUART0, LPUartRC)) { ///接收数据
|
||||
LPUart_ClrStatus(M0P_LPUART0, LPUartRC); ///<清接收中断请求
|
||||
uint8_t u8RxData = LPUart_ReceiveData(M0P_LPUART0); ///读取数据
|
||||
LPUartRx_CallBack(u8RxData);
|
||||
}
|
||||
}
|
||||
|
||||
void Uart0_IRQHandler(void)
|
||||
{
|
||||
if(Uart_GetStatus(M0P_UART0, UartRC)) { ///接收数据
|
||||
Uart_ClrStatus(M0P_UART0, UartRC); ///<清接收中断请求
|
||||
uint8_t u8RxData = Uart_ReceiveData(M0P_UART0); ///读取数据
|
||||
DebugUartIRQ(u8RxData);
|
||||
}
|
||||
}
|
||||
|
||||
void Rtc_IRQHandler(void)
|
||||
{
|
||||
if(Rtc_GetPridItStatus() == TRUE) {
|
||||
Rtc_ClearPrdfItStatus(); //清除中断标志位
|
||||
RtcIRQHander();
|
||||
}
|
||||
}
|
||||
|
||||
void LpTim0_IRQHandler(void)
|
||||
{
|
||||
if(Lptim_GetItStatus(M0P_LPTIMER0) == TRUE)
|
||||
{
|
||||
Lptim_ClrItStatus(M0P_LPTIMER0);//清除LPTimer0的中断标志位
|
||||
LPTimer0IRQHander();
|
||||
}
|
||||
}
|
||||
///<深度休眠模式外部端口配置(STK)
|
||||
static void DeepSleepGPIOCfg(void)
|
||||
{
|
||||
stc_gpio_cfg_t GpioInitStruct;
|
||||
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
|
||||
|
||||
//低功耗状态下未使用的脚配置
|
||||
//输入上拉
|
||||
GpioInitStruct.enDir = GpioDirIn;
|
||||
GpioInitStruct.enPu = GpioPuEnable;
|
||||
|
||||
Gpio_Init(SPI0_NSS_PORTx,SPI0_NSS_PINx,&GpioInitStruct);
|
||||
Gpio_Init(SPI0_SCK_PORTx,SPI0_SCK_PINx,&GpioInitStruct);
|
||||
Gpio_Init(SPI0_MISO_PORTx,SPI0_MISO_PINx,&GpioInitStruct);
|
||||
|
||||
//输入下拉
|
||||
GpioInitStruct.enDir = GpioDirIn;
|
||||
GpioInitStruct.enPd = GpioPdEnable;
|
||||
|
||||
Gpio_Init(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,&GpioInitStruct);
|
||||
}
|
||||
|
||||
void EnterDeepSleep(void)
|
||||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
|
||||
//< LORA
|
||||
Sx1276LoRaSleep();//Lora睡眠
|
||||
LORAIntDisable();//关闭LORA中断
|
||||
|
||||
ACCandMMCIntDisable();//关闭加速度和地磁中断
|
||||
|
||||
#if (USE_VBAT_AD == 1)//< AD
|
||||
AD_OFF();
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
|
||||
Sysctrl_ClkSourceEnable(SysctrlClkPLL,FALSE);
|
||||
Bgr_BgrDisable(); ///< 关闭BGR
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, FALSE);
|
||||
Adc_SGL_Stop();//关闭单次采样
|
||||
#endif
|
||||
|
||||
#if (USE_SPI0 == 1)
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi0,FALSE);//关闭SPI0外设时钟
|
||||
#endif
|
||||
#if (USE_UART0 == 1)
|
||||
EnableNvic(UART0_2_IRQn, IrqLevel3, false);
|
||||
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,FALSE); //关闭UART0时钟
|
||||
#endif
|
||||
|
||||
DeepSleepGPIOCfg();
|
||||
Lpm_GotoDeepSleep(FALSE);
|
||||
}
|
||||
|
||||
void WakeUpInit(void)
|
||||
{
|
||||
SystemClkDivInit();
|
||||
SystemClkInit(SysctrlRchFreq24MHz);
|
||||
GPIOInit();
|
||||
|
||||
#if (USE_VBAT_AD == 1)//< AD
|
||||
AD_ON();
|
||||
AdcInit();
|
||||
#endif
|
||||
#if (USE_UART0 == 1)
|
||||
Uart0Init();
|
||||
#endif
|
||||
#if (USE_SPI0 == 1)
|
||||
SPI0Init();
|
||||
#endif
|
||||
#if (USE_WDT == 1)//< WDT
|
||||
WdtInit();
|
||||
#endif
|
||||
|
||||
LORAIntEnable();//开启LORA中断
|
||||
Sx1276LoRaWakeup();//LORA唤醒
|
||||
ACCandMMCIntEnable();//开启加速度和地磁中断
|
||||
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
}
|
||||
|
||||
void SystemReset(void)
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void BspInit(void)
|
||||
{
|
||||
SystemClkDivInit();
|
||||
SystemClkInit(SysctrlRchFreq24MHz);
|
||||
GPIOInit();
|
||||
|
||||
#if (USE_VBAT_AD == 1)//< AD
|
||||
AD_ON();
|
||||
AdcInit();
|
||||
#endif
|
||||
#if (USE_UART0 == 1)//< DEBUG
|
||||
Uart0Init();
|
||||
#endif
|
||||
#if (USE_RTC == 1)//< RTC
|
||||
RTCInit(30);
|
||||
#endif
|
||||
#if (USE_WDT == 1)//< WDT
|
||||
WdtInit();
|
||||
#endif
|
||||
#if (USE_SPI0 == 1)
|
||||
SPI0Init();
|
||||
#endif
|
||||
#if (USE_SPI1 == 1)
|
||||
SPI1Init();
|
||||
#endif
|
||||
#if (USE_LPUART0 == 1)//< LPUART0
|
||||
LpUart0Init();
|
||||
#endif
|
||||
#if(USE_I2C0 == 1)
|
||||
I2C0Init();
|
||||
#endif
|
||||
#if(USE_I2C1 == 1)
|
||||
I2C1Init();
|
||||
#endif
|
||||
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
while(Ok != Flash_Init(6, TRUE));
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user