⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pack_comm.c

📁 税控收款机源码:拼音输入法,LCD,VFD驱动,IC卡驱动,税控国标
💻 C
📖 第 1 页 / 共 4 页
字号:
/*-------------------------------------------------------------
功能:在一定通讯协议下与上位管理系统之间的数据包串口通讯
说明:符合国家标准GB18240.1-2003和GB18240.2-2003的税控机软件
日期:2003年6月12日

---------------------------------------------------------------*/
#include "include.h"

#define ANSWER_ACK  0X32
#define ANSWER_NAK  0X33


#define    TOTAL_DATA_LEN	1024	//每包数据总长度
//#define    FAU_DATA_START_ADD       0X40000

//uchar code bbb[]={//0x32,0};
//0x00 ,0x35 ,0x00 ,0x01 ,0xC9 ,0xCC ,0xC6 ,0xB7 ,0x30 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,0x00 ,0x00 ,0x00 ,0x00,0x00 
//,0x00 ,0x20 ,0x4E ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
//0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x01 ,0x02 ,0x31 ,0x54 ,0x7E ,0x99 };

//==================================================================
void send_ACK_NAK(uchar command)
{
	uchar buf[6];
	uint crctemp;
	buf[0]=0x68;
	buf[1]=command;
	buf[2]=0;
	crctemp=crcxdata(2,buf+1);
	buf[3]=crctemp;
	buf[4]=crctemp>>8;
	buf[5]=0x66;
	send_str(6,buf);
}
//=================================================================
void Back_Outorder(uchar mode,uchar index,uchar len,uchar *out_data)
{
	uint cs;
	uchar data_len;
	uchar buf[256];
	if(mode==0)
	{
	    buf[0]='E';
		buf[1]='R';
	    send_str(2,buf);
	}
	else
    {
		buf[0]='O';
		buf[1]='K';
		buf[2]=index;
		buf[3]=len+4;
		memcpy(&buf[4],out_data,len);
		data_len=buf[3];
		cs=crcxdata((uint)data_len,buf);
		buf[data_len]=cs>>8;
		buf[data_len+1]=cs;
		data_len+=2;
		send_str(data_len,buf);
    }
}
//==========================================================================================
//找滚动前的明细记录如:当前的扇区为1,找的是从第2扇区开始的符合条件的明细
//* startdate,uchar *enddate :起止时间
//*addr开始的地址,返回下一条的地址
//mode 0:从要开始的扇区头开始 1:以*add为地址开始找
//==================================================================================================
uchar LookUp_inv_list_roll(uchar * startdate,uchar *enddate,ulong *addr,uchar mode,struct record_struct *record)
{
	struct record_addr_struct RecordAddr; 
	
	
	uchar i,j;
	uchar tmp;
	uchar sector; //扇区号
	uint  size;
	ulong addr_tmp;
	uint  crc;
	uchar finded,start;//是否找到需要的明细数据
	uchar lrc;
    uchar datatemp[10];

    read_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),&RecordAddr);
	crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
	if(crc!=RecordAddr.crc)
	{
		if(read_eeprom(RECORD_ADDR2,(uint)sizeof(RecordAddr),&RecordAddr))
			return(READ_EEPROM_FAIL);
		
		crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
		if(crc!=RecordAddr.crc)
			return(CRC_ERROR);
	}
    //send_str((uint)sizeof(RecordAddr),&RecordAddr);
	if(RecordAddr.record_addr==RECORD_START_ADDR) //没有写数据
		return(1);
	//从起始扇区顺序读
	if(mode==0)
	{
	 
	 if(RecordAddr.start_sector!=RECORD_SECTOR[(uint)sizeof(RECORD_SIZE)-1])
	 {
	 size=0;
	 sector=RecordAddr.start_sector+1;//
	 //2005.8.14
 	 for(i=RECORD_SECTOR[0],j=0;i<(RecordAddr.record_sector+1);i++,j++)size+=RECORD_SIZE[j]; //KBYTE
	 addr_tmp=(ulong)size*1024+RECORD_START_ADDR; //起始扇区的起始地址
	 //send_str(2,&size);
	 //send_str(4,&addr_tmp);
	 }
	 else return SEEK_FAIL;
	}
	else
	 addr_tmp=*addr;
	  start=1;
	  finded=0;
   //send_str(4,&addr_tmp);
	while(1) //没到最后写的一笔记录的结束地址或查找完毕
	{
		
		//-----先读出该票的项目数---------//
		if(!start) addr_tmp++; //同扇区的下一张票的起始地址//去掉一张发票的经营项目数的数据
		if(read_flash(addr_tmp,1,&tmp))return(READ_FLASH_FAIL);
		if(tmp==0xFF)//没有写数据则换扇区
		{
		  //2005.8.27
		   //if(mode==0)return SEEK_FAIL;
			sector++;
			if(sector>RECORD_SECTOR[(uint)sizeof(RECORD_SIZE)-1])
				sector=RECORD_SECTOR[0];
			//sector扇区的起始地址
			size=0;
			for(i=0,j=0;i<(uint)sizeof(RECORD_SIZE);i++,j++)
			{	size+=RECORD_SIZE[j]; //KBYTE
				if(((ulong)size*1024+RECORD_START_ADDR)>addr_tmp)
			     { addr_tmp=(ulong)size*1024+RECORD_START_ADDR;break;}
	        }
			if(read_flash(addr_tmp,1,&tmp))
			return(READ_FLASH_FAIL);
			if(tmp==0xFF)return SEEK_FAIL;
	
	
		}
		if(read_flash(addr_tmp+RECORD_LENGTH-1,1,&tmp))return(READ_FLASH_FAIL);
			
        	//读出记录全部信息
		if(read_flash(addr_tmp,(uint)(RECORD_LENGTH+INVOICE_ITEM_LEN*tmp+1),record))//明细记录为:定长+变长
			return(READ_FLASH_FAIL);
		//send_str((uint)(RECORD_LENGTH+INVOICE_ITEM_LEN*tmp+1),record);
		//校验
		lrc=lrcdata(RECORD_LENGTH+INVOICE_ITEM_LEN*record->item_num,//record.item_num,
			1,record);
	    
		if(lrc!=((uchar *)record)[RECORD_LENGTH+INVOICE_ITEM_LEN*record->item_num])//record.item_num])
			return(LRC_ERROR);
			//2005.7.26
		 	memcpy(datatemp,record->date,4);
	       uzip_date(datatemp,datatemp);
		   //send_str(3,datatemp);
		if(memcmp(datatemp,enddate,3)>0) //大于结束日期
			return SEEK_FAIL;
		if(memcmp(datatemp,startdate,3)>=0 &&
			 memcmp(datatemp,enddate,3)<=0) //找到				
		   {
            finded=1;
		   }
		  /*else                         //找到 不符合日期                
		  {
		    if(start_addr_finded) 
			return OK;//查找完毕
		   }
	     */
        //2005.8.13
		 addr_tmp+=RECORD_LENGTH+(uint)INVOICE_ITEM_LEN*tmp; //该票的结束地址
		 size=0;	
		for(i=RECORD_SECTOR[0],j=0;i<RECORD_SECTOR[(uchar)sizeof(RECORD_SECTOR)];i++,j++)
			size+=RECORD_SIZE[j]; //KBYTE
		if((addr_tmp>=((ulong)size*1024+RECORD_START_ADDR))&&!finded) return SEEK_FAIL;//没找到
		else if((addr_tmp>=((ulong)size*1024+RECORD_START_ADDR))&&finded) return OK;//查找完毕到最后一条找
		
		if(addr_tmp==(ulong)size*1024+RECORD_START_ADDR) //该票的结束地址到了最后一个扇区的结束地址
		{
		  addr_tmp=RECORD_START_ADDR;//开始扇区的起始地址
		  start=1;
		}
		else
		  start=0;
		if(finded) 
		{
		  if(!start) addr_tmp++; //同扇区的下一张票的起始地址
		  *addr=addr_tmp;
		  return 0;
		}
	}
}
//======================================================
//按日期找日记录
uchar query_by_date(uchar *start_date,uchar *end_date,uint *start_num,uchar *day_re_num)
{
 struct day_addr_struct  da_addr;
 struct day_struct da;
 uchar error;
 uchar num;
 uint  start;
 ulong addr;
 uchar head;
  //-----读取日记录数据地址-----------//
  error=read_eeprom(DAY_ADDR1,DAY_ADDR_LEN,&da_addr);
  if(error) return READ_EEPROM_FAIL;    
  if(da_addr.crc!=crcxdata(DAY_ADDR_LEN-2,&da_addr))
  {
    error=read_eeprom(DAY_ADDR2,DAY_ADDR_LEN,&da_addr);
    if(error) return READ_EEPROM_FAIL;
  }
  if(da_addr.crc!=crcxdata(DAY_ADDR_LEN-2,&da_addr)) return CRC_ERROR;
   num=0;
   head=0;
   start=0;
   *start_num=0;
   for(addr=DAY_START_ADDR;addr<da_addr.day_addr;addr+=DAY_LEN_FH)//192
  {
    if(read_flash(addr,DAY_LEN_EM,da.date)) return READ_FLASH_FAIL;//64
	start++;
    //if(!((memcmp(da.date,start_date,3)>=0)&&(memcmp(da.date,end_date,3)>=0))) continue; 
    if(memcmp(da.date,start_date,3)<0) continue; 
    if(memcmp(da.date,end_date,3)>0) break;   
   	//if(read_flash(addr,DAY_LEN_FH,buffer)) return READ_FLASH_FAIL;//192
	if(!head){head=1;*start_num=start-1;}
    num++;
	
   
  }//end for
  *day_re_num=num;
   
  if(num>0){return 0; }
  return NO_DATA;  
}
//===================================================================
//根据开始包号读天记录
uchar read_day_re(uchar pack_num,uchar *buffer)
{
	ulong addr;
	addr=pack_num;
	addr*=DAY_LEN_FH;
	addr+=DAY_START_ADDR;
	//addr=DAY_START_ADDR+(ulong)(pack_num*DAY_LEN_FH);
 
	if(read_flash(addr,DAY_LEN_FH,buffer)) return READ_FLASH_FAIL;//192

	return 0;
}
//==================================================================
/*void long_to_str(ulong lendata,uchar *buf)
{
 buf[0]=lendata>>24;
 buf[0]=lendata>>16;
 buf[0]=lendata>>8;
 buf[0]=lendata;
}*/
/*==================================================================
函数功能:数据包串口通讯
入口参数: trans_mode--通讯模式:0:接收1:发送2:其他
	       comm_func--通讯功能;
	       data_len--每个包的数据长度
出口参数:
返回值:   ==POWER_OFF,则表示断电,返回
 	       ==CANCEL,取消操作
 	       ==0,通讯成功
 	       ==其他,通讯失败
全局变量: g_max_plu_no
编制人:     日期:2003-06-25
==================================================================*/
uchar Data_pack_transport(uchar trans_mode,uchar comm_func,uchar data_len)
{
  uchar Hand,pack_tail,Hand_num,key;
  uint pack_num,bc_pack_num,pack_crc,pack_length;
  xdata uchar buf_tr[16],buff[TOTAL_DATA_LEN+9];//	1024+9,每包数据总长度
  uchar per_pack_num;//每包数据的包数
  //struct branch_struct xdata branch[MAX_BRANCH_NUM+1];
  uint plu_num,i,pack_quotient,pack_remainder,LL,valid_data_len;
  uchar j,error;
  uchar check,q=0;
  uchar buf[128];
  ulong addtemp;

  struct day_struct da;
  struct delare_addr_struct declare_addr;
  struct money_add_struct money_add;
  //struct invoice_roll_struct *invoice_roll;
  //struct record_struct  inv_rec;
  uchar ord_lenght;// = data_in[4] + 2 ;                      
  uint  cs;
  uchar csh;
  uchar csl;
  uchar command_type;
  uchar order_mode;
  uchar data_index;
  ulong start_num,end_num,tt;
  #ifdef C6_VER
    select_com(0);
  #else
    select_com(2);
  #endif 
  //modify_rate(6);//57600
  clear_rece_buffer();
  plu_num=0;
  LL=0;
  per_pack_num=TOTAL_DATA_LEN/data_len; //一包可打的数据结构的个数如:数据结构为九个字节 
                                        //一包就可打113个数据结构
  
  //------------握手------------//
  do
  {
    if(low_pwr) return POWER_OFF;//如果断电了,则exit 
    openbacklight();
    key=get_key();
	if((trans_mode==0)||(trans_mode==1))
      {
       if(!rece(6,buf_tr))
         {
	      
         if((buf_tr[1]==0x31)&&(buf_tr[5]==0x66))
          {
           send_ACK_NAK(ANSWER_ACK);
	       break;
          }
        else
         {
       
          send_ACK_NAK(ANSWER_NAK);
         }
       }
     }
  else
     {
      EA=0;
        if(!rece(5,buff))
		 {
          ord_lenght=buff[4]+2;
          if(!rece((ord_lenght-5),&buff[5]))
		    {
			 cs =  crcxdata((ord_lenght-2),&buff[0]);
             csh = (cs&0xff00)>>8;
             csl = (cs&0x00ff);
			 if(
			    (((buff[2]>=0x10) && (buff[2]<=0x19))||(buff[2]==0x01)||(buff[2]==0x56)||(buff[2]==0x60))
			    //&&((buff[ord_lenght-2] ==csh)&&(buff[ord_lenght -1] ==csl))
                )
			   {
                
                command_type=buff[2];
				for(j=0;j<(ord_lenght-7);j++)buf[j]=buff[5+j];//保存命令数据
				order_mode=ord_lenght-7; //收到的数据的长度
                order_mode&=0x7f;      //最高位为标志位
				EA=1;
				break;
			   }
			  else if(buff[2]==0x0)Back_Outorder(1,0,0,buff);//响应写机器编号时的联机回应
			  else Back_Outorder(0,0,0,buf_tr);
			 }
		   else Back_Outorder(0,0,0,buf_tr);
		 }
		 EA=1;
      /*if(!rece(7,buf_tr))
        {
		  ord_lenght = buf_tr[4] + 2 ;                      
          cs =  crcxdata((ord_lenght-2),&buf_tr[0]);
          csh = (cs&0xff00)>>8;
          csl = (cs&0x00ff);
		 if((buf_tr[0]==0x1b)&&(buf_tr[1]==0x10)&&(buf_tr[2]==0x1)
		    &&(buf_tr[3]==0x0)&&(buf_tr[5]==csh)&&(buf_tr[6]==csl)
			)
           {
           buf_tr[0]='O';
		   buf_tr[1]='K';
           buf_tr[2]=0;
		   buf_tr[3]=4;
		   cs = crcxdata(4,&buf_tr[0]);
		   buf_tr[4]=cs>>8;
		   buf_tr[5]=cs;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -