/* adc_c subroutine * analog to digital converter * with input static non-linear * function * * Copyright (C) 2007-2009 Alan Layec * * This file is part of modnumlib. * * modnumlib is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * modnumlib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with modnumlib; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* REVISION HISTORY : * $Log$ */ #include <math.h> #include "modnum_lib.h" /*based on f2c definition*/ #define d_nint(x) ((x) > 0 ? floor((x)+.5) : -floor(.5 - (x))) /* * adc_c routine de calcul d'un convertisseur analogique numérique * * Entrées : * n : taille des vecteurs * type : type de quantification (scalaire) * 0 - contre marche * 1 - mi-marche * nbit : longueur en bit de la valeur décimale de sortie (scalaire) * cc2 : flag code complément à 2 (scalaire) * 0 : nombre entier non signé * 1 : nombre entier signé * qn : flag calcul bruit de quantification (scalaire) * 0 : pas de calcul * 1 : calcul sur sortie régulière 2 * q : pas de quantification (scalaire) * vmin : valeur minimale du début de la quantification (scalaire) * of_er : erreur d'offset (scalaire) * fsr_er : erreur fsr (scalaire) * u : vecteur d'entrée (vecteur) * * Sorties : * y1 : vecteur de sortie du convertisseur (vecteur) * y2 : vecteur de sortie du bruit de quantification (vecteur) * * Dépendances : * math.h */ void adc_c(int *n,int *type,int *nbit, int *cc2,int *qn,double *q,double *vmin,\ double *of_er, double *fsr_er,double *u,double *y1,double *y2) { /*Déclaration des variables compteurs*/ int i; /*Déclaration de variables auxiliares*/ double fsr; /*full scale range*/ double fsr_dec; /*decalage du full scale range*/ for(i=0;i<(*n);i++) { /*Calcul échelle maximale*/ fsr=((double)((1<<(*nbit))-1))*(*q); /*Calcul erreur fsr*/ if ((*fsr_er)!=0.0) fsr_dec=u[i]-u[i]*((*vmin)+fsr+(*fsr_er))/((*vmin)+fsr); else fsr_dec=0.0; /*Réalise quantification*/ if ((*type)==0) /*Calcul pour une quantification à contre-marche*/ y1[i]=(*q)*(d_nint((u[i]+(*of_er)+fsr_dec)/(*q)-.5)); else if ((*type)==1) /*Calcul pour une quantification à mi-marche*/ y1[i]=(*q)*(d_nint((u[i]+(*q)/2.0+(*of_er)+fsr_dec)/(*q)-.5)); /*Test sur la grandeur de sortie(saturation)*/ if(y1[i]<(*vmin)) y1[i]=(*vmin); else if(y1[i]>(*vmin)+fsr) y1[i]=(*vmin)+fsr; /*Calcul valeur finale*/ y1[i]=(double)((int)((y1[i]-(*vmin))/(*q))); /*Calcul bruit de quantification*/ if ((*qn)!=0) y2[i]=(y1[i]*(*q))-(*vmin)-u[i]; /*Test code complément à 2*/ if((*cc2)==1) y1[i]=y1[i]-((double)(1<<((*nbit)-1))); } return; } /* * adcv_c routine de calcul d'un convertisseur analogique numérique * * Entrées : * n : taille des vecteurs * type : type de quantification (vecteur) * 0 - contre marche * 1 - mi-marche * nbit : longueur en bit de la valeur décimale de sortie (vecteur) * cc2 : flag code complément à 2 (vecteur) * 0 : nombre entier non signé * 1 : nombre entier signé * qn : flag calcul bruit de quantification (scalaire) * 0 : pas de calcul * 1 : calcul sur sortie régulière 2 * q : pas de quantification (vecteur) * vmin : valeur minimale du début de la quantification (vecteur) * of_er : erreur d'offset (vecteur) * fsr_er : erreur fsr (vecteur) * u : vecteur d'entrée (vecteur) * * Sorties : * y1 : vecteur de sortie du convertisseur (vecteur) * y2 : vecteur de sortie du bruit de quantification (vecteur) * * Dépendances : * math.h */ void adcv_c(int *n,int *type,int *nbit, int *cc2,int *qn,double *q,double *vmin,\ double *of_er, double *fsr_er,double *u,double *y1,double *y2) { /*Déclaration des variables compteurs*/ int i; /*Déclaration de variables auxiliares*/ double fsr; /*full scale range*/ double fsr_dec; /*decalage du full scale range*/ for(i=0;i<(*n);i++) { /*Calcul échelle maximale*/ fsr=((double)((1<<nbit[i])-1))*q[i]; /*Calcul erreur fsr*/ if (fsr_er[i]!=0.0) fsr_dec=u[i]-u[i]*(vmin[i]+fsr+fsr_er[i])/(vmin[i]+fsr); else fsr_dec=0.0; /*Réalise quantification*/ if (type[i]==0) /*Calcul pour une quantification à contre-marche*/ y1[i]=q[i]*(d_nint((u[i]+of_er[i]+fsr_dec)/q[i]-.5)); else if (type[i]==1) /*Calcul pour une quantification à mi-marche*/ y1[i]=q[i]*(d_nint((u[i]+q[i]/2.0+of_er[i]+fsr_dec)/q[i]-.5)); /*Test sur la grandeur de sortie(saturation)*/ if(y1[i]<vmin[i]) y1[i]=vmin[i]; else if(y1[i]>vmin[i]+fsr) y1[i]=vmin[i]+fsr; /*Calcul valeur finale*/ y1[i]=(double)((int)((y1[i]-vmin[i])/q[i])); /*Calcul bruit de quantification*/ if ((*qn)!=0) y2[i]=(y1[i]*q[i])-vmin[i]-u[i]; /*Test code complément à 2*/ if(cc2[i]==1) y1[i]=y1[i]-((double)(1<<(nbit[i]-1))); } return; }