COUNT()函数使用时数据溢出-->COUNT_BIG

本文介绍了COUNT_BIG函数的使用方法及其与COUNT函数的主要区别。COUNT_BIG总是返回bigint类型的值,适用于统计超过21.5亿的数据量,而COUNT返回int类型的值。COUNT_BIG(*)返回表中所有行的数量,包括NULL值。

COUNT_BIG

本文属于网上资料收集:

  • COUNT()函数使用时数据溢出是因为超出了其存储范围

介绍

————————————

COUNT_BIG 的使用与 COUNT 函数相似。
它们之间的唯一差别是它们的返回值:

  • COUNT_BIG 总是返回 bigint 数据类型值
  • 而 COUNT 则总是返回 int 数据类型值

语法

COUNT_BIG ( { [ ALL | DISTINCT ] expression } | * )

参数

  • ALL

对所有的值进行聚合函数运算。ALL 是默认设置。

  • DISTINCT

指定 COUNT_BIG 返回唯一非空值的数量。

  • expression

一个表达式,其类型是除 uniqueidentifiertextimagentext 之外的任何类型。不允许使用聚合函数和子查询。

注意:
[expression][1]指定应该计算所有行以返回表中行的总数。
COUNT_BIG(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。
COUNT(*) 函数不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。
COUNT_BIG(*) 返回指定表中行的数量而不消除副本。它对每行分别进行计数,包括含有空值的行。

  • 返回值类型

bigint

  • 注释

COUNT_BIG(*) 返回组中项目的数量,这些项目包括 NULL 值和副本。
COUNT_BIG(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。
COUNT_BIG(DISTINCT expression) 对组中的每一行都计算 expression 并返回唯一非空值的数量。


扩展

使用整数数据的精确数字数据类型。

  • bigint

从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。

  • int

从 -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647) 的整型数据(所有数字)。存储大小为 4 个字节。int 的 SQL-92 同义字为 integer。

  • smallint

从 -2^15 (-32,768) 到 2^15 - 1 (32,767) 的整型数据。存储大小为 2 个字节。

  • tinyint

从 0 到 255 的整型数据。存储大小为 1 字节。

如上述整形取值范围,当统计条数超过21.5亿时,应使用COUNT_BIG()

文件str.h内容 #include <stdlib.h> #include <string.h> #include <stdio.h> char *mystrstr(const char *s1,const char *s2,int len1,int len2);//s1= source, s2= template len1= strlen(s1); char* mystrchr(char *s, char c,int len); int mystrncmp(const char *s1,const char *s2,int n);//,int d); 文件str.c内容 #include "str.h" /* void main() { char *s1="hello world,\0 hello you,\0 hello me\0, hello her"; char *s2="her"; char *temp=mystrstr(s1,s2,strlen(s1),strlen(s2)); printf("%s\n",temp); }*/ char *mystrstr(const char *s1,const char *s2,int len1,int len2)//return point on success, 0 on fail. //s1= source, s2= template len1= strlen(s1) { char *p=(char*)s1; //const size_tlen=strlen(s2); for(;(p=mystrchr(p,s2[0],len1))!=NULL;p++) { if(mystrncmp(p,s2,len2)==0) return (char*)p; } return(0); } char* mystrchr(char *s, char c,int len)// return 0 for fail, pointer on success { while(len!=0 && *s != c) { ++s; --len; } return *s==c ? s : NULL; } int mystrncmp(const char *s1,const char *s2,int n)//,int d)// return 0 if eqal, -1 for less , 1 for more { int i; for(i=0;i<n;i++)//字符串前面部分都相同 { if(s1[i]>s2[i]) { return 1; } else { if(s1[i]<s2[i]) return -1; else continue; } /*if(d==1) { printf("%c==%c\n",s1[0],s2[0]); return 0; }*/ /* if(*s1-*s2>0) return 1; if(*s1-*s2<0) return -1; //s1++; //s2++; */ } return 0; } 文件func.h内容 #include <sys/types.h> #include <stdlib.h> #include <dirent.h> int is_dir_exist(const char * dir_path); 文件func.c内容 #include "func.h" int is_dir_exist(const char * dir_path) { if(dir_path==NULL) return 0; if(opendir(dir_path)==NULL) return 0; return 1; } 文件bin.h内容 #include <stdio.h> #include <stdlib.h> //#include <unistd.h> #include<stdlib.h> #include "str.h" #include <time.h> #define FILE_HEADER_SIZE 11 const char FILE_HEADER[]={0x17,0xfa,0xae,0x4e,0x0b,0x09,0x65,0x6e,0x76,0x00,0xa}; #define RECORD_HEAD_SIZE 5//09+tag+00+09 #define RECORD_TAG_SIZE 14//GL-C001+0x00+09+fmt+00+04 #define RECORD_TAG_OK_SIZE 9//OK+0x00+09+fmt+00+04 #define RECORD_FMT_SIZE 7//'C'+09+typ+00+09 #define RECORD_MIN_SIZE 60 #define RECORD_DAT_SIZE 6//00+09+dat+00 //#define RECORD_TYP_SIZE 6//GL-C001+0x00 //const char RECORD_HEADER[]={0x06,0x59,0xc1,0x05,0x29,/*0x04,*/0x03,0x00}; const char RECORD_HEADER[]={0x74,0x61,0x67,0x00,0x09};//0x09- const char END_R_A_LINE[]={0x00,0x00}; const char GLC[]="KV-C58B"; const char WA[]="KA-C902"; const char WAM[]="KV-C204"; const char LOT[]="KM-C102"; const char IMAGE[]="KI-E103"; const char FMT_A_HEADER[]="\v\t"; //int fseek(FILE *stream, long offset, int fromwhere);函数设置文件指针stream的位置。 #define BODY_BUFF_SIZE 1024*1024*512 #define HEAD_BUFF_SIZE 256 #define STRING 0x09 //HT #define INT 0x06 //ACK #define SHORT 0x05 //ENQ #define LFB 0x0b // VT #define CRA 0x0a //LF #define TIME 0x06 //ACK #define DOUBLE 0x08 //BS #define FLOAT 0x07 //?? #define CHAR 0x04 //EOT #define ZERO 0x02 //STX #define ONE 0x03 //ETX #define N0 0x00 //NUT //#define DEBUG //#define LOG #ifdef DEBUG #define printd(format, arg...) \ printf(format, ## arg) #else #define printd(format, arg...) #endif #ifdef LOG #define printl(format, arg...) \ printf(format, ## arg) #else #define printl(format, arg...) #endif typedef struct record_WAM { int wafer_no; int chuck_id; unsigned int max_nr_of_x_gridlines; unsigned int max_nr_of_wams; unsigned int nr_of_wams; double x_gridline_offsets[9]; struct wam_shot *shots; struct record_WAM * next; }record_WAM; typedef struct wam_node { double z; int valid; }wam_node; // wam->next -->wam --> next -->wam (wafer_no, chuck id,etc) :wafer 1 --> wafer 2 ... wafer 25 // | // shots-->next-->wam_shot // | // wam_shot(sid, cx,cy, x grid, y grid,etc) : shot1 --> shot2 ... shot106 ... // | // nodes (z, valid) // | // wam_node[(xgrid+1) * (ygrid+1)] : shot1 --> shot2 ... shot106 ... typedef struct wam_shot { unsigned int id; wam_node * nodes; struct wam_shot * next; double cx,cy; double x_gridlines_shift; unsigned int nr_of_x_gridlines; unsigned int nr_of_y_gridlines; double x_gridline_offsets[9]; double y_gridline_offsets[70]; }wam_shot; typedef struct record_tag { char tag[10]; int count; char typ[128]; struct record_tag *next; }record_tag; typedef struct record_head { char *head; char *tag; char fmt; char *typ; int typ_len; int size; struct record_head *next; } record_header; void free_wam(void); 文件bin.c内容 //查到C语言中fread的定义:size_t fread( void* buffer, size_t size,size_t count, FILE* stream ); #include "bin.h" #include "func.h" char *filename=NULL; FILE *fp=NULL; record_header * record_set_head=NULL; record_tag * tag_set_head=NULL; record_WAM * wam_set_head=NULL; char head_buff[HEAD_BUFF_SIZE]; char body_buff[BODY_BUFF_SIZE]; int open_mdl_file(char * filename) { fp=fopen(filename,"rb"); printf("mdl_file=%s!\n",filename); return fp!=NULL; } int close_mdl_file() { if(fp==NULL) { printf("No file opened, nothing to close!\n"); return 0; } else { fclose(fp); printf("MDL file has been closed!\n"); fp=NULL; return 1; } } int read_file_header() { int i; int len; if(fp) { if(0==(len=fread(head_buff,sizeof(char),FILE_HEADER_SIZE,fp))||len!=FILE_HEADER_SIZE) { printf("Read header buffer failed!\n"); return 0; } else { if(0==mystrncmp(head_buff,FILE_HEADER,FILE_HEADER_SIZE)) { printf("good header\n"); return 1; } else { printf("bad header\n"); return 0; } } } else { printf("no file opened!\n"); return 0; } } int parse_record(record_header *p) { //p->head = temp; int found=0; p->tag = p->head + RECORD_HEAD_SIZE; if(strcmp(p->tag,"OK")==0) { p->fmt = *(p->tag + RECORD_TAG_OK_SIZE); p->typ = p->tag + RECORD_TAG_OK_SIZE + RECORD_FMT_SIZE; } else { p->fmt = *(p->tag + RECORD_TAG_SIZE); p->typ = p->tag + RECORD_TAG_SIZE + RECORD_FMT_SIZE; } p->typ_len=strlen(p->typ); record_tag * tp=tag_set_head; if(tag_set_head==NULL)//not found a matched tag { tag_set_head=malloc(sizeof(record_tag)); tp=tag_set_head; strcpy(tp->tag,p->tag); //printf("len= %d\n",strlen(p->typ)); strncpy(tp->typ,p->typ,128); tp->count=1; tp->next=NULL; //printf("tag-typ %s\n",tp->typ); } else { while(tp->next!=NULL) { if(strncmp(p->tag,tp->tag,strlen(p->tag))==0)//match a exsiting tag { tp->count++; found=1; //printf("-------%s,%s---------\n",p->tag,tp->tag); break; } else { tp=tp->next; } } if((tp->next==NULL)&&strncmp(p->tag,tp->tag,strlen(p->tag))==0) { tp->count++; found=1; } if(found==0)//not found a matched tag { tp->next=malloc(sizeof(record_tag)); tp=tp->next; strcpy(tp->tag,p->tag); //printf("len= %d\n",strlen(p->typ)); strncpy(tp->typ,p->typ,128); tp->count=1; tp->next=NULL; //printf("tag-typ %s\n",tp->typ); } } return 0; } void dump_M_record(record_header *p) { char *buff=NULL; int is_a_time=0; double d; float f; short int s; int us; char *cd; int depth=0; time_t t; buff=p->typ + p->typ_len + RECORD_DAT_SIZE; depth=0; printf("\n%s\t",p->tag);// print tag before a record. int e=0; while(buff <= p->head+ p->size)// within the range of record size { printl("[e=%d,type=%x]",e,buff[0]); e++; switch(buff[0]) { case STRING://string, 0x09+string+NULL//HT buff++; if(strncmp(buff,"line",4)==0)//end of line. { printf("\n"); printf("%s\t**",p->tag);// print tag before each line. } else { printf(" %s ",buff); } if((strlen(buff))==1&&(strncmp(buff,"s",1)==0)) { is_a_time=1; } else { is_a_time=0; } buff+=strlen(buff)+1; //printf("%x",buff[0]); break; case DOUBLE://double , 0x08 + double 8 bit, Bigendian//BS //printf("%x,%x,%x,%x,%x,%x,%x,%x,%x\n",buff[0],buff[1],buff[2],buff[3],buff[4],buff[5],buff[6],buff[7],buff[8]); cd=(char*)&d; cd[0]=buff[8];cd[1]=buff[7];cd[2]=buff[6];cd[3]=buff[5]; cd[4]=buff[4];cd[5]=buff[3];cd[6]=buff[2];cd[7]=buff[1]; buff++; printf(" %g ",d); buff+=sizeof(double); //printf("after a float : %x\n",buff[0]); break; case FLOAT://double , 0x08 + double 8 bit, Bigendian//BS //printf("%x,%x,%x,%x,%x,%x,%x,%x,%x\n",buff[0],buff[1],buff[2],buff[3],buff[4],buff[5],buff[6],buff[7],buff[8]); cd=(char*)&f; cd[0]=buff[4];cd[1]=buff[3];cd[2]=buff[2];cd[3]=buff[1]; buff++; printf(" %g ",f); //#printf("FFFFFFFFFFFFFFFFFFFFFFFFF"); buff+=sizeof(float); break; //printf("after a float : %x\n",buff[0]); case ZERO://Char, just a zero buff++; printf(" %d ",0); //buff+=1; break; case ONE://Char, just a one buff++; printf(" %d ",1); //buff+=1; break; case CHAR://Char, 0x04+'C'+No NULL//EOT buff++; printf(" %d ",(unsigned char)buff[0]); buff+=1; break; case SHORT://Short int, 0x05 + short int (2 byte) + NO NULL//ENQ buff++; cd=(char*)&s; cd[0]=buff[1];cd[1]=buff[0]; printf(" %d ",s); buff+=2; break; case INT://Short int or ctime , 0x06 + int (4 byte) + NO NULL//ENQ buff++; if(is_a_time==1) { cd=(char*)&t; cd[0]=buff[3];cd[1]=buff[2];cd[2]=buff[1];cd[3]=buff[0]; printf(" %s ",ctime(&t)); } else { cd=(char*)&us; cd[0]=buff[3];cd[1]=buff[2];cd[2]=buff[1];cd[3]=buff[0]; printf(" %d ",us); } buff+=4; break; case CRA: case LFB:// End of line or end of sub line.//VT //printf("==>single 0b found at %d==>\n",buff-(p->head)); printf("\n"); printf("%s\t",p->tag); /* if(depth==0) { printf("{ "); } else printf("<");*/ depth++; buff++; //printf("depth=%d",depth); break; case N0:// End of line or end of sub line.//NULL buff++; depth--; if(depth<0) { buff = p->head + p->size+1; //printf("\n"); //printf("%s\t",p->tag); //printf("}\n"); } else { printf(" ");} //printf(">"); break; default: printf("unknown=%x ",(unsigned char)buff[0]); buff++; printf("reading failed on file: %s\n",filename); exit(0); //getch(); break; } } //p->body=t; } int handle_defined_record(record_header *p) { return 0; } int handle_LOT_record(record_header *p,char *xmlstr) { char * buff=NULL; char * end; char *cd; char temp[128]; //sprintf(xmlstr,"<lot_info>" int i; //char csv_file[128]; //char layout_file[]="..\\output\\wafer_layout.xml"; double d; unsigned int ui; buff=p->typ + p->typ_len + RECORD_DAT_SIZE; end=buff+(p->size); if(strncmp(LOT,p->tag,strlen(LOT))==0) { //printf("inside a %s\n",p->tag); sprintf(xmlstr,"<lot_info MDL_name=\"%s\" ",filename); buff+=next_value(buff,STRING,temp,end); while(strncmp(temp,"lot_id",strlen("lot_id"))!=0) { buff+=next_value(buff,STRING,temp,end); } buff+=next_value(buff,STRING,temp,end); sprintf(xmlstr,"%s lot_id=\"%s\" ",xmlstr,temp); buff+=next_value(buff,STRING,temp,end);//recipe id while(strncmp(temp,"recipe_id",strlen("recipe_id"))!=0) { buff+=next_value(buff,STRING,temp,end); } buff+=next_value(buff,STRING,temp,end); sprintf(xmlstr,"%s recipe_id=\"%s\" ",xmlstr,temp); buff+=next_value(buff,STRING,temp,end);//layer id while(strncmp(temp,"layer_id",strlen("layer_id"))!=0) { buff+=next_value(buff,STRING,temp,end); } buff+=next_value(buff,STRING,temp,end); sprintf(xmlstr,"%s layer_id=\"%s\" ",xmlstr,temp); while(strncmp(temp,"lot_size",strlen("lot_size"))!=0) { buff+=next_value(buff,STRING,temp,end); } if(buff[0]==ONE) { ui=1; } else { buff+=next_value(buff,CHAR,&ui,end);//layer id } printl("lot_size=%d",ui); sprintf(xmlstr,"%s lot_size=\"%d\"> </lot_info> ",xmlstr,ui); printd("lot xml=%s\n",xmlstr); return 1; } return 0; } int handle_IMAGE_record(record_header *p,char *xmlstr)// every WAM record is a single wafer. { char * buff=NULL; char * end; char *cd; char temp[128]; int i; int l; //char csv_file[128]; //char layout_file[]="..\\output\\wafer_layout.xml"; double d; float f; unsigned int ui; double w,h; buff=p->typ + p->typ_len + RECORD_DAT_SIZE; end=buff+(p->size); if(strncmp(IMAGE,p->tag,strlen(IMAGE))==0) { for(i=0;i<1;i++) { buff+=next_value(buff,STRING,temp,end); while(strncmp(temp,"image_size",strlen("image_size"))!=0) { l=next_value(buff,STRING,temp,end); if(l==-1)//end of record reached { printf("end of record before next\n"); break; } else { buff+=l; } } buff+=next_value(buff,DOUBLE,&d,end); w=d; buff+=next_value(buff,DOUBLE,&d,end); h=d; printf("w=%g,h=%g\n",w,h); if(w>0.00001) break; } sprintf(xmlstr,"<image_size w=\"%g\" h=\"%g\"> </image_size>\n",w,h); printd("image xml=%s",xmlstr); return 1; } return 0; } int handle_WAM_record(record_header *p,char *xmlstr)// every WAM record is a single wafer. { char * buff=NULL; char * end; char *cd; char temp[128]; //char csv_file[128]; //char layout_file[]="..\\output\\wafer_layout.xml"; double d; float f; unsigned int ui; wam_shot *shot_p=NULL; static record_WAM * wam=NULL; int i; static int wafer_no=0; //static FILE *flp=NULL; buff=p->typ + p->typ_len + RECORD_DAT_SIZE; end=buff+(p->size); if(strncmp(WAM,p->tag,strlen(WAM))==0) { buff+=next_value(buff,STRING,temp,end); printl("1st string= %s\n",temp); if(strncmp(temp,"Wafer Map is empty.",strlen("Wafer Map is empty."))==0) { printf("Wafer Map is empty. --> wafer =%d\n",wafer_no+1); return 0; } wafer_no++; printf("wafer no= %d\n",wafer_no); if(wam_set_head==NULL)//1st wafer and wam_set_head ==NULL { wam=malloc(sizeof(record_WAM)); // now the head point to the new element. wam_set_head=wam; wam->next=NULL; wam->shots=NULL; } else { wam->next=malloc(sizeof(record_WAM)); wam=wam->next; wam->next=NULL; wam->shots=NULL; } wam->wafer_no=wafer_no; //FILE *fp = NULL; //sprintf(csv_file,"..\\output\\wafer_%d.csv",wafer_no); //if((fp = fopen(csv_file, "wt+"))==NULL) //{ // printf("csv file create failed!\n"); // return 0; //} //wam->shots->nodes=NULL; while(strncmp(temp,"CHUCK_ID_",strlen("CHUCK_ID_"))!=0) { buff+=next_value(buff,STRING,temp,end); printl("%s\n",temp); } wam->chuck_id=temp[strlen("CHUCK_ID_")]-'0'; printd("-chuck_id==%d---",wam->chuck_id); buff+=next_value(buff,CHAR,&wam->max_nr_of_x_gridlines,end); printd("max_x = %d\n",wam->max_nr_of_x_gridlines); buff+=next_value(buff,STRING,temp,end); if(buff[0]==SHORT) buff+=next_value(buff,SHORT,&wam->max_nr_of_wams,end); else buff+=next_value(buff,CHAR,&wam->max_nr_of_wams,end); printd("max_wam = %d\n",wam->max_nr_of_wams); buff+=next_value(buff,STRING,temp,end); if(buff[0]==SHORT) buff+=next_value(buff,SHORT,&wam->nr_of_wams,end); else buff+=next_value(buff,CHAR,&wam->nr_of_wams,end); printd("nr_wam = %d\n",wam->nr_of_wams); //getch(); for(i=0;i<wam->max_nr_of_x_gridlines;i++) { buff+=next_value(buff,FLOAT,&f,end); printl("x[%d]=%g\n",i,f); wam->x_gridline_offsets[i]=f; } buff+=next_value(buff,STRING,temp,end);//"for wam printl("wams!!\n"); for(i=0;i<wam->nr_of_wams;i++) { // Todo: error here!! while(1) { buff+=next_value(buff,STRING,temp,end); printd("searching for id %s\n",temp); if(strncmp(temp,"id",strlen("id"))==0) { break; } } printd("a sid was found!, current count =%d, total shot count =%d \n",i+1,wam->nr_of_wams);//SID can be a Char or INT (if > 128) if(wam->shots==NULL)//1st shot { wam->shots=malloc(sizeof(wam_shot)); wam->shots->next=NULL; shot_p=wam->shots; } else { shot_p->next=malloc(sizeof(wam_shot)); shot_p=shot_p->next; shot_p->next=NULL; } shot_p->nodes=NULL; if(buff[0]==CHAR) { printd("looking a sid with char\n"); buff+=next_value(buff,CHAR,&shot_p->id,end); } else{ if(buff[0]==SHORT) { printd("looking a sid with short\n"); buff+=next_value(buff,SHORT,&shot_p->id,end); } else { if(buff[0]==ONE)//0x03 { buff++; shot_p->id=1; } else { printf("error!buff[0]=%x\n",buff[0]); //getch(); } } } buff+=next_value(buff,DOUBLE,&d,end); shot_p->cx=d; buff+=next_value(buff,DOUBLE,&d,end); shot_p->cy=d; printd("%d,%g,%g\n",shot_p->id,shot_p->cx,shot_p->cy); buff+=next_value(buff,FLOAT,&f,end); shot_p->x_gridlines_shift=f; buff+=next_value(buff,STRING,temp,end);//nr_of_x_gridlines printd("nr_of_x_gridlines = %s\n",temp); if(buff[0]==ONE) { shot_p->nr_of_x_gridlines=1; buff++; } else { buff+=next_value(buff,CHAR,&shot_p->nr_of_x_gridlines,end); } buff+=next_value(buff,STRING,temp,end);//nr_of_x_gridlines printd("nr_of_y_gridlines = %s\n",temp); if(buff[0]==ONE) { shot_p->nr_of_y_gridlines=1; buff++; } else { buff+=next_value(buff,CHAR,&shot_p->nr_of_y_gridlines,end); } printd("X=%d,y=%d\n",shot_p->nr_of_x_gridlines,shot_p->nr_of_y_gridlines); int j; for(j=0;j<shot_p->nr_of_x_gridlines;j++) { buff+=next_value(buff,FLOAT,&f,end); shot_p->x_gridline_offsets[j]=f; printl("x_grid[%d]=%g\n",j,f); } for(j=0;j<shot_p->nr_of_y_gridlines;j++) { buff+=next_value(buff,FLOAT,&f,end); shot_p->y_gridline_offsets[j]=f; printl("y_grid[%d]=%g\n",j,f); } //input data table int x,y; shot_p->nodes=malloc(sizeof(wam_node)*(shot_p->nr_of_x_gridlines+1)*(shot_p->nr_of_y_gridlines+1)); for(y=0;y<shot_p->nr_of_y_gridlines;y++) { buff+=next_value(buff,STRING,temp,end);//columns for(x=0;x<shot_p->nr_of_x_gridlines;x++) { buff+=next_value(buff,FLOAT,&f,end); shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].z=f; printl("%d,%g,%g,%g\n",shot_p->id,\ shot_p->cx+shot_p->x_gridline_offsets[x]+shot_p->x_gridlines_shift,\ shot_p->cy+shot_p->y_gridline_offsets[y],\ f); } } //input valid table buff+=next_value(buff,STRING,temp,end);//valid for(y=0;y<shot_p->nr_of_y_gridlines;y++) { buff+=next_value(buff,STRING,temp,end);//columns for(x=0;x<shot_p->nr_of_x_gridlines;x++) { while(1) { buff+=next_value(buff,STRING,temp,end); //column printl("col=%s\n",temp); if(strncmp(temp,"FALSE",strlen("FALSE"))==0) { shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].valid=0; break; } if(strncmp(temp,"TRUE",strlen("TRUE"))==0) { shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].valid=1; break; } } if(shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].valid==1) { /*fprintf(fp,"%d,%g,%g,%g\n",shot_p->id,\ shot_p->cx+shot_p->x_gridline_offsets[x]+shot_p->x_gridlines_shift,\ shot_p->cy+shot_p->y_gridline_offsets[y],\ shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].z);*/ printl("%d,%g,%g,%g\n",shot_p->id,\ shot_p->cx+shot_p->x_gridline_offsets[x]+shot_p->x_gridlines_shift,\ shot_p->cy+shot_p->y_gridline_offsets[y],\ shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].z); } } } printd("just finished matrix read!shot_p->id =%d \n",shot_p->id); }/* if(wafer_no==1){//write file header only 1st wafer and one single time //sprintf(layout_file,"..\\output\\wafer_layout_%d.xml",wafer_no); if((flp = fopen(layout_file, "wt+"))==NULL) { printf("layout xml file create failed!\n"); return 0; } fprintf(flp,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); fprintf(flp,"<layout><wams>\n");//need </wams> </layout> //write wafer layout information to layout.csv files. } else// other wafer open just for append and no file header again. { if((flp = fopen(layout_file, "a"))==NULL) { printf("layout xml file reopen failed!\n"); return 0; } } */ //fprintf(flp,"%d,%d,%d\n",wam-,wam->chuck_id,wam->nr_of_wams); //free all wam,shot,nodes tree structure. /*while(wam->shots) { //struct wam_node *node_p=NULL; shot_p=wam->shots; if(wafer_no==1){//print only on 1st wafer //each line a single wam. fprintf(flp,\ "<wam \ id=\"%d\"\ cx=\"%g\" \ cy=\"%g\" \ nr_x_grid=\"%d\" \ nr_y_grid=\"%d\"> \ </wam>\n",shot_p->id,shot_p->cx,shot_p->cy,shot_p->nr_of_x_gridlines,shot_p->nr_of_y_gridlines); } wam->shots=wam->shots->next; if(shot_p->nodes) {free(shot_p->nodes);} free(shot_p); }*/ //print for every wafers //end wams here /*fprintf(flp,"</wams>\n <wafers> \ <wafer wafer_no=\"%d\" \ chuck_id=\"%d\"\ nr_of_wams=\"%d\"> \ </wafer>\n" ,wafer_no,wam->chuck_id,wam->nr_of_wams);//need </wafers> and </layout> fclose(flp); free(wam); fclose(fp); printd("wam freed and file closed!\n");*/ return 1; } else { return 0;//not handled } } int next_value(char *buff,int type,void *p,char * end) { char *cd; char * start=buff; int e; while(buff <= end)// within the range of record size { printl("[e=%d,type=%x]",e,buff[0]); e++; printl("looking for a %d\n",type); switch(buff[0]) { case STRING://string, 0x09+string+NULL//HT buff++; if(type==STRING) { strncpy(p,buff,128); //printf("%s\n",buff); buff+=strlen(buff)+1; return buff-start; } else { printd("looking for a %d, skip a STRING, buff=%s\n",type, buff); buff+=strlen(buff)+1; } break; case DOUBLE://double , 0x08 + double 8 byte, Bigendian//BS //printf("%x,%x,%x,%x,%x,%x,%x,%x,%x\n",buff[0],buff[1],buff[2],buff[3],buff[4],buff[5],buff[6],buff[7],buff[8]); if(type==DOUBLE) { cd=(char*)p; cd[0]=buff[8];cd[1]=buff[7];cd[2]=buff[6];cd[3]=buff[5]; cd[4]=buff[4];cd[5]=buff[3];cd[6]=buff[2];cd[7]=buff[1]; buff+=sizeof(double)+1; return buff-start; } else { printd("looking for a %d , skip a DOUBLE, buff=%x\n",type,buff[0]); buff+=sizeof(double)+1; } break; case FLOAT://float 0x07 like a double, but 4 bytes. if(type==FLOAT) { cd=(char*)p; cd[0]=buff[4];cd[1]=buff[3];cd[2]=buff[2];cd[3]=buff[1]; buff+=sizeof(float)+1; return buff-start; } else { printd("looking for a %d , skip a FLOAT, buff=%x\n",type,buff[0]); buff+=sizeof(float)+1; exit(1); } break; case ZERO://Char, 0x04+'C'+No NULL//STX printd("skip a ZERO, buff=%x\n",buff[0]); buff++; //printf(" %d ",0); //buff+=1; break; case ONE://Char, 0x04+'C'+No NULL//ETX printd("skip a ONE, buff=%x\n",buff[0]); buff++; //printf(" %d ",1); //buff+=1; break; case CHAR://Char, 0x04+'C'+No NULL//EOT buff++; //printf(" %d ",(unsigned char)buff[0]); if(type==CHAR) { *(unsigned int*)p=(unsigned int)buff[0]; buff++; return buff-start; } else { printd("skip a CHAR, buff=%x\n",buff[0]); buff++; } break; case SHORT://Short int, 0x05 + short int (2 byte) + NO NULL//ENQ buff++; if(type==SHORT) { cd=(char*)p; cd[0]=buff[1];cd[1]=buff[0]; //printf(" %d ",s); buff+=2; return buff-start; } else { printd("skip a SHORT, buff=%x\n",buff[0]); buff+=2; } break; case INT://Short int, 0x05 + short int (2 byte) + NO NULL//ENQ buff++; if(type==INT) { cd=(char*)p; cd[0]=buff[3];cd[1]=buff[2];cd[2]=buff[1];cd[3]=buff[0]; buff+=4; return buff-start; //printf(" %d ",us); } else { printd("skip a INT, buff=%x\n",buff[0]); buff+=4; } break; case CRA: case LFB:// End of line or end of sub line.//VT //printf("skip a CRLF, buff=%x\n",buff[0]); buff++; break; case N0:// End of line or end of sub line.//NULL //printf("skip a N0 , buff=%x\n",buff[0]); buff++; break; default: printf("unknown=%x ",(unsigned char)buff[0]); //getch(); buff++; printf("next_value failed on file: %s\n",filename); exit(0); break; } } return -1;//-1 means on finding within range OR wrong type requested. //p->body=t; } int get_wafer_maps(char * out_folder) { record_header * p=NULL; p=record_set_head;//link to head int find=0; char lot_xml[2048];//should be enough for a lot string. char image_xml[128]; char wafer_info_xml[2048];//[]="../output/wafer_info.xml"; char wafer_csv_file[2048]; FILE *fp_wafer_info = NULL; FILE *fp_wafer_csv=NULL; //printf(tag); if(out_folder[strlen(out_folder)]=='/')//remove ending '/' if exist { out_folder[strlen(out_folder)]='\0'; } sprintf(wafer_info_xml,"%s/wafer_info.xml",out_folder); printd("output to %s\n",out_folder); while(p!=NULL) { //parse_record(p);//parse the basic information of each record //printf("%s-->%s-->%d-->%d\n",tag,p->tag,strlen(tag),strlen(p->tag)); if(strncmp(WAM,p->tag,strlen(p->tag))==0) { handle_WAM_record(p,NULL); //continue; } if(strncmp(LOT,p->tag,strlen(p->tag))==0) { printf("%s,%s\n",LOT,p->tag); handle_LOT_record(p,lot_xml); //continue; } if(strncmp(IMAGE,p->tag,strlen(p->tag))==0) { //watch out , maybe there are two IMAGE record handle_IMAGE_record(p,image_xml); //continue; } p=p->next;// check next } //sprintf(csv_file,"..\\output\\wafer_%d.csv",wafer_no); if((fp_wafer_info = fopen(wafer_info_xml, "wt+"))==NULL) { printf("wafer_info_xml file create failed!\n"); return 0; } else { //write xml file header first fprintf(fp_wafer_info,"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); fprintf(fp_wafer_info,"<wafer_info> %s\n %s\n",lot_xml,image_xml); fprintf(fp_wafer_info,"<wams>\n"); record_WAM * wam_p=NULL; wam_p=wam_set_head; wam_shot *shot_p=wam_p->shots; while(shot_p!=NULL) { fprintf(fp_wafer_info,"<wam id=\"%d\" cx=\"%g\" cy=\"%g\" \ nr_of_x_gridlines=\"%d\" nr_of_y_gridlines=\"%d\">\ </wam>\n",\ shot_p->id,\ shot_p->cx,\ shot_p->cy,\ shot_p->nr_of_x_gridlines,\ shot_p->nr_of_y_gridlines); shot_p=shot_p->next; } fprintf(fp_wafer_info,"</wams>\n"); fprintf(fp_wafer_info,"<wafers>\n"); while(wam_p!=NULL) { fprintf(fp_wafer_info,"<wafer wafer_no=\"%d\" chuck_id=\"%d\" nr_of_wams=\"%d\"> </wafer>\n"\ ,wam_p->wafer_no,wam_p->chuck_id,wam_p->nr_of_wams); //sprintf(wafer_csv_file,"../output/wafer_%d.csv",wam_p->wafer_no); sprintf(wafer_csv_file,"%s/wafer_%d.csv",out_folder,wam_p->wafer_no); if((fp_wafer_csv = fopen(wafer_csv_file, "wt+"))==NULL) { printf("wafer_csv file create failed!\n"); return 0; } shot_p=wam_p->shots; int x,y; while(shot_p!=NULL){ for(y=0;y<shot_p->nr_of_y_gridlines;y++) { //buff+=next_value(buff,STRING,temp,end);//columns for(x=0;x<shot_p->nr_of_x_gridlines;x++) { if(shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].valid==1) { fprintf(fp_wafer_csv,"%d,%g,%g,%g\n",shot_p->id,\ shot_p->cx+shot_p->x_gridline_offsets[x]+shot_p->x_gridlines_shift,\ shot_p->cy+shot_p->y_gridline_offsets[y],\ shot_p->nodes[x+shot_p->nr_of_x_gridlines*y].z); } } } shot_p=shot_p->next; } fclose(fp_wafer_csv); wam_p=wam_p->next; } fprintf(fp_wafer_info,"</wafers>\n"); fprintf(fp_wafer_info,"</wafer_info>\n"); fclose(fp_wafer_info); } //wam_shot *shot_p=NULL; free_wam(); return 1 ;// if no find , find =0; } /* typedef struct record_WAM { int wafer_no; int chuck_id; unsigned int max_nr_of_x_gridlines; unsigned int max_nr_of_wams; unsigned int nr_of_wams; double x_gridline_offsets[9]; struct wam_shot *shots; struct record_WAM * next; }record_WAM; */ int read_record(char * tag) { record_header * p=NULL; p=record_set_head;//link to head int find=0; //printf(tag); while(p!=NULL) { //parse_record(p);//parse the basic information of each record //printf("%s-->%s-->%d-->%d\n",tag,p->tag,strlen(tag),strlen(p->tag)); if(strncmp(tag,p->tag,strlen(p->tag))==0) { //printf("%s,%s,%c \n",p->tag,p->typ,p->fmt); if(handle_defined_record(p)==0) { dump_M_record(p); printf("\n++++++++++++++++++end of record+++++++++++++\n"); } //dump_M_record(p); find=1; } p=p->next;// check next } return find;// if no find , find =0; } void list_all_records() { record_tag * tp=NULL; tp=tag_set_head; int i=0; while(tp!=NULL) { printf("%4d\t%s\t%4d\t%s\n",i,tp->tag,tp->count,tp->typ); i++; tp=tp->next;// check next } } void read_all_records() { record_header * p=NULL; p=record_set_head;//link to head while(p!=NULL) { dump_M_record(p); p=p->next; } } int parse_file_body() { char * temp=NULL; int len_of_temp; int i; int len_of_buff; record_header * p=NULL; while((len_of_buff=read_to_buff())!=0) { temp=body_buff; len_of_temp=len_of_buff; printf("read count=%d\n",len_of_temp); //getch(); while(1)//len_of_temp > RECORD_MIN_SIZE) { if((temp=mystrstr(temp,RECORD_HEADER,len_of_temp,RECORD_HEAD_SIZE))!=NULL) { if(record_set_head==NULL)//1st record { if(record_set_head=malloc(sizeof(record_header))) { p=record_set_head; p->head=temp; p->next=NULL; } else { printf("malloc failed on head allocation!\n"); exit(0); } } else { if(p->next=malloc(sizeof(record_header))) { //printf("size of record =%4d\n",temp-(p->head)); p->size=temp -(p->head); //printf("size of current record = %d\n",p->size); p=p->next;//Update New record head p->next=NULL; p->head=temp; } else { printf("malloc failed on leaf allocation!\n"); exit(0); } } temp=temp+RECORD_MIN_SIZE; len_of_temp=len_of_buff-(temp-body_buff); if(len_of_temp <= RECORD_MIN_SIZE) { p->size = len_of_buff - (p->head - body_buff); break; } //printf("len_of_temp=%d\n",len_of_temp); } else//end of the buff { p->size = len_of_buff - (p->head - body_buff); //printf("size of last record = %d\n",p->size); break; } } }// we read each file in a whole p=record_set_head;//link to head while(p!=NULL) { parse_record(p);//parse the basic information of each record p=p->next; } if(feof(fp)) { printf("file end reached!\n"); return 1; } else { printf("read file_body failed!\n"); return 0; } } void free_wam(void) { wam_shot * shot_p=NULL; record_WAM * wam_p=NULL; int w=0,s=0; while(wam_set_head!=NULL) { wam_p=wam_set_head; wam_set_head=wam_set_head->next;//move to next wafer while(wam_p->shots!=NULL)//free every shot and move the pointer to next shot { shot_p=wam_p->shots; wam_p->shots=wam_p->shots->next; if(shot_p->nodes) { free(shot_p->nodes);//free nodes } free(shot_p);//free shots s++; } free(wam_p); w++; //free wafers } if(w>0){ printf("total %d wafers freed\n",w); printf("total %d shots freed\n",s*w);} //printf("wams all freed\n"); } void free_body(void) { record_header * p=NULL; record_tag *tp=NULL; int i=0; while(record_set_head!=NULL) { p=record_set_head; record_set_head=p->next; i++; // if(p->body) /// free(p->body); free(p); } printf("total %d records freed!\n",i); i=0; while(tag_set_head!=NULL) { tp=tag_set_head; tag_set_head=tp->next; i++; // if(p->body) // free(p->body); free(tp); } printf("total %d tags freed!\n",i); } int read_to_buff() { int len=0; if(fp&&!feof(fp)) { if(0==(len=fread(body_buff,1,BODY_BUFF_SIZE,fp))) { printf("Read body buffer failed!\n"); return 0; } else { if(len<sizeof(body_buff)) return len; else return sizeof(body_buff); } } else { printf("no file opened!\n"); return 0; } } void free_all(void) { free_body(); free_wam(); } //MAIN函数调用前面两个方法 int main(int argc, char* argv[]) { char *option=NULL; char buff[256];//for filename gzip cmd int i; if(argc > 2) { filename=argv[1]; if(strncmp(argv[1]+strlen(argv[1])-3,".gz",3)==0) { sprintf(buff,"gzip -d %s",argv[1]); i=system(buff); filename[strlen(argv[1])-3]=0; if(i==0) printf("%s decompressed, press a key to continue!%d\n",filename,i); else { printf("error on gzip\n"); //getch(); return 0;} } open_mdl_file(filename); if(read_file_header()==1) { printf("Read header OK!\n"); parse_file_body(); atexit(free_all); if(argv[2][0]=='-')//-A= all -T==tag -L==list -I==interactive mode { switch(argv[2][1]) { case 'A': read_all_records(); break; case 'T': if(argc==4)// record tag as 4th parameter { printf("read of record %s\n",argv[3]); read_record(argv[3]); } else { printf("missing a tag name!\n"); } break; case 'I': printf("not ready yet,remind Robin!\n"); break; case 'L': printf("========List of records===========\n"); list_all_records(); break; case 'W'://wafer map printf("========Get Wafer map data===========\n"); if(argc==4) { if(is_dir_exist(argv[3]))// record tag as 4th parameter { printf("write csv,xml to %s\n",argv[3]); get_wafer_maps(argv[3]); } else { printf("folder not find, will quit!\n"); } } else { printf("writing to default folder ./!\n"); get_wafer_maps("./"); } break; default: printf("wrong option,%c,select A,T,I,L !\n",argv[2][1]); break; } } else { printf("wrong option,%s,select -A,-T,-I,L !\n",argv[2]); } } else { printf("Read header failed!\n"); return 0; } close_mdl_file(); //free_body(); return 1; } else { printf("usage: read mdl_filename -A==all -T==tag -I==interactive mode -L==list\n "); return 0; } } 帮我检查我这次提供的这些文件中,除了C语言的标准库之外是否有没有被定义的模块。如果有请指出我会继续提供,如果没有那么帮我分析代码的结构和作用
06-10
/*! *\fn bool tpsocket_write(struct tpsocket_fd *sock, struct tpsocket_buf*buf); * *\brief Write a socket buffer to a socket tx buffer queue. * *\param[in] sock The socket to write to, will be freed on failure. *\param[in] buf The socket buffer to be written. * *\return Always true if buffer length is under limit. */ bool tpsocket_write(struct tpsocket_fd *sock, struct tpsocket_buf*buf) { return tpsocket_write_force(sock, buf, false); } /*! *\fn int tpsocket_write_force(struct tpsocket_fd *sock, struct tpsocket_buf*buf, bool force); * *\brief Write a socket buffer to a socket tx buffer queue. * *\param[in] sock The socket to write to, will be freed on failure. *\param[in] buf The socket buffer to be written. *\param[in] force Force the socket buffer to be written. * *\return Always true if buffer length is under limit. */ bool tpsocket_write_force(struct tpsocket_fd *sock, struct tpsocket_buf*buf, bool force) { if (buf) { if (!force && !tpsocket_writable(sock)) { if (!sock->writeDisable) { DEBUG("SOCK %p WRITE BUFFER OVER FLOW! %d > %d\n", sock, sock->write_buf_length , sock->handler.write_buf_max); sock->writeDisable = 1; } tpbuf_free(buf); return false; } else if (tpsocket_writable(sock)) { if (sock->writeDisable) { DEBUG("SOCK %p WRITE BUFFER WRITEABLE! %d < %d\n", sock, sock->write_buf_length , sock->handler.write_buf_max); sock->writeDisable = 0; } } list_add_tail(&buf->list, &sock->write_buf); sock->write_buf_length += tpbuf_data_len(buf); if (sock->fd.fd < 0) { return true; } else if (sock->type & TPSOCKET_TYPE_FILE) { if (!(sock->pending_flag & ULOOP_WRITE)) { sock->pending_flag |= ULOOP_WRITE; tpsocket_timer_set(sock, &sock->poll, 0); } } else { if (!sock->fd.error && !(sock->pending_flag & ULOOP_WRITE)) { if (!(sock->fd.flags & ULOOP_WRITE)) { tpsocket_fd_add(sock, sock->fd.flags | (ULOOP_WRITE)); } } } #ifndef TPSOCKET_SUPPORT_PTHREAD_ULOOP if (sock->sp && sock->thread_write_len < SOCKET_BUF_FINE) { tpsocket_write_cb(sock, SOCKET_BUF_BIG, &sock->thread_write_len); } #endif } return true; }
最新发布
10-21
//#include "LPC177x_8x.h" // Device header #include "includes.h" #define VALUE_VIBRATION 5 typedef struct { float k; // 需要存储 float zero_trace; // 零点追踪 float Loading_coef; // 加载值 float zero_coef; // 零点值 需要存储 float NetWeight_coef; // 去皮标定值 uint16_t wen_flag; // 大于10表示稳定 float weight; // 重量g float weight_Last; // 上次重量g uint32_t weight_show; // 显示重量 uint32_t weight_show_Last; // 显示重量 uint32_t ADC_VALUE_Last; // 上一次AD差分值 uint32_t ADC_VALUE; // 本次AD差分值 uint8_t Symbol; // 符号 1为负,0为正 uint32_t magnification; // 放大倍数 uint8_t coff; // 一级滤波强度 uint8_t Blance_Abnormal; // 传感器异常标志 uint8_t Valve_change; // 电磁阀状态改变 } ADS1232; extern ADS1232 ADS_coef; /* ADS1232 配置增益 #define GainX1 GAIN0_0;GAIN1_0; #define GainX2 GAIN0_1;GAIN1_0; #define GainX64 GAIN0_0;GAIN1_1; 目前使用 #define GainX128 GAIN0_1;GAIN1_1; */ uint16_t trace_s; uint8_t FirstUp; uint32_t liu_wen; uint8_t liu_count; uint8_t big_count; ADS1232 ADS_coef; extern struct COM com4; extern struct BALANCEDATA BaData; INT8U Amountadding[10];//质量变化数组//ly20241104 #define WINDOW_SIZE_MAX 20 #define WINDOW_LEISURE_SIZE 12 #define WINDOW_FILL 4 #define WINDOW_CARDINAL 6 #define ADCa_t 1 #define FIXED_VALUE (214748364.8 / 2 / 5) #define SAMPLE_RATE_HZ 80 // ADC采样率 #define FILTER_CUTOFF_HZ 15 // 滤波器截止频率 #define M_PI 3.14159265358979323846f // 单精度浮点版本 // 平滑窗口结构体定义 typedef struct { uint32_t buffer[WINDOW_SIZE_MAX]; // 窗口数据存储 uint8_t index; // 当前写入位置 uint32_t sum; // 窗口数据总和 uint32_t mean; // 窗口数据取极值平均值 uint32_t window_number; // 窗口个数 uint8_t WINDOW_SIZE; // 采集个数 uint8_t EXCLUDE_NUM; // 去除最大/最小值数量 } SlidingFilter; SlidingFilter SF; SlidingFilter SF_W; // IIR滤波器结构体 typedef struct { float alpha; float prev_output; } IIR_Filter; IIR_Filter weight_filter; // IIR滤波器实例 IIR_Filter fill_filter; // 观测维度定义为1(仅AD测量值) #define OBS_DIM 1 // 状态维度:假设我们估计的是重量值及其变化率(速度) #define STATE_DIM 2 #define WINDOW 10 // 自适应参数结构体 typedef struct { double lambda; // 遗忘因子(0.95~0.99) double rho; // 衰减因子(0.95~0.99) double Q_scale; // Q调整基准值 double R_scale; // R调整基准值 double innov_mean; // 新息均值 double innov_var; // 新息方差 double innov_window[WINDOW]; // 新息窗口 int innov_index; // 窗口索引 // 保存基准噪声值 double R_base; // 初始观测噪声基准值 double Q_pos_base; // 初始位置过程噪声基准值 double Q_vel_base; // 初始速度过程噪声基准值 } AdaptParams; // 强跟踪滤波器结构体 typedef struct { double x[STATE_DIM]; // 状态向量 [位置, 速度] double P[STATE_DIM][STATE_DIM]; // 状态协方差矩阵 double Q[STATE_DIM][STATE_DIM]; // 过程噪声协方差 double R; // 观测噪声协方差 double F[STATE_DIM][STATE_DIM]; // 状态转移矩阵 double H[OBS_DIM][STATE_DIM]; // 观测矩阵 AdaptParams adapt; // 自适应参数 int steady_state; // 稳态标志 (0:动态 1:稳态) uint32_t steady_count; // 稳态计数器 } ASTKF; ASTKF filter; uint32_t uabs_diff(uint32_t value1, uint32_t value2) { return (value1 >= value2) ? (value1 - value2) : (value2 - value1); } /** *一阶滤波算法 *@param new_value 新采样值 *@param old_value 上次滤波结果 *@param cof(一级滤波系数cof / 256) *@return 本次滤波结果 */ uint32_t first_filter(uint32_t new_value, uint32_t old_value, uint8_t cof) { unsigned long temp; if (new_value < old_value) { temp = old_value - new_value; temp = temp * cof / 256; temp = old_value - temp; } else if (new_value > old_value) { temp = new_value - old_value; temp = temp * cof / 256; temp = old_value + temp; } else { temp = old_value; } return temp; } // 高级滑动滤波器 int compare_floats(const void *a, const void *b) { return *(uint32_t *)a > *(uint32_t *)b ? 1 : -1; } float advanced_sliding_filter(SlidingFilter *SF_t) { uint32_t sorted[SF_t->WINDOW_SIZE]; // 排序去极值 memset(sorted, 0, sizeof(sorted)); memcpy(sorted, SF_t->buffer, sizeof(sorted)); qsort(sorted, SF_t->WINDOW_SIZE, sizeof(uint32_t), compare_floats); SF_t->sum = 0; for (int i = SF_t->EXCLUDE_NUM; i < SF_t->WINDOW_SIZE - SF_t->EXCLUDE_NUM; i++) { SF_t->sum += sorted[i]; } SF_t->mean = (SF_t->sum / (SF_t->WINDOW_SIZE - 2 * SF_t->EXCLUDE_NUM)); //SF_t.mean = division_value(SF_t.mean); return SF_t->mean; } // IIR滤波器实现 void IIR_Filter_Init(IIR_Filter *filter, float alpha) { filter->alpha = alpha; filter->prev_output = 0.0f; } float IIR_Filter_Update(IIR_Filter *filter, float input) { // 根据重量变化率动态调整截止频率 if (0 > (ADS_coef.weight * ADS_coef.weight_Last)) { float delta_weight = fabsf(ADS_coef.weight - ADS_coef.weight_Last); float dynamic_cutoff = FILTER_CUTOFF_HZ * (1.0 - fminf(0.7, delta_weight / 100.0)); filter->alpha = 1.0f - expf(-2 * M_PI * dynamic_cutoff / SAMPLE_RATE_HZ); } filter->prev_output = filter->alpha * input + (1.0f - filter->alpha) * filter->prev_output; return filter->prev_output; } // 初始化滤波器 void astkf_init(ASTKF *filter, double init_pos, double init_vel, double q_pos, double q_vel, double r) { int i, j, k; memset(filter, 0, sizeof(ASTKF)); // 初始状态 filter->x[0] = init_pos; filter->x[1] = init_vel; // 状态协方差初始化 for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = 0.0; } } filter->P[0][0] = 0.1; filter->P[1][1] = 0.01; // 过程噪声协方差 Q filter->Q[0][0] = q_pos; filter->Q[1][1] = q_vel; // 观测噪声协方差 R filter->R = r; // 状态转移矩阵 F(假设匀速模型) filter->F[0][0] = 1.0; filter->F[0][1] = 0.05; // dt = 0.05 filter->F[1][0] = 0.0; filter->F[1][1] = 1.0; // 观测矩阵 H filter->H[0][0] = 1.0; filter->H[0][1] = 0.0; // 新增自适应参数初始化 filter->adapt.lambda = 0.97; filter->adapt.rho = 0.98; filter->adapt.Q_scale = 1.0; filter->adapt.R_scale = 1.0; filter->adapt.innov_mean = 0.0; filter->adapt.innov_var = 1.0; filter->adapt.innov_index = 0; for (int i = 0; i < WINDOW; i++) { filter->adapt.innov_window[i] = 0.0; } filter->adapt.R_base = r; filter->adapt.Q_pos_base = q_pos; filter->adapt.Q_vel_base = q_vel; // 设置当前使用的噪声值(初始等于基准值) filter->R = r; filter->Q[0][0] = q_pos; filter->Q[1][1] = q_vel; filter->steady_state = 1; // 初始设为稳态 filter->steady_count = 0; // 稳态计数器清零 } // 预测步骤 void astkf_predict(ASTKF *filter) { int i, j, k; // 临变量 double temp[STATE_DIM] = {0}; double FP[STATE_DIM][STATE_DIM] = {{0}}; double P_new[STATE_DIM][STATE_DIM] = {{0}}; // 状态预测: x = F * x for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { temp[i] += filter->F[i][j] * filter->x[j]; } } // 协方差预测: FP = F * P for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { for (k = 0; k < STATE_DIM; k++) { FP[i][j] += filter->F[i][k] * filter->P[k][j]; } } } // P_new = FP * F^T + Q for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { for (k = 0; k < STATE_DIM; k++) { P_new[i][j] += FP[i][k] * filter->F[j][k]; } P_new[i][j] += filter->Q[i][j]; // 添加过程噪声 } } // 更新状态和协方差 for (i = 0; i < STATE_DIM; i++) { filter->x[i] = temp[i]; for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = P_new[i][j]; } } } // 更新新息统计信息 void update_innovation_statistics(ASTKF *filter, double innovation) { int i; // 更新滑动窗口 filter->adapt.innov_window[filter->adapt.innov_index] = innovation; filter->adapt.innov_index = (filter->adapt.innov_index + 1) % WINDOW; // 计算窗口内的新息均值和方差 double sum = 0.0; double sq_sum = 0.0; int actual_count = 0; for (i = 0; i < WINDOW; i++) { if (filter->adapt.innov_window[i] != 0.0) // 跳过未初始化的值 { sum += filter->adapt.innov_window[i]; sq_sum += filter->adapt.innov_window[i] * filter->adapt.innov_window[i]; actual_count++; } } if (actual_count > 0) { // 使用指数加权平均更新统计量 double mean = sum / actual_count; double var = (sq_sum / actual_count) - (mean * mean); // 应用遗忘因子 filter->adapt.innov_mean = filter->adapt.lambda * filter->adapt.innov_mean + (1 - filter->adapt.lambda) * mean; filter->adapt.innov_var = filter->adapt.lambda * filter->adapt.innov_var + (1 - filter->adapt.lambda) * var; } } // 更新步骤(带自适应强跟踪机制) void astkf_update(ASTKF *filter, double z) { int i, j; // 计算新息(观测残差) double innovation = z - (filter->H[0][0] * filter->x[0] + filter->H[0][1] * filter->x[1]); // 更新新息统计信息 update_innovation_statistics(filter, innovation); double innov_std = sqrt(filter->adapt.innov_var + 1e-6); // ===== 优化后的稳态检测机制 ===== double noise_floor = 15.0; // 根据实际噪声范围设置 double steady_threshold = fmax(noise_floor, innov_std * 0.8); // 稳态检测 if(fabs(innovation) < steady_threshold) { filter->steady_count++; if(filter->steady_count > 8) { // 降低连续稳态计数要求 filter->steady_state = 1; } } else { filter->steady_count = 0; filter->steady_state = 0; } // ===== 优化强跟踪阈值 ===== double beta = 1.0; const double dynamic_thresh = 2.5; // 动态阈值提高到2.5σ const double steady_thresh = 4.0; // 稳态阈值提高到4.0σ double threshold = filter->steady_state ? steady_thresh : dynamic_thresh; // 仅在超过阈值启用强跟踪 if(fabs(innovation) > threshold * innov_std) { beta = fmax(0.3, innov_std * innov_std / (innovation * innovation)); } // ===== 自适应噪声基底管理 ===== static double base_r = 50.0; // 初始基准噪声 // 自动更新噪声基线(只在稳态更新) if(filter->steady_state && filter->steady_count > 20) { base_r = 0.95 * base_r + 0.05 * filter->adapt.innov_var; } // 设置观测噪声R不低于基准值 filter->R = fmax(base_r, filter->adapt.R_base); // ===== 自适应调整Q和R ===== // 1. 仅在动态状态下调整Q if(!filter->steady_state) { double innovation_ratio = fabs(innovation) / (innov_std + 1e-6); // 新息异常增大:线性增加Q缩放因子 if (innovation_ratio > threshold) { filter->adapt.Q_scale += 0.2 * (innovation_ratio - threshold); filter->adapt.Q_scale = fmin(filter->adapt.Q_scale, 3.0); } else { // 缓慢恢复Q缩放因子(衰减机制) filter->adapt.Q_scale *= filter->adapt.rho; filter->adapt.Q_scale = fmax(filter->adapt.Q_scale, 1.0); } // 应用Q调整 filter->Q[0][0] = filter->adapt.Q_scale * filter->adapt.Q_pos_base; filter->Q[1][1] = filter->adapt.Q_scale * filter->adapt.Q_vel_base; } // 计算新息协方差 S = H * P * H^T + R double S = 0.0; for (i = 0; i < STATE_DIM; i++) { double temp = 0.0; for (j = 0; j < STATE_DIM; j++) { temp += filter->H[0][j] * filter->P[j][i]; } S += temp * filter->H[0][i]; } S += filter->R; /* // // ===== 强跟踪因子 ===== // double beta = 1.0; // const double INNOV_THRESH = 2.0; // 新息异常阈值 // // 根据新息大小调整增益 // double innov_size = fabs(innovation); // double innov_std = sqrt(filter->adapt.innov_var + 1e-6); // 避免除以0 // if (innov_size > INNOV_THRESH * innov_std) // { // beta = innov_std * innov_std / (innovation * innovation); // } // // ===== 自适应调整Q和R ===== // // 1. 根据新息方差调整过程噪声Q // double innovation_ratio = innov_size / (innov_std + 1e-6); // if (innovation_ratio > INNOV_THRESH) // { // // 新息异常增大:线性增加Q缩放因子 // filter->adapt.Q_scale += 0.5 * (innovation_ratio - INNOV_THRESH); // filter->adapt.Q_scale = fmin(filter->adapt.Q_scale, 5.0); // 上限5倍 // } // else // { // // 缓慢恢复Q缩放因子(衰减机制) // filter->adapt.Q_scale *= filter->adapt.rho; // filter->adapt.Q_scale = fmax(filter->adapt.Q_scale, 1.0); // } // // 应用Q调整 // filter->Q[0][0] = filter->adapt.Q_scale * filter->adapt.Q_pos_base; // filter->Q[1][1] = filter->adapt.Q_scale * filter->adapt.Q_vel_base; // // 2. 根据新息序列调整观测噪声R // if (filter->adapt.innov_var > S) // { // // 实际方差 > 理论方差增大R // double r_factor = 1.0 + 0.2 * (filter->adapt.innov_var / S - 1.0); // filter->R = fmin(r_factor * filter->adapt.R_base, 5.0 * filter->adapt.R_base); // } // else // { // // 恢复基准R值 // filter->R = filter->adapt.R_base; // }*/ // ===== 卡尔曼滤波更新 ===== // 计算卡尔曼增益 K = P * H^T / S double K[STATE_DIM] = {0}; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { K[i] += filter->P[i][j] * filter->H[0][j]; } K[i] /= S; } // 更新状态 x = x + beta * K * innovation for ( i = 0; i < STATE_DIM; i++) { filter->x[i] += beta * K[i] * innovation; } // 更新协方差 P = (I - beta * K * H) * P double KH[STATE_DIM][STATE_DIM] = {{0}}; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { KH[i][j] = K[i] * filter->H[0][j]; } } double I_minus_betaKH[STATE_DIM][STATE_DIM] = {{0}}; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { I_minus_betaKH[i][j] = (i == j ? 1.0 : 0.0) - beta * KH[i][j]; } } double P_new[STATE_DIM][STATE_DIM] = {{0}}; for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { for (int k = 0; k < STATE_DIM; k++) { P_new[i][j] += I_minus_betaKH[i][k] * filter->P[k][j]; } } } // 保存更新后的协方差 for (i = 0; i < STATE_DIM; i++) { for (j = 0; j < STATE_DIM; j++) { filter->P[i][j] = P_new[i][j]; } } } uint32_t division_value(uint32_t AD) { uint32_t i = 0; i = AD / 25; return i * 25; } uint32_t division_value50(uint32_t AD) { uint32_t i = 0; i = AD / 50; return i * 50; } unsigned long i_us; unsigned long AD_dat = 0x00; /******************************************************************************* 函数:Read_Ads1232() 功能: 从ADS1232芯片中读取24位数据值(3字节) 参数: Calibration 返回: AD_dat *******************************************************************************/ unsigned long read_Ads1232(uint8_t Calibration) // 读取数值,并校准 { unsigned char x = 0; AD_dat = 0x00; ADS_SCLK_L; // SCLK_L while (ADS_DOUT_Read) { i_us++; delay_us(100); if (i_us > 0x1ffff) return 0; } // 等待数据线拉低,表示可以读取数据 for (x = 0; x < 24; x++) // 连续读取24位数据 { AD_dat <<= 1; // 左移 1位 ADS_SCLK_H; // SCLK_H delay_us(10); ADS_SCLK_L; // SCLK_Ladvanced if (ADS_DOUT_Read) // 获取数据口线的值 { AD_dat |= 0x00000001; } else { AD_dat &= 0xfffffffe; } delay_us(10); } if (Calibration) // 增加一个脉冲,芯片校准 { ADS_SCLK_H; // SCLK_H delay_us(10); ADS_SCLK_L; // SCLK_L } return division_value50(AD_dat & 0x00ffffff); // 防止数据溢出 // return (AD_dat&0x00ffffff);//防止数据溢出 } // 将AD值转换为差分电压并放大ADS_coef.precision倍 uint32_t ADtoDiffVolt(uint32_t AD_Data) { return division_value((AD_Data / FIXED_VALUE) * ADS_coef.magnification); } // 将差分电压与零点之差计算重量单位g float DiffVoltTOg(uint32_t DiffVolt) { float NetZero = (ADS_coef.zero_coef + ADS_coef.NetWeight_coef); uint32_t AD_Diff = (DiffVolt >= NetZero) ? (DiffVolt - NetZero) : (NetZero - DiffVolt); if (DiffVolt >= NetZero) { ADS_coef.Symbol = 0x00; //正值 BaData.TotalSymbol = 0x00; BaData.NetSymbol = 0x00; } else { ADS_coef.Symbol = 0x01; //负值 BaData.TotalSymbol = 0x01; BaData.NetSymbol = 0x01; } return ADS_coef.k * AD_Diff; } // 返回值为差分电压放大值 uint32_t Read_Ads1232(uint8_t Calibration) { static uint8_t i = 0; static uint8_t index_last = 0; static uint8_t window_size; uint32_t temp; uint32_t ADTemp; if (Filling.State == FUELING) //加注中 { window_size = WINDOW_FILL; SF.EXCLUDE_NUM = 0; } else { window_size = WINDOW_CARDINAL; SF.EXCLUDE_NUM = 1; } // 更新数据缓冲区 temp = read_Ads1232(Calibration); temp = IIR_Filter_Update(&fill_filter, (float)temp); if (Filling.State != IDLE && SF.buffer[index_last] != 0 && uabs_diff(temp, SF.buffer[index_last]) > ((SF.buffer[index_last] - ADS_coef.zero_coef) / 3))//本次与上一次之差大于上一次与零点之差的1/3 { temp = SF.buffer[index_last]; } if (i == 0) // 第一个先存起来,根据情况赋值 {} else { SF.buffer[SF.index] = first_filter(temp, SF.buffer[index_last], ADS_coef.coff); } if ((SF.buffer[SF.index] >= 0x5FFFFF) || !(temp | 0X00)) // 改为传感器异常?? { ADS_PDWN_L; // PDWN_L delay_us(20); ADS_PDWN_H; // PDWN_H delay_ms(50); // 去电复位 SF.buffer[SF.index] = read_Ads1232(Calibration); if (SF.buffer[SF.index] >= 0x5FFFFF || SF.buffer[SF.index] <= 0X100) // 传感器异常 { ADS_coef.Blance_Abnormal = 1; SetBit((uint8 *)&FillAlarm.STS, 6, 0); // 6-称传感器异常 } } else { ADS_coef.Blance_Abnormal = 0; } if (i == 0) { if (uabs_diff(ADtoDiffVolt(temp), ADS_coef.ADC_VALUE_Last) > (0x200)) // 差分值变化大 { SF.WINDOW_SIZE = window_size; SF.index = 0; SF.buffer[SF.index] = temp; } else { if (WINDOW_FILL == SF.WINDOW_SIZE || 0x00 == SF.buffer[0]) // 从加注中模式切换过来,和第一个 { SF.WINDOW_SIZE = window_size; SF.index = 0; SF.buffer[SF.index] = temp; } else { if (SF.WINDOW_SIZE == window_size) { SF.index = window_size; SF.buffer[window_size] = temp; SF.WINDOW_SIZE = window_size * 2; } else { SF.buffer[SF.index] = temp; SF.EXCLUDE_NUM = 2; } } } } index_last = SF.index; SF.index = (SF.index + 1) % SF.WINDOW_SIZE; if (i >= (window_size - 1) && ADS_coef.k > 0.0f && ADS_coef.k < 1.0f) ADS1232_Processing(Calibration); i = (i + 1) % window_size; if (ADS_coef.k < 0.0f || ADS_coef.k > 1.0f) SetBit((uint8 *)&FillAlarm.STS, 4, 0); // 6-电子秤标定异常 // 预测与更新 astkf_predict(&filter); astkf_update(&filter, (double)ADtoDiffVolt(SF.buffer[index_last])); if (filter.x[0] != 0) return filter.x[0]; else return SF.buffer[index_last]; } // 零点标记 uint8_t zero_calibration() { LPC_GPIOINT->IO2IntEnF &= (~ADS_DOUT);//禁止ADS_DOUT中断 uint8_t i = 0; FillFlag.ZeroBiaoding = 4; // 标记中 ADS_coef.zero_coef = 0x00; for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (ADS_coef.zero_coef == 0x00) { ADS_coef.zero_coef = ADS_coef.ADC_VALUE_Last; } else { ADS_coef.zero_coef = (ADS_coef.zero_coef + ADS_coef.ADC_VALUE_Last) / 2; } } ADS_coef.zero_trace = ADS_coef.zero_coef; if (1 != ADS_coef.Blance_Abnormal) { ADS_coef.NetWeight_coef = 0; //FillPara.ADS1232_zero = ADS_coef.zero_coef; FillFlag.ZeroBiaoding = 2; // 标定成功 Write_ADS1232(); // 保存 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 2; } else { LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 3; } } // 加载标记 uint8_t Loading_calibration(uint32_t loading_value) { uint8_t i = 0; LPC_GPIOINT->IO2IntEnF &= (~ADS_DOUT);//禁止ADS_DOUT中断 for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (ADS_coef.Loading_coef == 0x00) { ADS_coef.Loading_coef = ADS_coef.ADC_VALUE_Last; } else { ADS_coef.Loading_coef = (ADS_coef.Loading_coef + ADS_coef.ADC_VALUE_Last) / 2; } } // 计算k值 ADS_coef.k = ((float)(loading_value * 10) / (ADS_coef.Loading_coef - ADS_coef.zero_coef)); if (ADS_coef.k > 0.0f && ADS_coef.k < 1.0f && 1 != ADS_coef.Blance_Abnormal) { ClrBit((uint8*)&FillAlarm.STS, 4); //FillPara.ADS1232_k = (ADS_coef.k * 1000000000); Write_ADS1232(); // 保存 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 2; // 标定成功 } else { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 return 3; // 标定失败 } } //去皮标定 uint8_t NetWeight_calibration() { uint8_t i = 0; float NetTemp; for (i = 0; i < 90; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); if (NetTemp == 0x00) { NetTemp = ADS_coef.ADC_VALUE_Last; } else { NetTemp = (NetTemp + ADS_coef.ADC_VALUE_Last) / 2; } } ADS_coef.NetWeight_coef = NetTemp - ADS_coef.zero_coef; } void FillingStream() { char Temp, i; INT32U temp1; INT8U TotalOffset; if ((Filling.State == FUELING) && (BaData.TotalSymbol == 0)) //ly20240410 zxl20241210 { //计算加注速率 if (FillFlag.ReadBalanceTimes < 50) { FillFlag.ReadBalanceTimes++; } FillFlag.Readflag = 0; Temp = uabs_diff(Filling.TotalWeight, Filling.OldTotalWeight); //ly20241218 if ((Filling.PotType == FORTY_EIGHTKG) || (Filling.PotType == FIVTYKG)) //ly20250107 { TotalOffset = 80; } else { TotalOffset = 50; } if (Temp > 0) { if ((Temp < TotalOffset) || (FillFlag.Calculateflag == 0) || (FillFlag.ReadBalanceTimes < 30)) //ly20241221 { Amountadding[FillFlag.Index] = Temp; FillFlag.OldAddTotal = Temp; Filling.OldTotalWeight = Filling.TotalWeight; Filling.TotalAbnormalTimes = 0; } else { Filling.TotalAbnormalTimes++;//ly20241221 if (Filling.TotalAbnormalTimes < 4) { Filling.TotalWeight = Filling.OldTotalWeight; //ly20241220 Amountadding[FillFlag.Index] = FillFlag.OldAddTotal; Filling.OldTotalWeight += FillFlag.OldAddTotal; } else { Filling.State = SUSPEND; //保存数据 DCF_OUT_CTRL(DCF_V1, OFF); //关阀 DCF_OUT_CTRL(DCF_V2, OFF); //关阀 ADS_coef.Valve_change = VALUE_VIBRATION; WriteWork_status(SUSPEND); LogDispose("Goto Suspend4 \n", strlen("Goto Suspend4 \n")); show.dislist = 59; Filling.Abnormalstopflag = 1; //ly20240920 Filling.TotalAbnormalTimes = 0; } } } else { Filling.OldTotalWeight = Filling.TotalWeight; Amountadding[FillFlag.Index] = 0x00; } FillFlag.Index++; if (FillFlag.Index >= 10) { FillFlag.Calculateflag = 1; FillFlag.Index = 0; } if (FillFlag.Calculateflag == 1) //ly20241104 { temp1 = 0; for (i = 0; i < 10; i++) { temp1 += Amountadding[i]; } Filling.FillingSpeed = temp1 * 5; //计算流速平均值标识Ng/600ms流速 if (Filling.FillingSpeed > Filling.FillingMaxSpeed) { Filling.FillingMaxSpeed = Filling.FillingSpeed; } if (Filling.FillingSpeed > 350) { Filling.FillingSpeed = Filling.FillingoldSpeed; } else { Filling.FillingoldSpeed = Filling.FillingSpeed; } } if (Filling.State == FUELING) { FuelingOperation(); } } } uint32_t WeightShow_10(float weight) { uint32_t show_value = weight / 10; uint8_t units_digit = (uint32_t)weight % 10; if (0 == show_value && units_digit < 8) { ADS_coef.weight_show = show_value * 10; } else { if (units_digit >= 5) { ADS_coef.weight_show = (show_value + 1) * 10; } else { ADS_coef.weight_show = show_value * 10; } } Filling.TotalWeight = ADS_coef.weight_show / 10; BaData.TotalWeight = ADS_coef.weight_show / 10; BaData.LastData = BaData.TotalWeight; Filling.NetWeight = ADS_coef.weight_show / 10; BaData.NetWeight = ADS_coef.weight_show / 10; FillingStream(); BaData.DataUpdateflag = 1; } uint32_t WeightShow_20(float weight) { uint32_t show_value = weight / 20; uint8_t units_digit = (uint32_t)weight % 20; if (weight > 15 && ADS_coef.wen_flag >= 30 && (fabsf(weight - ADS_coef.weight_show) < 15)) {} else { if (0 == show_value && units_digit < 15) { ADS_coef.weight_show = show_value * 20; } else { if (units_digit >= 10) { ADS_coef.weight_show = (show_value + 1) * 20; } else { ADS_coef.weight_show = show_value * 20; } } } Filling.TotalWeight = ADS_coef.weight_show / 10; BaData.TotalWeight = ADS_coef.weight_show / 10; BaData.LastData = BaData.TotalWeight; Filling.NetWeight = ADS_coef.weight_show / 10; BaData.NetWeight = ADS_coef.weight_show / 10; FillingStream(); BaData.DataUpdateflag = 1; } // 初始化 void ADS1232_init() { uint8_t i = 0; uint32 int32Temp; // 初始化 FirstUp = 1; ADS_coef.magnification = 10000000; ADS_coef.coff = 180; ADS_coef.NetWeight_coef = 0; ADS_coef.Valve_change = 0; ADS_PDWN_L; // PDWN_L delay_us(20); ADS_PDWN_H; // PDWN_H delay_us(40); // 去电复位 // 读取几次,待数据稳定后再读取输出 for (i = 0; i < 12; i++) { ADS_coef.ADC_VALUE_Last = Read_Ads1232(ADCa_t); delay_us(20); } //读取铁电保存值 ReadContinuumeMBRS64A((uint8 *)(&RealTimeData.ADS1232[0]) - & (RealTimeData.Head), (void *)&RealTimeData.ADS1232[0], 12, FillFlag.FmDeviceType); int32Temp = ComputeCRC32((uint32_t *)(&RealTimeData.ADS1232[0]), 2); if (int32Temp != RealTimeData.ADS1232[2]) { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 } else { ADS_coef.zero_coef = RealTimeData.ADS1232[0]; ADS_coef.k = ((float)RealTimeData.ADS1232[1] / 1000000000.0); if (ADS_coef.k > 0.0f && ADS_coef.k < 1.0f) { ClrBit((uint8*)&FillAlarm.STS, 4); } else { SetBit((uint8 *)&FillAlarm.STS, 4, 0); //电子秤标定异常 } } // 滤波器初始化 float alpha = 1.0f - expf(-2 * M_PI * FILTER_CUTOFF_HZ / SAMPLE_RATE_HZ); IIR_Filter_Init(&weight_filter, alpha); IIR_Filter_Init(&fill_filter, alpha); // 初始化滤波器:初始位置=4000,初始速度=0 // Q:过程噪声,R:观测噪声 astkf_init(&filter, 80000.0, 0, 15000, 2000000, ADS_coef.ADC_VALUE_Last); //zero_calibration(); // 零点标记 //Loading_calibration(20000); // 假设加载标定值为20000g LPC_GPIOINT->IO2IntEnF |= ADS_DOUT;//启用ADS_DOUT中断 } uint8_t SFW_A; float LLw; float Lw_w; float sum = 0, sq_sum = 0, r = 0; uint8_t kfi; void ADS1232_Processing(uint8_t Calibration) { uint32_t ad; uint32_t IIRTemp; float weight_abs = 0.0f; if (1 == ADS_coef.Blance_Abnormal) SetBit((uint8 *)&FillAlarm.STS, 6, 0); // 6-称传感器异常 else ClrBit((uint8*)&FillAlarm.STS, 6); advanced_sliding_filter(&SF); SF.window_number++; if (SF.window_number > 0xffff && (Filling.State == IDLE)) // 加上没有在加注状态判断 { SF.window_number = 0; ADS_PDWN_L; // PDWN_L delay_us(40); ADS_PDWN_H; // PDWN_H 去电复位 delay_us(40); read_Ads1232(Calibration); delay_us(10); read_Ads1232(Calibration); } ADS_coef.ADC_VALUE = ADtoDiffVolt(SF.mean); // 读取差分电压值 ad = ADS_coef.ADC_VALUE; IIRTemp = IIR_Filter_Update(&weight_filter, (float)ADS_coef.ADC_VALUE); if (uabs_diff(IIRTemp, ADS_coef.ADC_VALUE) < 200) ADS_coef.ADC_VALUE = IIRTemp; // 预测与更新 if (ADS_coef.Valve_change > 0) //阀门有改变AD值不可信 { ADS_coef.Valve_change--; ADS_coef.ADC_VALUE = filter.x[0] + (fabsf(ADS_coef.weight_Last - LLw)/4); } else { //卡尔曼滤波 astkf_predict(&filter); astkf_update(&filter, ADS_coef.ADC_VALUE); ADS_coef.ADC_VALUE = filter.x[0]; } ADS_coef.weight = DiffVoltTOg(ADS_coef.ADC_VALUE); Lw_w = fabsf(ADS_coef.weight_Last - ADS_coef.weight); // if (Lw_w < 10 && Filling.State == IDLE) // ADS_coef.weight = (ADS_coef.weight + ADS_coef.weight_Last) / 2; // //计算流动稳定值(预测) // if (Lw_w < (Filling.FillingSpeed + 100)) // { // if (liu_wen == 0) // liu_wen = ADS_coef.weight; // else // liu_wen = (liu_wen + ADS_coef.weight + (Filling.FillingSpeed / 6)) / 2; // if (uabs_diff(liu_wen, ADS_coef.weight) > 200) // { // if (liu_count > 3) //修正 // { // liu_wen = ADS_coef.weight; // } // liu_count++; // } // else // liu_count = 0; // } // if (Filling.State != IDLE) // { // //防止突变 连续3次突变 // if (Lw_w > ADS_coef.weight_Last / 20 && ADS_coef.weight > (liu_wen + Filling.FillingSpeed)) // { // if (big_count < 5) // { // ADS_coef.weight = ADS_coef.weight_Last; // big_count++; // } // } // else // big_count = 0; // } //稳定性加强 if (Filling.State == FUELING && Filling.FillingSpeed > 0) //上次重量差小于上上次重量差三倍 { SF_W.WINDOW_SIZE = ((SFW_A >= 3) ? (SFW_A = 9) : SFW_A++); SF_W.EXCLUDE_NUM = 1; SF_W.buffer[SF_W.index] = ADS_coef.weight; if (SFW_A > 3) { //SF_W.buffer[SF_W.index] += (Filling.FillingSpeed/10*3); advanced_sliding_filter(&SF_W); if (fabsf(SF_W.mean - ADS_coef.weight) < 25) ADS_coef.weight = SF_W.mean; else { SFW_A = 0; SF_W.index = 0; } } SF_W.index = (SF_W.index + 1) % 3; } else if (Lw_w < 60) { SF_W.WINDOW_SIZE = ((SFW_A >= 14) ? (SFW_A = 14) : SFW_A++); if (Filling.State == SAVEDATA || Filling.State == SUSPEND) SF_W.EXCLUDE_NUM = 4; else SF_W.EXCLUDE_NUM = 2; SF_W.buffer[SF_W.index] = ADS_coef.weight; if (SFW_A > 9) { advanced_sliding_filter(&SF_W); ADS_coef.weight = SF_W.mean; } SF_W.index = (SF_W.index + 1) % 14; } else { SFW_A = 0; SF_W.index = 0; } // 判稳 if (fabsf(ADS_coef.weight_Last - ADS_coef.weight) < 5) //g { ADS_coef.wen_flag++; if (20 < ADS_coef.wen_flag) // 连续20次于上一次重量相差在5g以内 { BaData.DataStable = 1; FillFlag.DataState = 1; // 判断为数据稳定 if (1 == FirstUp && ADS_coef.weight != 0 && ADS_coef.weight < 200 && ADS_coef.zero_coef > 0) { FirstUp = 0; ADS_coef.NetWeight_coef = ADS_coef.ADC_VALUE - ADS_coef.zero_coef; } } if (ADS_coef.wen_flag > 0x2fff) // 保持稳定状态 ADS_coef.wen_flag = 0x2f; if (ADS_coef.wen_flag > 0x40 && ADS_coef.weight < 200) // 零点跟踪 { trace_s++; ADS_coef.zero_trace += ADS_coef.ADC_VALUE; ADS_coef.zero_trace = ADS_coef.zero_trace / 2; if (trace_s > 0x70) { ADS_coef.NetWeight_coef = ADS_coef.zero_trace - ADS_coef.zero_coef; trace_s = 0; } } else { } ADS_coef.wen_flag = 0; BaData.DataStable = 0; FillFlag.DataState = 0; // 判断为数据不稳 } WeightShow_10(ADS_coef.weight); sprintf((char *)com4.TX_Buffer, "show:%d weight:%f AD:%d ->%d Lw_LLw:%f speed:%d i_us:%ld\n", ADS_coef.weight_show, ADS_coef.weight, ad, ADS_coef.ADC_VALUE, fabsf(ADS_coef.weight_Last - LLw), (Filling.FillingSpeed), i_us); com4.TX_tailPtr = strlen(com4.TX_Buffer); STARTtx4(); i_us = 0; LLw = ADS_coef.weight_Last; ADS_coef.weight_Last = ADS_coef.weight; ADS_coef.ADC_VALUE_Last = ADS_coef.ADC_VALUE; ADS_coef.ADC_VALUE = 0; } 这是一个电子秤项目发现在充装过程中有卡尔曼滤波预测下一个的值相差很大,有预测下一个的值相差很小,观测的都是在加注中,所以预测都是想上预测的,这样很不稳定统一,如何解决
09-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值