//**************************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); }