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

📄 deal_data.c

📁 税控收款机源码:拼音输入法,LCD,VFD驱动,IC卡驱动,税控国标
💻 C
📖 第 1 页 / 共 5 页
字号:
			print_error=rlt;
	}
	if(g_printer_sel==0xaa)g_printer_sel=1;//恢复打印机的选择	
	if(print_error)
		return(print_error);
	
	return(rlt);
	
}
#endif

//=========================================================================
void init_trade_info(struct trade_info_struct * trade_info)
{
	trade_info->bit_money_no=0;
	set_value0(trade_info->customer_name,(uint)sizeof(trade_info->customer_name));
	trade_info->decrease_money=0;
	trade_info->discount_money=0;
	trade_info->invoice_type=NORMAL_INVOICE;
	trade_info->menu_num=0;
	trade_info->pay_money=0;
	trade_info->pay_way=0;
	trade_info->invoice_no=0;
	trade_info->pre_money=0;
	trade_info->service_money=0;
	trade_info->subtotal_menuno=0;
	trade_info->subtotal_menunum=0;
	trade_info->subtotal_money=0;
	trade_info->total_money=0;
	trade_info->trade_end=0;
	trade_info->trader_no=0;
	trade_info->table_no=0;

}
/*---------------------------------------------------------------
功能:保存笔交易记录到FLASH,更新其他相关数据
入口参数: record待保存的笔记录地址结构指针
返回值:成功返回0,否则返回其它错误
/*-------------------------------------------------------------*/
uchar save_record_data(struct record_struct * record)					  
{
  /*  struct record_addr_struct 
  {
   ulong record_addr;		                 //电子票根当前地址
   uchar record_sector;        	             //记录当前扇区
   uchar start_sector;                       //电子票根的起始扇区
   uint crc;			                     //电子票根的CRC
  };
*/
	struct record_addr_struct RecordAddr; 
	uchar rlt;
	uint crc;
	ulong record_add;
	//uchar buf[10];
    
    //ulong testadd;
    //uchar testbuff[10];
   // uchar testdisbuf[24];
	//从EEPROM中读笔记录地址(上一笔记录的结束地址)
	read_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),&RecordAddr);
	crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
	//send_str((uint)sizeof(RecordAddr),&RecordAddr);
	if(crc!=RecordAddr.crc)
	{
		if(read_eeprom(RECORD_ADDR2,(uint)sizeof(RecordAddr),&RecordAddr))
			return(READ_EEPROM_FAIL);
		//send_str((uint)sizeof(RecordAddr),&RecordAddr);
		crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
		if(crc!=RecordAddr.crc)
			return(CRC_ERROR);
	}
	if(RecordAddr.record_addr!=RECORD_START_ADDR) //不是第一笔交易//起始地址从8扇区开始524288;
	{
		rlt=calc_record_addr(RecordAddr,&RecordAddr,
			RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN+1);//得到该记录实际存放的起始地址
		if(rlt)
			return(rlt);
	
		
	}
	record->lrc=lrcdata((RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN),1,record);
	//if(record->item_num<PAGE_ITEM_NUM)//项数可变,移动LRC到最后一个有用项后小于9项
		((uchar *)record)[RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN]=record->lrc;
	/*if(low_pwr==1)
	              {                       ///掉电测试时LRC可能出问题
	               rlt=lrcdata((RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN),1,record);	
				   if(rlt!=((uchar *)record)[RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN])
				    {
		             record->lrc=lrcdata((RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN),1,record);
					 if(record->lrc!=rlt)
					 {
					  //send_char(0xaa);
					  rlt=lrcdata((RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN),1,record);
                      ((uchar *)record)[RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN]=rlt;
					 }
					 else ((uchar *)record)[RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN]=record->lrc;
				    }
                  }
	 */
	if (write_flash(RecordAddr.record_addr,(uint)(RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN+1),record))
	 {
	  //send_char(0xbb);
	  delayms(50) ;
	  rlt=lrcdata((RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN),1,record);
       ((uchar *)record)[RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN]=rlt;
	  if (write_flash(RecordAddr.record_addr,(uint)(RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN+1),record))
	   {
	    delayms(50) ;
	     if (write_flash(RecordAddr.record_addr,(uint)(RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN+1),record))
		return(WRITE_FLASH_FAIL);
		}
	  }
   //if (write_flash(RecordAddr.record_addr+0x10000,(uint)(RECORD_LENGTH+(uint)record->item_num*INVOICE_ITEM_LEN+1),record));
	//新的地址(最后一笔记录的结束地址)存入EEPROM
	record_add=RecordAddr.record_addr;
	//RecordAddr.record_addr+=RECORD_LENGTH+record->item_num*INVOICE_ITEM_LEN;//固定长度+不定长度
    RecordAddr.record_addr=record_add+RECORD_LENGTH+record->item_num*INVOICE_ITEM_LEN;//固定长度+不定长度
	RecordAddr.crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
     //send_str(2,&RecordAddr.crc);
	if(write_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),&RecordAddr))
     {
	  if(write_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),&RecordAddr)) 
	   return(WRITE_EEPROM_FAIL);
	 }
	//send_str((uint)sizeof(RecordAddr),&RecordAddr);
	/*if(low_pwr==1)
	{
	 crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
	 if(crc!=RecordAddr.crc)RecordAddr.crc=crcxdata((uint)sizeof(RecordAddr)-2,&RecordAddr);
	 if(read_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),buf))
	   return(READ_EEPROM_FAIL);
	   
	 if(memcmp(&RecordAddr,buf,(uint)sizeof(RecordAddr))!=0)
	 {
	  
	  if(write_eeprom(RECORD_ADDR1,(uint)sizeof(RecordAddr),&RecordAddr)) 
		return(WRITE_EEPROM_FAIL);
	 }
						
	 }
	 */
	if(write_eeprom(RECORD_ADDR2,(uint)sizeof(RecordAddr),&RecordAddr)) 
	  {
	   write_eeprom(RECORD_ADDR2,(uint)sizeof(RecordAddr),&RecordAddr);
		return(WRITE_EEPROM_FAIL);
       }
	
	//笔记录数据清0
	//set_value0(record,sizeof(*record));
	//明细压力测试
    /*testtiaoshu++;
    set_value0(testdisbuf,24);
	strcpy(testdisbuf,"正在进行明细压力测试");
    lcd_disp(0,0,testdisbuf);
	sprintf(testdisbuf,"地址:%010lu",RecordAddr.record_addr); 
    lcd_disp(2,0,testdisbuf);
    sprintf(testdisbuf,"明细条数:%010lu",testtiaoshu); 
    lcd_disp(3,0,testdisbuf);
	*/
	return(0);
}
/*---------------------------------------------------------------
 功能:计算天记录在FLASH中的当前保存地址
  入口参数: DayAddr上一天的结束地址及所在扇区的天记录地址结构
           
 出口参数: newDayAddr:该天发票存放的起始地址及所在扇区的天记录地址结构
  
  返回值:成功返回0,否则返回其它错误
/*-------------------------------------------------------------*/
uchar calc_DayData_addr(const struct day_addr_struct DayAddr,struct day_addr_struct* newDayAddr)
         				 
{
	uchar i,j;
	uint size;

	i=0;
	j=0;
	size=0;
	if(
	   DayAddr.day_addr+(uint)sizeof(struct day_struct)+0x80<DAY_START_ADDR ||
       DayAddr.day_sector<DAY_SECTOR[0] ||
       DayAddr.day_sector>DAY_SECTOR[(uint)sizeof(DAY_SECTOR)-1]
	  )
 	 return(ADDR_FLASH_FAIL);	 //地址错

	while(1)
	{
    
		size+=DAY_SIZE[i];
		if((ulong)size*1024+DAY_START_ADDR>=
			DayAddr.day_addr+(uint)sizeof(struct day_struct)+0x80)//
      			break;
		i=(i+1)%((uint)sizeof(DAY_SECTOR));

	}

	newDayAddr->day_sector=DAY_SECTOR[i];

	if (newDayAddr->day_sector!=DayAddr.day_sector) 
	{
		//擦出该扇区
		if (flash_sector_erase(newDayAddr->day_sector))
      		return(ERASE_FLASH_FAIL);
		//计算该扇区的开始地址
		/*size=0;
		for(j=0;j<i;j++)
     		size+=DAY_SIZE[j];
		//扇区末不足记录天记录的字节不用直接跨入下一扇区
		newDayAddr->day_addr=(ulong)size*1024+DAY_START_ADDR;
		*/
	}
	//else
		newDayAddr->day_addr=DayAddr.day_addr;

	if(
	 newDayAddr->day_addr<DAY_START_ADDR ||
     newDayAddr->day_sector<DAY_SECTOR[0] ||
     newDayAddr->day_sector>DAY_SECTOR[(uint)sizeof(DAY_SECTOR)-1]
	 )
	return(ADDR_FLASH_FAIL);	//地址错
	return(0);
}
/*---------------------------------------------------------------
 功能:检查是否到了新的一天,是则保存日交易记录到FLASH
 输出:成功返回0,否则返回其它错误
/*-------------------------------------------------------------*/
uchar save_day_data(void)
{
	struct day_addr_struct DayAddr; 
	uchar xdata tmp[7];
	struct day_struct DayData;
	uchar xdata cmd[150],buf[200];//
	uchar rlt,i;
	uint crc;
	//ulong temp;

    if(low_pwr)return(POWER_OFF);//掉电
    if(!g_tax_pin_pass)return(0);//口令未通过
	rlt=0;
	set_value0(cmd,(uint)sizeof(cmd));
	set_value0(buf,(uint)sizeof(buf));
     if(read_eeprom(DAY_ADDR1,(uint)sizeof(DayAddr),&DayAddr))
		   {
			if(read_eeprom(DAY_ADDR2,(uint)sizeof(DayAddr),&DayAddr))
     			return(READ_EEPROM_FAIL);	
      		crc=crcxdata((uint)sizeof(DayAddr)-2,&DayAddr);
			if(crc!=DayAddr.crc)
      			return(CRC_ERROR);	
		   }
		  else
		   {
			crc=crcxdata((uint)sizeof(DayAddr)-2,&DayAddr);
			if(crc!=DayAddr.crc)
			{
      			if(read_eeprom(DAY_ADDR2,(uint)sizeof(DayAddr),&DayAddr))
     				return(READ_EEPROM_FAIL);
					//send_char(DayAddr.crc);//ff
      			crc=crcxdata((uint)sizeof(DayAddr)-2,&DayAddr);
				//'send_char(crc);//94
				if(crc!=DayAddr.crc)
      				return(CRC_ERROR);
		     }
	    	}
			//DayAddr.day_addr+=192;
    //send_str(4,(uchar*)&DayAddr.day_addr);
   //if((DayAddr.day_addr+192)>2064384)	return(LOCK_DATE);//(uint)sizeof(DayData)+0x80提前两天锁机
    
	if(DayAddr.day_addr>(INVOICE_ROLL_START_ADDR-(uint)sizeof(DayData)-0x80))	return(LOCK_DATE);
   //从EEPROM中读日记录数据
	if(read_eeprom(DAY,(uint)sizeof(DayData),&DayData))
		return(READ_EEPROM_FAIL);
	//send_str(4,DayData.date);
	if(lrcdata((uint)sizeof(DayData)-1,0,&DayData))
      {
       
		return(LRC_ERROR);
      }
   
/*
	if( (DayData.invoice_num+DayData.rescissory_num+DayData.retreat_num==0)&&
	    (DayData.date[0]==0)&& 
	    (DayData.date[1]==0)&&
	    (DayData.date[2]==0)
	   )
		return(0);//没有保存的数据
*/
	if (read_rtc(tmp))
		return(READ_CLOCK_FAIL);//读时钟错误
   
	if(DayData.date[0]!=tmp[0] || DayData.date[1]!=tmp[1] ||  //年月日
	      DayData.date[2]!=tmp[2])  //新的一天
         
	   {
        while(1)//可能多天的零记录
        {
	      	//从EEPROM中读日记录地址(该记录应存的起始地址)
         if(low_pwr) return(POWER_OFF);//等1时表示已关掉了交流电
		 
	
		 strcpy(cmd,"DAC0FB000041");
		 //命令数据区
		 buf[0]=0x20;
		 memcpy(&buf[1],DayData.date,3);
		buf[4]=DayData.invoice_num >>8;
		buf[5]=DayData.invoice_num &0xFF;
		buf[6]=DayData.retreat_num >>8;
		buf[7]=DayData.retreat_num &0xFF;
		buf[8]=DayData.rescissory_num >>8;
		buf[9]=DayData.rescissory_num &0xFF;
		for(i=0;i<6;i++)
		{
			buf[10+i]=DayData.tax_item_code[i];
			ltoa(DayData.sale_money[i],&buf[16+i*4]);
			ltoa(DayData.retreat_money[i],&buf[40+i*4]);
		}
		buf[64]=lrcdata(64,1,buf);
        
		rlt=pack_cmd(cmd,buf,0x41,0);
		//rlt=pack_cmd(cmd,buf,0x41,0x81);
		if(rlt)
			return(rlt);
		//send_str(75,cmd);

		//testbuf[0]=0xaa;
		rlt=sam_iso(cmd);
	
		if(rlt)
			return(SAM_COMM_FAIL);
		//send_str(134,cmd);
		//		do{}while(1);
		
		rlt=get_data(cmd);
		if(rlt)
			return(CARD_ERROR);
	  
		//send_str(129,cmd);
		
		//if(GetResponse(SAM_CARD,0x81,&buf[(uint)sizeof(DayData)])) //04.11 09改
		//	return(CARD_ERROR);
		memcpy(buf,&DayData,(uint)sizeof(DayData));
		memcpy(buf+(uint)sizeof(DayData),cmd,0x80);
       if(DayAddr.day_addr!=DAY_START_ADDR) //不是第一天
	    {
     
		//得到该记录实际存放的起始地址
     	rlt=calc_DayData_addr(DayAddr,&DayAddr);
      	if(rlt)
      		return(rlt);
     	}
 
		//为节省空间不存返回的数据的校验和
		if (write_flash(DayAddr.day_addr,(uint)sizeof(DayData)+0x80,buf))
     		return(WRITE_FLASH_FAIL);
	    
     	//日记录地址
		DayAddr.day_addr+=(uint)sizeof(DayData)+0x80; //下一个记录应存的起始地址
		//DayAddr.day_num++;
		//校验
		DayAddr.crc=crcxdata((uint)sizeof(DayAddr)-2,&DayAddr);
		
		/*testtiaoshu=0;
	    while(1)//天记录压力测试
		{
         if(DayAddr.day_addr!=DAY_START_ADDR) //不是第一天
	    {
     
		//得到该记录实际存放的起始地址
     	rlt=calc_DayData_addr(DayAddr,&DayAddr);
      	if(rlt)
      		return(rlt);
     	}
		if (write_flash(DayAddr.day_addr,(uint)sizeof(DayData)+0x80,buf))
     		return(WRITE_FLASH_FAIL);
	    
     	//日记录没有滚存
		DayAddr.day_addr+=(uint)sizeof(DayData)+0x80; //下一个记录应存的起始地址
		//DayAddr.day_num++;
		//校验
		DayAddr.crc=crcxdata((uint)sizeof(DayAddr)-2,&DayAddr);

	   testtiaoshu++;
       strcpy(buf,"正在进行天记录压力测试");
       lcd_disp(0,0,buf);
	   sprintf(buf,"天记录地址:%010lu",DayAddr.day_addr); 
       lcd_disp(2,0,buf);
       sprintf(buf,"天记录条数:%010lu",testtiaoshu); 
       lcd_disp(3,0,buf);
	   delayms(10000);
	  if(get_key()==VOID)break;
		}
	  */	
		//新的地址存入EEPROM
		if(write_eeprom(DAY_ADDR1,(uint)sizeof(DayAddr),&DayAddr)) 
     

⌨️ 快捷键说明

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