📄 odometer.c
字号:
/****************************************************************
** *
** FILE : OdoMeter.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2002.1.15 *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "tools.h"
#include "errcode.h"
#include "errtask.h"
#include "ramimage.h"
#include "sensor.h"
#include "timetask.h"
#include "systime.h"
#include "gpsrecer.h"
#include "gpstool.h"
#include "odometer.h"
#include "ZPrint.h"
#if EN_ODOMETER > 0
#include "public.h"
#endif
#define ODOMETER_DEBUG 0
#if ODOMETER_DEBUG
static INT8U tempdata[20],templen;
static INT8U Index=0;
typedef struct
{
INT8U Lat_C;
INT8U Long_C;
}SIMULAT_GPS;
static SIMULAT_GPS simulat_gps[4]={ 0x18,0x76,
0x18,0x77,
0x19,0x77,
0x19,0x76
};
static void GetGPSdata_(INT8U *data1,INT8U *data2)
{
data1[0]=simulat_gps[Index].Lat_C;
data1[1]=0x01;
data1[2]=0x01;
data1[3]=0x01;
data2[0]=simulat_gps[Index].Long_C;
data2[1]=0x01;
data2[2]=0x01;
data2[3]=0x01;
if(++Index>=4) Index=0;
}
#endif
/*
********************************************************************************
* 定义配置参数
********************************************************************************
*/
#define MAX_METER 10
#define PERIOD_SCAN SECOND, 1 /* 扫描周期 */
#define PERIOD_UPDATE MINUTE, (2 * 60) /* 刷新flash时间周期 */
#define MAX_RUN_SECOND 300
/*
********************************************************************************
* 定义数据结构
********************************************************************************
*/
typedef struct {
INT8U attrib;
BOOLEAN started;
INT8U tag;
INT32U space;
void (*handler)(INT8U tag);
} METER;
/*
********************************************************************************
* 定义状态参数
********************************************************************************
*/
#define MODE_GPS 0x01
/*
********************************************************************************
* 定义模块局部变量
********************************************************************************
*/
static METER meter[MAX_METER];//定义里程统计表,每个需要统计里程处便安装一个里程统计表
static TMR_TSK *scantmr;
static TMR_TSK *updatetmr;
static INT8U status;
static INT16U fraction;
static INT32U curspace;
static INT8U pre_lat[4], pre_long[4], cur_lat[4], cur_long[4];
void ClearOdoMeter(void)
{
odometer.datevalid = false;
odometer.t_space = 0;
StorePubPara(ODOMETER_);
StoreRamImage(RI_ODOMETER_, (INT8U *)&odometer, sizeof(odometer));
}
INT8U GetOdoMeterDate(INT8U *ptr)//获取里程统计的起始日期
{
memcpy(ptr, &odometer.startdate, sizeof(odometer.startdate));
return sizeof(odometer.startdate);
}
INT8U GetOdoMeterData(INT8U *ptr)//获取总里程数据,并转换为ASCII字符
{
return DecToAscii(ptr, odometer.t_space, 0);
}
static void UpdateTmrProc(void)//定时(2小时)将ODOMETER参数刷新到FLASH中
{
StartTmr(updatetmr, PERIOD_UPDATE);
StorePubPara(ODOMETER_);
StoreRamImage(RI_ODOMETER_, (INT8U *)&odometer, sizeof(odometer));//保存到内存映射区相应位置
}
static void ScanTmrProc(void)//计算里程,间隔1s
{
INT8U i;
StartTmr(scantmr, PERIOD_SCAN);
if(!odometer.datevalid) {
if (SysTimeValid()) {
odometer.datevalid = true;
GetSysTime_Date(&odometer.startdate);
StorePubPara(ODOMETER_);
StoreRamImage(RI_ODOMETER_, (INT8U *)&odometer, sizeof(odometer));
}
}
if (!SensorValid_FILTER(_ACC)) { /* ACC状态处于OFF,则不进行里程计算 */
return;
}
#if ODOMETER_DEBUG
GetGPSdata_(cur_lat,cur_long);
#else
if (!GpsDataValid()) return; /* GPS数据无效 */
GetLatitude(cur_lat); /* 获取当前位置纬度 */
GetLongitude(cur_long); /* 获取当前位置经度 */
#endif
if (CmpString_Byte(pre_lat, sizeof(pre_lat), 0xff)) {
curspace = 0;
} else {
/* 通过前后秒的位置计算出1秒之内行驶的距离 */
curspace = CalculateGpsSpace(pre_lat, pre_long, cur_lat, cur_long);
if(MAX_RUN_SECOND <= curspace ) curspace = 0;
}
memcpy(pre_lat, cur_lat, sizeof(pre_lat));
memcpy(pre_long, cur_long, sizeof(pre_long));
curspace *= 105L; /* 加上5%的校正误差 */
fraction += (curspace % 100L);
curspace /= 100L;
if (fraction >= 100) { /* 小数部分进行进位处理 */
curspace += fraction / 100;
fraction %= 100;
}
for (i = 0; i < MAX_METER; i++) {
if (meter[i].started && meter[i].handler != 0) {
if (meter[i].attrib & _SUM) {
meter[i].space += curspace;//累加递增方式
} else {
if (meter[i].space > curspace) {
meter[i].space -= curspace;//递减方式,减到0则统计完成执行handler函数
} else {
meter[i].started = false;
meter[i].handler(meter[i].tag);
}
}
}
}
odometer.t_space += curspace;
VirStorePubPara(ODOMETER_);
StoreRamImage(RI_ODOMETER_, (INT8U *)&odometer, sizeof(odometer));
}
static INT8U FindBlankMeter(void)
{
INT8U i;
for (i = 0; i < MAX_METER; i++) {
if (meter[i].handler == 0) return i;
}
return 0xff;
}
static void DiagnoseProc(void)
{
if (GetTmrSwitch(scantmr) != ON) ErrExit(ERR_ODOMETER_TMR);
if (GetTmrSwitch(updatetmr) != ON) ErrExit(ERR_ODOMETER_TMR);
}
void InitOdoMeter(void)
{
INT8U i;
for (i = 0; i < MAX_METER; i++) {
meter[i].handler = (void (*)(INT8U)) 0;
}
if (RamImageValid(RI_ODOMETER_)) {
ResumeRamImage(RI_ODOMETER_, (INT8U *)&odometer, sizeof(odometer));
} else if(!PubParaValid(ODOMETER_)) {
ClearOdoMeter();
}
scantmr = CreateTimer(ScanTmrProc, 0);
updatetmr = CreateTimer(UpdateTmrProc, 0);
StartTmr(scantmr, PERIOD_SCAN);
StartTmr(updatetmr, PERIOD_UPDATE);
status = MODE_GPS; /* 缺省情况下采用GPS位置信息计算里程数据 */
memset(pre_lat, 0xff, sizeof(pre_lat));
memset(pre_long, 0xff, sizeof(pre_long));
InstallDiagProc(DiagnoseProc);
}
INT8U InstallMeter(void (*handler)(INT8U), INT8U tag)
{
INT8U id;
if ((id = FindBlankMeter()) == 0xff) {
ErrExit(ERR_ODOMETER_INSTALL);
return 0xff;
} else {
meter[id].started = false;
meter[id].tag = tag;
meter[id].handler = handler;
return id;
}
}
void RemoveMeter(INT8U id)
{
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
} else {
meter[id].handler = (void (*)(INT8U)) 0;
}
}
void ChangeMeterTag(INT8U id, INT8U tag)
{
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
} else {
meter[id].tag = tag;
}
}
void StartMeter(INT8U id, INT8U attrib, INT16U space)
{
HWORD_UNION temp;
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
} else {
meter[id].attrib = attrib;
meter[id].started = true;
attrib &= ~_SUM;
temp.hword = space;
if (attrib == _DM) {
meter[id].space = temp.bytes.low * 10 + temp.bytes.high * 1000;
} else if (attrib == _KM) {
meter[id].space = (temp.bytes.high * 100 + temp.bytes.low) * 1000L;
} else {
ErrExit(ERR_ODOMETER_ATTRIB);
}
}
}
void StopMeter(INT8U id)
{
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
} else {
meter[id].started = false;
}
}
INT32U GetMeterSpace(INT8U id)
{
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
return 0;
} else {
return meter[id].space;
}
}
void ClearMeter(INT8U id)
{
if (id >= MAX_METER) {
ErrExit(ERR_ODOMETER_ID);
} else {
meter[id].space = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -