/* pll.c Software Linear PLL 6211 Program */ /* Upendra Ummethala and Mike Mellor */ /* December 19, 2000 EE539 Real Time DSP Final Project */ #define N 8000 #include "sin8000_table.h"/* Sine wave digitized to 8000 points */ /* The variable names used below are from Chapter 5 in */ /* the book: Phase-Locked Loops by Roland Best */ /* Fourth edition McGraw-Hill */ int u1_n; /* Input signal at time n */ int u2_n=0; /* DCO output signal at time n */ int u2_nplus1; /* DCO output signal at n+1 */ int phi2_n=0; /* DCO output phase at time n */ int phi2_nplus1; /* DCO output phase at n+1 */ int ud_n_1=0; /* Phase detector output at n-1 */ int ud_n; /* Phase detector output at n */ int uf_n_1=0; /* Loop filter output at n-1 */ int uf_n; /* Loop filter output at n */ int inp_freq=100; /* Input sine freq = 100Hz */ int table_index=0; /* Index into the sine table */ int w0= 628; /* 100Hz = 628 rad/s target freq*/ int K0= 1; /* VCO Gain scaled up by ~2^6 */ int uf_n_tmp; /* Tmp to scale uf_n down by 2^6*/ int cycle_count=0; /* Number of sine cycles */ int pi_scaled=25133; /* PI scaled by 8000 Hz rate */ int A1 = -4002; /* Loop filter coefficient scaled up by 2^12*/ int B0 = 4348; /* Loop filter coefficient scaled up by 2^12*/ int B1 = -3784; /* Loop filter coefficient scaled up by 2^12*/ void main() { comm_poll(); while(1) /* Runs forever */ { /* Create scaled input */ u1_n=31*sin8000_table[table_index];/* from sine table */ /* The following is for generating the input*/ table_index=table_index+inp_freq; if(table_index >= N) { /* Unwrap phase if 2*pi range */ table_index -= N; /* is exceeded, i.e. modulo N */ cycle_count++; /* Count cycles at phase wrap */ } if(cycle_count >100) /* After 100 cycles */ { /* at this phase give */ table_index += (N >> 2); /* a 180 degree phase step */ cycle_count = 0; /* Reset cycle count. */ } u1_n=input_sample(); /* obtain input from ADC*/ ud_n=u1_n*u2_n; /* Phase detector output */ uf_n=-A1*uf_n_1+B0*ud_n+B1*ud_n_1; /* Filter output */ uf_n=uf_n>>12; /* Scaled down filter output*/ uf_n_tmp=uf_n>>6; /* Undo VCO Gain(K0) scaling*/ /* Calculate next DCO output*/ /* phase for time n+1 */ phi2_nplus1=phi2_n+(w0+K0*uf_n_tmp); /* Maintain -pi to +pi range*/ /* for next DCO phase */ if (phi2_nplus1>pi_scaled) /* If next DCO phase>pi */ phi2_nplus1=phi2_nplus1-2*pi_scaled; /* unwrap by 2*pi*/ if (phi2_nplus1>=0) /* If next DCO phase is positive*/ u2_nplus1=1; /* DCO output=+1(Walsh function)*/ else /* If next DCO phase is negative*/ u2_nplus1=-1; /* DCO output=-1(Walsh function)*/ output_sample(u2_nplus1*31000); /* Output to scope */ /* Update values for next pass through loop */ ud_n_1=ud_n; /* Phase detector: ud(n-1)=ud(n)*/ uf_n_1=uf_n; /* Filter ouput: uf(n-1)=uf(n) */ phi2_n=phi2_nplus1; /* DCO phase: phi2(n)=phi2(n-1) */ u2_n=u2_nplus1; /* DCO output: u2(n)=u2(n+1) */ } }