📄 pc_comm.c
字号:
#include <absacc.h>
#include <file.h>
#include <w77516.h>
#define StartAddOfRFPC 0x1000 //接收PC数据的缓存区首地址
#define StartAddOfSTPC 0x2000 //向PC发送数据的缓存区首地址1
#define StartAddOfSTPC1 0x3000 //向PC发送数据的缓存区首地址2
//黑名单、白名单按以下方式存放在28SF040中
//第一个扇区存储名单版本号、生效日期、有效截止日期、有效区域、名单数量、校验和
//其后每扇区第一字节为该扇区内实际存储的数据的长度n(最大240字节、15段,24条名单)
//第2至第(n+1)字节为实际存储的数据、第(n+2)和(n+3)字节存储CRC校验和
//白名单位于扇区10-19、新增黑名单位于扇区20-29、新删黑名单位于30-39
//黑名单位于扇区40-874,200条灰记录位于扇区900-999、2000笔脱机数据位于1000-1999扇区
#define PriceFS 6 //油品油价表在6、7扇区各存一份
#define StationFS 8 //油站通用信息在扇区8 存一份
#define WhiteFS 10 //白名单存储的第一个扇区号
#define AddBlackFS 20 //新增黑名单存储的第一个扇区号
#define DelBlackFS 30 //新删黑名单存储的第一个扇区号
#define BlackFS 40 //基础黑名单存储的第一个扇区号
#define GrayRecordDataFS 900 //灰记录数据存储的第一个扇区号
#define TransactionDataFS 1000 //成交数据存储的第一个扇区号
#define NumberOfTransactionRecord 2000 //脱机数据的最大数目
#define NumberOfGrayDataRecord 100 //灰记录数据的最大数目
#define LengthOfPriceVerInfo 203 //油品油价信息的长度
#define LengthOfStationVerInfo 19 //油站通用信息的长度
#define AddressOfStationVerInfo 48 //油站通用信息在2402中的存储地址
#define LengthOfBlackVerInfo 18 //基础黑名单数据的长度
#define AddressOfBlackVerInfo 72 //基础黑名单数据在2402中的存储地址
#define LengthOfAddBlackVerInfo 4 //新增黑名单数据的长度
#define AddressOfAddBlackVerInfo 92 //新增黑名单数据在2402中的存储地址
#define LengthOfDelBlackVerInfo 4 //新删黑名单数据的长度
#define AddressOfDelBlackVerInfo 96 //新删黑名单数据在2402中的存储地址
#define LengthOfWhiteVerInfo 4 //白名单数据的长度
#define AddressOfWhiteVerInfo 100 //白名单数据在2402中的存储地址
#define LengthOfTransactionRecord 32 //成交记录的长度
#define AddressOfTransactionRecord1 128 //成交记录存储地址1
#define AddressOfTransactionRecord2 160 //成交记录存储地址2
#define LengthOfTransactionData 97 //成交数据(灰记录)的长度
byte bdata PCCOMM;
sbit ReceivedFlagOfPC=PCCOMM^0; //是否已经接收到来自PC的一帧数据
sbit ReceivedFlag1OfPC=PCCOMM^1; //是否已经接收到来自PC的一帧数据
sbit Received0xfa=PCCOMM^2; //是否已接收到0xfa的标志
sbit Sent0xfa=PCCOMM^3; //是否已发送0xfa的标志
sbit PCOffLine=PCCOMM^4; //与PC通讯脱机的标志
sbit CheckDLDataFlag=PCCOMM^6; //需要检测下载数据
sbit RequestDownLoad=PCCOMM^7; //请求下载基础黑名单数据
byte xdata SendPCTransactionData; //向PC发送交易数据的标志
byte bdata PCCOMM1;
sbit ErrorInfo=PCCOMM1^1; //需要向PC发送错误信息
sbit SendBufferFlag=PCCOMM1^2; //向PC发送数据使用的缓存区的标志
sbit CardInsert=PCCOMM1^3; //卡是否已插入的标志位
sbit TMACError=PCCOMM1^7; //为1 则需要重新计算T_MAC
byte xdata EmpCardFlag;
word xdata TimerOfOnDuty;
byte xdata CheckBlackWhite; //需要向PC查询黑/白名单
byte xdata TypeOfCheckBW; //0-使用后台黑/白名单、1-使用油机内部黑/白名单
byte xdata CheckGrayRecord; //需要向PC查询灰记录
byte xdata SendTimes; //送卡状态的次数
byte xdata TimerOfInit;
byte xdata BufferOfReceiveFromPC[256] _at_ StartAddOfRFPC;//已接收到的PC数据的存储缓冲区
word xdata ReadAddressOfRFPC; //接收到的PC数据在接收缓冲区中的读出地址
byte xdata ReceivedLengthOfPC; //正在接收的数据帧中已经接收到的数据长度
byte xdata ReceivedLength1OfPC; //正在接收的数据帧中已经接收到的数据长度
byte xdata TimerOfRFPC; //接收PC数据的帧间定时(接收到一字节后10毫秒内再没有接收到数据则准备重新接收)
byte xdata TimerOfPCOffLine; //用于检测与PC通讯是否中断(5秒没有接收到PC数据则认为通讯断)
byte xdata ReceivedDestAddress; //接收到的目的地址
byte xdata ReceivedSrcAddress; //接收到的源地址
byte xdata ReceivedPCTTL; //接收到的PC帧号
byte xdata ValidLengthOfRFPC; //接收到的有效长度
byte xdata TimerOfSTPC; //向PC送数的时间间隔为0.5秒
byte xdata SendPCTTL; //发送到PC的帧号
byte xdata TimesOfSendTraction; //上送成交数据的次数
byte xdata BufferOfSendToPC[128] _at_ StartAddOfSTPC;//待发送到PC的数据的存储缓冲区
byte xdata BufferOfSendToPC1[128] _at_ StartAddOfSTPC1;//待发送到PC的数据的存储缓冲区
word xdata ReadAddressOfSTPC; //待发送到PC的数据在发送缓冲区中的读出地址
byte xdata LengthOfSTPC; //还需要发送到PC的数据的长度
//byte xdata Sent0xfa; //是否已发送0xfa的标志
byte xdata ApplyDL;
byte xdata ApplyDownLoad; //申请下载(1-已申请下载基础黑名单、2-已申请下载新增黑名单
// 3-已申请下载新删黑名单、4-已申请下载白名单
// 5-已申请下载油品油价、6-已申请下载通用信息
// 7-已申请下载私有数据、8-已申请下载新的程序)
byte xdata DownLoadFlag; //下载数据标志(1-正在下载基础黑名单、2-正在下载新增黑名单
// 3-正在下载新删黑名单、4-正在下载白名单
// 5-正在下载油品油价、6-正在下载通用信息
// 7-正在下载私有数据、8-正在下载新的程序)
dword xdata DLTotalLength; //要下载的数据的总长度
word xdata DLSegOffset; //本次要下载的段偏移
byte xdata DLLength; //本次要下载的长度
word xdata DLSector; //本次下载的扇区号
union Hex_2 xdata Hex2; //2字节16进制数
union Hex_4 xdata Hex4; //4字节16进制数
byte xdata CheckDLData; //检查下载数据的标志
//1-正在检查基础黑名单、2-正在检查新增黑名单
//3-正在检查新删黑名单、4-正在检查白名单
//5-正在检查油品油价、 6-正在检查油站通用信息
byte xdata TimerOfDownLoad;
word xdata TotalSectorNum; //正在检测名单占有的扇区数
word xdata SectorNum; //正在检查的扇区号
byte xdata InfoList[16]; //下载黑白名单时存储名单信息
byte xdata Buffer[256] _at_ 0x1200; //存储临时数据
byte xdata TimerOfCheckOffLineData;
byte xdata OilNumber[2];
byte xdata TimerOfOnLamp1s; //1秒钟刷新一次
byte xdata ErrorInformation[128]; //暂存加油机出错信息
byte xdata ErrorLen;
struct BlackInfo xdata BlackVerInfo,BlackVerInfo1;//基础黑名单版本信息
struct BlackWhiteInfo xdata AddBlackVerInfo,AddBlackVerInfo1;//新增黑名单版本信息
struct BlackWhiteInfo xdata DelBlackVerInfo,DelBlackVerInfo1;//新删黑名单版本信息
struct BlackWhiteInfo xdata WhiteVerInfo,WhiteVerInfo1;//白名单版本信息
struct PriceInfo xdata PriceVerInfo _at_ 0x1800;
struct PriceInfo xdata PriceVerInfo1;//油品油价版本信息
struct StationInfo xdata StationVerInfo,StationVerInfo1;//油站通用信息
struct TransactionRecordInfo xdata TransactionRecord;
struct TransactionRecordInfo xdata TransactionRecord1;//成交记录信息
struct TransactionDataInfo xdata TransactionData;
struct TransactionDataInfo xdata TransactionData1;//成交数据
struct GrayDataInfo xdata GrayData; //灰记录匹配数据
struct TotalDataInfo xdata TotalData[4];//存储读取的累计数
extern struct IcCardData1 xdata IcCardData;//IC卡相关数据
extern byte xdata PopIcCardFlagof2s;//弹卡后等待2秒钟
extern byte xdata CardStatus; //上次的卡状态
extern byte xdata TimerOfJLOffLine;//与计量脱机的时间
extern struct SaveData xdata DataOfSave;
extern struct NozzleData xdata DataOfNozzle;
extern byte idata TimerOfSpeaker;
extern byte idata TimerOfReceivePC;
extern byte xdata IO_Temp[];
//检测是否与PC通讯断,返回值为1 则已断
byte Test_OffLine()
{
if (PCOffLine==0)
return (0);
return (1);
}
dword HexToLong(byte xdata *px,byte i)
{
byte j;
if (i==3)
{
Hex4.c[0]=0;
for (j=0;j<i;j++)
Hex4.c[j+1]=px[j];
}
else
{
for (j=0;j<i;j++)
Hex4.c[j]=px[j];
}
return (Hex4.i);
}
LongToHex(dword i,byte xdata *px,byte j)
{
byte k;
Hex4.i=i;
if (j==4)
{
for (k=0;k<j;k++)
*px++=Hex4.c[k];
}
if (j==3)
{
for (k=0;k<j;k++)
*px++=Hex4.c[k+1];
}
}
//计算CRC 校验和
word CRC_16(byte *buf,word len)
{
word crc=0x0000;
byte c,i,f1;
Clear_WatchDog();
f1=1;
while(len!=0)
{
c=*buf;
if (c!=0xff)
f1=0;
for(i=0;i<8;i++)
{
if ((crc ^ c) & 1)
crc=(crc>>1)^0xa001;
else
crc>>=1;
c>>=1;
}
len--;
buf++;
}
Clear_WatchDog();
if (f1==1)
return (0);
return (crc);
}
//将下载的名单数据保存到28SF040中
//Num-要保存的数据长度、i-要存储到的扇区号
Save_BLackWhite_List(byte Num,word i)
{
byte j;
dword xdata k;
byte xdata *px;
k=i;
k<<=8; //要存储到的地址
j=Num%10; //最后一次下载
Num-=j;
px=StartAddOfRFPC+10;
*px=Num; //暂存数据长度
i=CRC_16(px+1,Num);
px[Num+1]=i>>8; //CRC高字节
px[Num+2]=i; //CRC低字节
write_28sf040(k,Num+3,px); //向28SF040地址k 处写入px地址开始的(Num+3)字节数据
}
//保存基础黑名单的版本信息
Save_BlackVerInfo()
{
word i;
Clear_WatchDog();
BlackVerInfo.CRC=CRC_16((byte *)&BlackVerInfo,LengthOfBlackVerInfo-2);//基础黑名单的CRC校验和
i=BlackFS; //要存储到的扇区号
i<<=8; //要存储到的地址
write_28sf040(i,LengthOfBlackVerInfo,(byte *)&BlackVerInfo);//向28SF040写入基础黑名单
Clear_WatchDog();
Write_2402(AddressOfBlackVerInfo,(byte *)&BlackVerInfo,LengthOfBlackVerInfo);//保存基础黑名单信息
}
//清除基础黑名单的版本信息
Clear_BlackVerInfo()
{
BlackVerInfo.Ver[0]=0; //版本号为0
BlackVerInfo.Ver[1]=0;
BlackVerInfo.Number=0; //名单数量为0
Save_BlackVerInfo(); //存储基础黑名单
}
//获得基础黑名单的版本信息
Load_BlackVerInfo()
{
word i;
i=BlackFS; //要读取的扇区号
i<<=8; //要读取的地址
read_28sf040(i,LengthOfBlackVerInfo,(byte *)&BlackVerInfo1);//从28SF040中读出基础黑名单信息
if (BlackVerInfo1.CRC!=CRC_16((byte *)&BlackVerInfo1,LengthOfBlackVerInfo-2))
{ //28SF040中的基础黑名单信息不正确
Read_2402(AddressOfBlackVerInfo,(byte *)&BlackVerInfo1,LengthOfBlackVerInfo);//从2402中读取基础黑名单信息
if (BlackVerInfo1.CRC!=CRC_16((byte *)&BlackVerInfo1,LengthOfBlackVerInfo-2))
{ //2402中的基础黑名单信息也不正确
if (BlackVerInfo.CRC==CRC_16((byte *)&BlackVerInfo,LengthOfBlackVerInfo-2))
{ //SRAM中信息正确
write_28sf040(i,LengthOfBlackVerInfo,(byte *)&BlackVerInfo);//向28SF040写入基础黑名单
Write_2402(AddressOfBlackVerInfo,(byte *)&BlackVerInfo,LengthOfBlackVerInfo);//保存基础黑名单信息
}
else
{
Clear_BlackVerInfo(); //没有基础黑名单信息,清除信息
Send_Error_Information("基础黑名单初始化!");
}
}
else
write_28sf040(i,LengthOfBlackVerInfo,(byte *)&BlackVerInfo1);//向28SF040写入基础黑名单
}
read_28sf040(i,LengthOfBlackVerInfo,(byte *)&BlackVerInfo);//从28SF040中读出基础黑名单信息
}
//保存基础黑名单信息
Save_BlackList_Info()
{
DownLoadFlag=0; //清除正在下载基础黑名单的标志
BlackVerInfo.Ver[0]=InfoList[0]; //版本号高字节
BlackVerInfo.Ver[1]=InfoList[1]; //版本号低字节
BlackVerInfo.ValidDate[0]=InfoList[2];//有效日期中年的高位字节
BlackVerInfo.ValidDate[1]=InfoList[3];//有效日期中年的低位字节
BlackVerInfo.ValidDate[2]=InfoList[4];//有效日期中月份
BlackVerInfo.ValidDate[3]=InfoList[5];//有效日期中日期
BlackVerInfo.StopDate[0]=InfoList[6]; //截止日期中年的高位字节
BlackVerInfo.StopDate[1]=InfoList[7]; //截止日期中年的低位字节
BlackVerInfo.StopDate[2]=InfoList[8]; //截止日期中月份
BlackVerInfo.StopDate[3]=InfoList[9]; //截止日期中日期
BlackVerInfo.ValidRegion[0]=InfoList[10];//有效区域高字节
BlackVerInfo.ValidRegion[1]=InfoList[11];//有效区域低字节
BlackVerInfo.Number=HexToLong(InfoList+12,4);//名单数量
Save_BlackVerInfo(); //保存基础黑名单版本信息
}
//存储基础黑名单
Save_BlackList()
{
byte i;
dword xdata j;
Clear_WatchDog();
if (ApplyDownLoad==1)
{ //下载数据为基础黑名单信息
for (i=0;i<16;i++)
InfoList[i]=XBYTE[StartAddOfRFPC+11+i];//暂存基础黑名单信息
if (DLTotalLength==16)
Save_BlackList_Info(); //数据全部下载完毕
else
{
Clear_BlackVerInfo(); //清除基础黑名单版本号
DLSector=1; //继续下载的数据存储在第二个扇区中
}
}
else
{ //下载的是基础黑名单数据
i=ValidLengthOfRFPC-5; //下载数据的实际长度
Save_BLackWhite_List(i,DLSector+BlackFS);//存储到28SF040中
if (RequestDownLoad==0)
{ //不是检测中下载数据
j=DLSector-1;
j*=240;
j+=i+16; //得到实际已经下载的数据的长度
if (j>=DLTotalLength)
Save_BlackList_Info(); //数据全部下载完毕
else
DLSector++; //要写入的扇区号加一,继续下载
}
else
RequestDownLoad=0; //清除请求下载的标志位
}
}
//保存新增黑名单的版本信息
Save_AddBlackVerInfo()
{
word i;
AddBlackVerInfo.CRC=CRC_16((byte *)&AddBlackVerInfo,LengthOfAddBlackVerInfo-2);//新增黑名单的CRC校验和
i=AddBlackFS; //要存储到的扇区号
i<<=8; //要存储到的地址
write_28sf040(i,LengthOfAddBlackVerInfo,(byte *)&AddBlackVerInfo);//向28SF040写入新增黑名单
Write_2402(AddressOfAddBlackVerInfo,(byte *)&AddBlackVerInfo,LengthOfAddBlackVerInfo);//保存新增黑名单信息
}
//清除新增黑名单的版本信息
Clear_AddBlackVerInfo()
{
AddBlackVerInfo.Ver=0; //版本号为0
AddBlackVerInfo.Number=0; //名单数量为0
Save_AddBlackVerInfo(); //存储新增黑名单
}
//获得新增黑名单的版本信息
Load_AddBlackVerInfo()
{
word i;
i=AddBlackFS; //要读取的扇区号
i<<=8; //要读取的地址
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -