/* CPPLL Hand Calculator, OC, 2007 Example : CaPPeLLo -Icp 10.0E-6 -Wn 1.0E6 -N 128 -Kvco 45.0E9 -Wi 40.0E6 -Ksi 0.9 */ #include "iostream" #include "math.h" float PI = 3.141592653589793; float C1, C3, C3min, C3max, R, Tau, Rmax, Bl, Kvco, Ko; float Wn, Wi, Ksi, Icp; float K, proportionalTerm, integralTerm; bool isRmaxOk, isStable; int N; //___________________________________________________________ void PrintUsageMessage(char *nameOfTheTool) { fprintf(stderr, "Switces of %s (2nd Order CP-PLL parameter calculator) are :\n\ -Kvco : VCO gain in Hz/V\n\ -N : Feedback divide ratio\n\ -Wi : Reference frequency in Hz\n\ -Wn : Natural frequency of the loop in Hz\n\ -Icp : Charge pump current in A\n\ -Ksi : Desired dumping factor\n\ ", nameOfTheTool); } //___________________________________________________________ void PrintDUT(char *nameOfTheTool) { fprintf(stderr, "\n\ Feed-Back System Under Consideration in %s :\n\ \n\ Kp Icp Tau Kvco\n\ +-----+ +----+ +-----+ +-----+ \n\ Wi -->| PFD |-->| CP |-->| LPF |--->| VCO |--+--> Wo\n\ +--+--+ +----+ +-----+ +-----+ |\n\ | |\n\ | Wo/N +----+ N*Wi |\n\ +---------------| %N |<-------------+\n\ +----+\n\ \n\ Low Pass Filter Configuration :\n\ \n\ +-----+\n\ | LPF | ==> +----+-------+----+\n\ +-----+ | |\n\ | |\n\ | +-+\n\ | C3 | | R\n\ ----- | | \n\ ----- | |\n\ | +-+\n\ | |\n\ | | C1\n\ | -----\n\ | -----\n\ | |\n\ | |\n\ ----- ----- \n\ --- ---\n\ - -\n\ \n", nameOfTheTool, nameOfTheTool); } //___________________________________________________________ int SetParameters(int argc, char **argv) { if (argc <= 1) { PrintUsageMessage(argv[0]); exit(0); } int optCtr = 1; if (strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0 ) { PrintUsageMessage(argv[0]); exit(0); } while (optCtr != argc) { if (0 == strcmp(argv[optCtr], "-N")) { optCtr++; sscanf(argv[optCtr], "%d", &N); optCtr++; } else if (0 == strcmp(argv[optCtr], "-Wn")) { optCtr++; sscanf(argv[optCtr], "%f", &Wn); Wn=Wn*2.0*PI; // convert to rad/s optCtr++; } else if (0 == strcmp(argv[optCtr], "-Kvco")) { optCtr++; sscanf(argv[optCtr], "%f", &Kvco); Ko=Kvco*2.0*PI; // convert to rad/s/V optCtr++; } else if (0 == strcmp(argv[optCtr], "-Wi")) { optCtr++; sscanf(argv[optCtr], "%f", &Wi); Wi=Wi*2.0*PI; // convert to rad/s optCtr++; } else if (0 == strcmp(argv[optCtr], "-Ksi")) { optCtr++; sscanf(argv[optCtr], "%f", &Ksi); optCtr++; } else if (0 == strcmp(argv[optCtr], "-Icp")) { optCtr++; sscanf(argv[optCtr], "%f", &Icp); optCtr++; } else { PrintDUT(argv[0]); PrintUsageMessage(argv[0]); exit(1); } } return 0; } //___________________________________________________________ int Calculate() { C1=(Ko*Icp)/(2*PI*Wn*Wn*N); C3max=0.1*C1; C3min=0.02*C1; C3=(C3min+C3max)/2.0; Tau=(2*Ksi)/Wn; R=Tau/C1; K=(Ko*Icp*R)/(2*PI*N); Rmax=(2*PI*Wi*N)/(Ko*Icp); Bl=((Wn/2.0)*(Ksi+1.0/(4.0*Ksi))); proportionalTerm=Icp*R; integralTerm=Icp/(C3*Wi); if (R <= Rmax) isRmaxOk = true; else isRmaxOk = false; if (K*Tau < Wi*Tau) isStable = true; else isStable = false; return 0; } //___________________________________________________________ int Output() { printf("Loop Parameters : \n\n"); printf("Wi in Mrad/s : %f\n", (float)(Wi/1.0E6)); printf("Wo in Grad/s : %f\n", (float)(Wi*N*1.0E-9)); printf("Wn in Mrad/s : %f\n", (float)(Wn*1.0E-6)); printf("N : %f\n", (float)(N)); printf("Ksi : %f\n", (float)(Ksi)); printf("Ko in Grad/s/V : %f\n", (float)(Ko*1.0E-9)); printf("Icp in uA : %f\n", (float)(Icp*1.0E6)); printf("C1 in pF : %f\n", (float)(C1/1.0E-12)); printf("C3min in pF : %f\n", (float)(C3min*1.0E12)); printf("C3max in pF : %f\n", (float)(C3max*1.0E12)); printf("C3 in pF : %f\n", (float)(C3*1.0E12)); printf("R in Ohm : %f\n", (float)(R)); printf("Rmax in Ohm : %f (", (float)(Rmax)); if (!isRmaxOk) printf("ERROR - R>Rmax, Conflict !..)\n"); else printf("R