示例#1
0
  //**************************8
  // 3整组测量。          
  //功能: 实现某组电池的整组测量。
  //************************* 
void TotalGrpMeasure(void )
{
    unchar i;
    unchar s[12];
     
     unint fint;
     float fres;
     float f,arf[3];    

 switch(MenuStatus)
 {
 case 2:
     if(CURPATH.CurrentDirStarClusID !=0)
       {
         CURPATH.CurrentDirStarClusID = 0;
       } 
     if((ReadFile("CONFIG  TXT", (unchar*)pCfgHead, 0,sizeof (CFG_HEAD))!=0xff))//取出系统头
     {
      
      Index = 1;

     // t=*(unint*)Temp;再次出现字节对齐的问题,开始调试的时候是没问题的现在又出了。。。
         s[0] = Index/1000+0x30;         
         s[1] = (Index%1000)/100+0x30;
         s[2] = ((Index%1000)%100)/10+0x30;
         s[3] = ((Index%1000)%100)%10+0x30;
         s[4] = '\0'; 
       

      Str_8x16(0,0,"组:");
      Str_8x16(0,3,s);
 


      DispFanBai(0,3,4);
      MenuStatus =1000;
     }
     else
     {
       Str_8x16(1,0 ,"系统文件不存在");
       Delay_ms(2000);
       MenuStatus = 3;
       return;
     } 
  break;
 case 1000:
   
         switch(GetKey1())
         {
         case ENTER_KEY:
           DispFanBai(0,3,4);//组位置取消反白
           //先从config文件读出该组电池对应的组属性域;
          
          if( ReadFile("CONFIG  TXT",(unchar*)pGrpHead,Index*64,sizeof (GRP_HEAD))==0xff)
          {
            Str_8x16(2,0,"系统配置文件错误");
            Delay_ms(2000);
            MenuStatus =3;
            return;
          }
     
           
           
           //进入该组所在的目录如果没有该组就建立该组的目录。并在该目录下根据时间建立该组的测量文件
           
        if(CURPATH.CurrentDirStarClusID !=0)
       {
         CURPATH.CurrentDirStarClusID = 0;
       }
         s[0] = Index/1000+0x30;         
         s[1] = (Index%1000)/100+0x30;
         s[2] = ((Index%1000)%100)/10+0x30;
         s[3] = ((Index%1000)%100)%10+0x30;
         s[4] = '\0';
       if(ChgDir(s)==0xff)//没有该目录建立该目录并进入
       {
         CreateDir(s);
            
       }
       ChgDir(s);
       DIR *ID=(DIR*)&Temp[12];
       s[0] = year/1000+0x30;
       s[1] = (year%1000)/100+0x30;
       s[2] = ((year%1000)%100)/10+0x30;
       s[3] = ((year%1000)%100)%10+0x30;    
       s[4]=month/10+0x30;
       s[5]= month%10+0x30;
       s[6]= day/10+0x30;
       s[7]=day%10+0x30;
       s[8]='D';
       s[9]='A';
       s[10]='T';
       s[11]=0;
       
         
         
       if(GetFileID(s, ID)==0xffff)//文件不存在建立之并根据config.txt建立该文件的默认头部
          {
            CreateFile(s);
         
            pMeasureHead=(MEASURE_HEAD*)Temp;
            pMeasureHead->DeviceID=pCfgHead->DeviceID;
            pMeasureHead->BatGrpID=pGrpHead->BatGrpID;
            pMeasureHead->BatNumbers=pGrpHead->BatNumbers;
            AppendData(s,(unchar*)pMeasureHead,sizeof (MEASURE_HEAD));
          }
       //判定该组电池今天已经测量了多少块以便进行下面的测量。
           Index =(ID->FilePosit.Size-16)/8+1;//已经存在的电池测量数据组
           if(Index>=pGrpHead->BatNumbers)
           {
             Str_8x16(1,0,"该组已经测量完毕");
            Delay_ms(2000);
            MenuStatus =3;
            return;
             
           }
        s[0] = Index/1000+0x30;
       s[1] = (Index%1000)/100+0x30;
       s[2] = ((Index%1000)%100)/10+0x30;
       s[3] = ((Index%1000)%100)%10+0x30;           
       s[4] = 0;
       Str_8x16(0,12,s);
       
         
         //给cy单片机上电打开串口并进行串口初始化;
         pRecv0Str=&Temp[20];//设置接收缓冲区的地址。       
         POWRON_CY;
         Init_Uart0;

         Uart0RxTimeOut = 0;
         //等待cy单片机的响应包;
         while(1)
         {
           if(GetKey2( pAck,Temp,10)!=NULL)
           {
             //判定得到的数据是否合法
             if((Temp[4]==0x04)&&(Temp[5]==0x03)&&(Temp[6]==0x02)&&(Temp[7]==0x01))
             {
               unchar  data[4];
               data[0] =10;//设定地址为10
               data[1] = 0;
               data[2] = 0;
               data[3] = 0;
               SendCmd(SET_ADRESS,0,data);  
               Uart0RxTimeOut =0;
             
             }
             
             break;
           }
           
          if(Uart0RxTimeOut>=250)
          {
            //cy单片机没有响应退出;
            Str_8x16(1,0,"测量模块没有响应");
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;
          }
         }


             while(1)
             {
               if(GetKey2( pAck,Temp,10)!=NULL)//得到cy的设定地址回应
                 
               {
                 if(Temp[2]==10)
                 {
 
                    break;
                 }                 
                 
                break; 
               }
         if(Uart0RxTimeOut>=250)
          {
            //cy单片机没有响应退出;
            Str_8x16(1,0,"测量模块没有响应");
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;
          }               
             }         
         
         
         
           DispFanBai(0,12,4);//电池编号位置加反白;
         //Index = 1;

           MenuStatus =2000;
           break;
         case UP_KEY:
       
         if(Index ==pCfgHead->NumberBatGrps)
         { 
          Index=1;
          
         } 
         else
         {  
          Index++;
          
         }
         s[0] = Index/1000+0x30;         
         s[1] = (Index%1000)/100+0x30;
         s[2] = ((Index%1000)%100)/10+0x30;
         s[3] = ((Index%1000)%100)%10+0x30;
         s[4] = '\0';
         
         Str_8x16(0,3,s);
         DispFanBai(0,3,4);
           
           break;
         case DOWN_KEY:
          
         if(Index==1)
         { 
          Index = pCfgHead->NumberBatGrps;
         
         } 
         else
         {  
          Index--; 
          
         }  
         s[0] = Index/1000+0x30;         
         s[1] = (Index%1000)/100+0x30;
         s[2] = ((Index%1000)%100)/10+0x30;
         s[3] = ((Index%1000)%100)%10+0x30;
         s[4] = '\0';
         
         Str_8x16(0,3,s);
         DispFanBai(0,3,4);           
           break;
         case ESC_KEY:
           break;
         default:
           break;
         }     
     
   
   
  break;
 case 2000: //开始测量不响应任何按键
   //发送测量命令给cy
   
   i = 0;
   while(1)
   {
    
   Uart0RxTimeOut=0;
     SendCmd(MEASURE_VOLT,10,s);
     while(1)
     { 
       if(GetKey2( pAck,Temp,10)!=NULL)
       {
         memcpy((unchar*)&fint,&Temp[4],2);
         f=(float)fint/1000;//注意字节对齐问题;
        
         if((f>=pGrpHead->BatVoltMin)&&(f<=pGrpHead->BatVoltMax))
         {
           arf[i]=f;
           i++;
           break;
         }
       }
       else if(Uart0RxTimeOut>=250)//超时退出;
          {
            //cy单片机没有响应退出;
            Str_8x16(1,0,"测量模块没有响应");
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;
          }

       
     }
     if(i==3)
     {
       //已经测量了3次
       i =0;
      float f1 = fabsf(arf[0]-arf[1]);
      float f2 = fabsf(arf[0]-arf[2]);
      float f3 = fabsf(arf[2]-arf[1]);
                       
                        
      if((f1<=0.01)&&(f2<=0.01)&&(f3<=0.01))//比较有效性
      {
        
      //夹子夹好了并连续得到三次合格的电压值;
        //退出电压测量进行电阻测量。

//*******************8
   
        //发测量阻值的命令;
        Uart0RxTimeOut = 0;
        
        SendCmd(MEASURE_RES,10,s);
        DispFanBai(0,12,4);//取消反白。
        f=(arf[0]+arf[1]+arf[2])/3;
        while(1)
        {
         if(GetKey2( pAck,Temp,10)!=NULL)
         { 
         
         memcpy(Temp,&f,4);
         memcpy(&fint,&Temp[4],2);
         fres =(float)fint/1000;
         memcpy(Temp,&fres,4);
        // 显示出电压和内阻值;
         sprintf((char*)s,"%5.3f",f);
         Str_8x16(1,5,s);
         Str_8x16(1,5,s);
         Str_8x16(1,0,"电压:");
         Str_8x16(1,10,"V");
         sprintf((char*)s,"%5.3f",fres);
         Str_8x16(2,5,s);
         Str_8x16(2,0,"内阻:");
         Str_8x16(2,10,"mΩ");
           
         //测量结果存储到文件里
       s[0] = year/1000+0x30;
       s[1] = (year%1000)/100+0x30;
       s[2] = ((year%1000)%100)/10+0x30;
       s[3] = ((year%1000)%100)%10+0x30;    
       s[4]=month/10+0x30;
       s[5]= month%10+0x30;
       s[6]= day/10+0x30;
       s[7]=day%10+0x30;
       s[8]='D';
       s[9]='A';
       s[10]='T';
       s[11]=0;
    
       AppendData(s,Temp,8);
       
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       //开始下一个电池的测量
       //  Str_8x16(2,0, "ENT:下一个 ESC:退出");
         ClrKeyBuf();
         unchar key;
       s[0] = Index/1000+0x30;
       s[1] = (Index%1000)/100+0x30;
       s[2] = ((Index%1000)%100)/10+0x30;
       s[3] = ((Index%1000)%100)%10+0x30;         
       s[4] = 0;
       Str_8x16(0,12,s);
       DispFanBai(0,12,4); //测完了当前电池再次反白此电池表明测量完        
        while(1)//等待用户操作;
          
        {
          KeyScan();
          
          key=GetKey1();
         if(key==ENTER_KEY) 
         {
           if(Index==pGrpHead->BatNumbers)
           {
             //测到了最后一块电池退出系统。
             Str_8x16(1,0,"整组测量完毕");
             Delay_ms(2000);
             POWROFF_CY;
             MenuStatus =3;
             return;         
             
             
           }
           else
           {  
             Index++;
           }
           s[0] = Index/1000+0x30;
           s[1] = (Index%1000)/100+0x30;
           s[2] = ((Index%1000)%100)/10+0x30;
           s[3] = ((Index%1000)%100)%10+0x30;         
           s[4] = 0;
           Str_8x16(0,12,s);
           Str_8x16(0,12,s);
           DispFanBai(0,12,4);
           Str_8x16(1,0,"                ");           
           Str_8x16(2,0,"                ");           
           
           Uart0RxTimeOut=0;
           break;
         }
         else if(key==ESC_KEY)
         {
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;            
           
         
         }
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^         
           
        }
        
        
          break;//退出测量阻值的应答循环。
          }
       else if(Uart0RxTimeOut>=250)//超时退出;
          {
            //cy单片机没有响应退出;
            Str_8x16(1,0,"测量模块没有响应");
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;
          }
          
      
        }

        
//***************************************        


      //break;  
       
      }
      else
      {
        //判定为夹子没有夹好
        Str_8x16(3,0,"没夹好请重新测量");
        unchar key;
       while(1)
       {
         KeyScan();
         key=GetKey1();
         if(key==ENTER_KEY)
         {
           i=0;
          Str_8x16(3,0,"                "); 
           break;//继续重试当前电池的测量
         }
         else if(key==ESC_KEY)           //放弃对当前电池测量因为这个电池可能已经坏了接着测下面的电池。
         {
           i =0;
       //先占据文件相应的位置等将来进行单独测量。
       s[0] = year/1000+0x30;
       s[1] = (year%1000)/100+0x30;
       s[2] = ((year%1000)%100)/10+0x30;
       s[3] = ((year%1000)%100)%10+0x30;    
       s[4]=month/10+0x30;
       s[5]= month%10+0x30;
       s[6]= day/10+0x30;
       s[7]=day%10+0x30;
       s[8]='D';
       s[9]='A';
       s[10]='T'; 
       for (unchar j=0;j<8;j++)
         Temp[j]=0;
          AppendData(s,Temp,8);    
       if(Index < pGrpHead->BatNumbers)
       {
         Index++;
        Str_8x16(3,0,"跳过测量下一只      "); 
       }
       else
       {
                //测量完毕;
            Str_8x16(1,0,"整组测量完毕");
            Delay_ms(2000);
            POWROFF_CY;
            MenuStatus =3;
            return;         

       }
       s[0] = Index/1000+0x30;
       s[1] = (Index%1000)/100+0x30;
       s[2] = ((Index%1000)%100)/10+0x30;
       s[3] = ((Index%1000)%100)%10+0x30;         
       s[4] = 0;
       Str_8x16(0,12,s); 
       DispFanBai(0,12,4);

           
         }
           
       }
      // break;
      }
     // break;
     }

   }


        


   
   
   
  
 default:
   break;
 } 
}
Posicao_t key_function(Posicao_t aux)
{

	uint16_t x=aux.x;
	uint16_t y=aux.y;


	uint8_t   ascii_code=0;			// Variável para receber valor ascii
	uint8_t   tecla_liberada=0;		// Variável para receber liberação da tecla
	static uint32_t contador=0;		// Variável para atraso na repetição de tecla
	static uint8_t  key=0;			// Variável auxiliar para valor do ascii

	ascii_code=GetKey();        // GetKey retorna valor ascii apenas 1 vez quando tem algum novo
	tecla_liberada=GetKey2();	// GetKey2 retorna valor 1(true) se tecla ascii for liberada



	if(ascii_code!='\0' && ascii_code!='\n'){		// Se alguma tecla foi pressionada
		key=ascii_code;						// memoriza valor ascii
		contador=1;}						// Iniciar contador(será desativado na borda de subida)

	if(contador!=0){						// Se já tiver iniciado o contador
		contador++;}						// contar +1

	if(contador>1000){						// Se contador atingir o atraso necessário
		ascii_code=key;						// a tecla salva é carregada novamente
		contador=900;}						// reinicia o contador com menor período

	if (tecla_liberada==1){						// Verifica se a tecla ascii foi liberada
		contador=0;}						// cancela contador


  LCD_DrawLine(x,y, 20, LCD_DIR_VERTICAL, RGB_COL_WHITE); 						//Apaga o cursor de texto

     ascii_code=verificaracentos(ascii_code);									//Chama função de modificação para acentuação

     if(ascii_code>31 && ascii_code!='\0' && ascii_code!='\n'){   				//Verifica se o valor ascii é de um caractere gráfico

    	 UB_Font_DrawChar(x,y,ascii_code,&Arial_11x20,aktColor,RGB_COL_WHITE);  //Chama função que imprime caractere
    	 x=x+11;}																//Realiza deslocamento horizontal

   switch (ascii_code){			//Decide entre as teclas com função qual delas foi prescionada

   case 1:
	   menu=0;
   break;

   case 2:								//Função backspace
	   if(x>10){								//Verifica se tem espaço na esquerda do cursor
		   x-=11;								//Volta o cursos para esquerda
	   }else if(y>20){							//Caso o cursor esteja na esquerda verifica se tem espaço na linha de cima
		   x=230;								//Vai ao final na linha
		   y-=20;}								//na linha superior
	   LCD_DrawFullRect(x, y, 11, 20, RGB_COL_WHITE); //Apaga um caractere
	  break;

   case 3:		 						//Função tab

   break;

   case 4:		 						//Função enter
	   x=10;									//Vai ao começo da linha
	   if(y<280)								//Verifica se tem espaço em baixo do cursor
	   y+=20;									//Desce uma linha
   break;

   case 5:       						//Seta esqerda
	   if(x>11)									//Verifica se tem espaço para deslocamento
	   x-=11;									//move cursor
   break;
   case 6:		 						//Seta cima
	   if(y>20)									//Verifica se tem espaço para deslocamento
	   y-=20;									//move cursor
   break;
   case 7:								//Seta baixo
	   if(y<280)								//Verifica se tem espaço para deslocamento
	   y+=20;									//move cursor
   break;
   case 8:		 						//Seta direita
	   if(x<229)								//Verifica se tem espaço para deslocamento
	   x+=11;									//move cursor
   break;
   }


   if(x>230){        		//Verifica se é o último caractere da linha?
	   if(y<290){      		//Verifica se é antes da última linha?
          x=10;	y+=20;}     // Se for, volta pro começo, na próxima linha
	   else x-=11;}  		//Se for último caractere da última linha, apenas volta o espaço de um caractere

   LCD_DrawLine(x,y, 20, LCD_DIR_VERTICAL, aktColor);		// Desenha cursor de texto



     aux.x=x;
     aux.y=y;


 return(aux);

}