From: provo_b@kosmos.wcc.govt.nz (Bart)
Subject: Re: Bugs in 68HC16 project.
Reply-To: provo_b@kosmos.wcc.govt.nz
Organization: Wellington City Council, Wgtn, NZ
Date: Sat, 29 Aug 1992 21:45:43 GMT

Subject: Re: Bugs in 68HC16 project
>morrow@cns8.ucalgary.ca (Bill Morrow) writes on Wed, 26 Aug 92 17:07:29 GMT

>..HC16 development project 5-channel filter. His IIR filter seems to be 
>  saturating, so I'm wondering if there is a mistake in the instructions.

YES!  There are also a number of areas in the code that could be improved.

The given SPI command queue causes PCS0 to be negated to eliminate the one
"dont care" byte that would otherwise occur in an un-interrupted transmission.
Normally this results in some "ghosting" on the display LEDs.  However if
the PIT has been set for a faster Periodic Interrupt period, (by mistake
or oversight) this ghosting will become brighter and can swamp the display!

The corrections to the coefficient calculations are below, and a short C
program that I use to significantly ease the task of trying different
filters is appended.

/*************************** extract ***************************************
Subject: 'HC16 toolkit
From: datwyler@javelin.sim.es.com (Doug Datwyler)
Date: Tue, 17 Mar 1992 19:51:54 GMT

I got the question answered about the filter coefficients, twice. Once from
an applications engineer, the other from Ross Wille. Thanks to both.
On sheet 33 of the Project Manual, there is an error.

Fo = 1kHz  Fs = 24.95kHz Q = 1.5  	 Theta = ((2 * PI * Fo) / Fs)
X = Theta / (2 * Q)               	 if X > PI / 4 then X = 0.76398

Beta = 0.5 * {1 - tan(X)} / {1 + tan(X)}
Gamma = (0.5 + Beta) * cos(Theta)
Alpha = (0.5 - Beta) / 2

So, you see, the angle is never allowed to get where the Beta coefficient is
less than 0 (zero).
****************************************************************************/
/* Simple program to compute the coefficents for the 5band analyser program
   and generate HC16 assembler lines for inclusion.  COEFF.exe compiled with
   TURBO-C 1.5.

   Note that I have used the half bandwidth, h_bw = bw/2, for the program
   input option and for the output lines.  This made it a little more
   convenient in testing the 5band spectrum analyser.

   The following batch file generates coeff.asm, given the half bandwidth.
   5bc.bat:
            coeff 1000 , 3  >coeff.asm  | With this bandwidth, observed
            coeff 2000 , 3 >>coeff.asm  | differences in peak frequencies
            coeff 3000 , 3 >>coeff.asm  | could be attributed to the
            coeff 4000 , 3 >>coeff.asm  | uncertainty of the frequency counter
            coeff 5000 , 3 >>coeff.asm  | on the IWTASU CRO, which was used!

   The following batch file generates coeff.asm, given the filter's Q.
   5bc0.bat:
            coeff 125   .5  >coeff.asm
            coeff 500  1.  >>coeff.asm
            coeff 1000 1.5 >>coeff.asm
            coeff 4000 1.0 >>coeff.asm
            coeff 1E4   .5 >>coeff.asm

  Modify the 5band.asm file by removing the "dc.w <filter coefficient>" lines
  and replace with:
        ORG     $F0280          ; following lines have been replaced
        INCLUDE 'COEFF.asm'     ; COEFF.asm created by 5bc0.bat from coeff.exe.
        ....                    ; etc.
*/

/* -------- COEFF.c -------------- */

#include <stdio.h>
#include <math.h>

void  PrintCoefficents(float Fo, float Q);
float theta(float Fo, float Fs);
float phi(float theta, float Q);
float beta(float phi);
float gamma(float beta, float theta);
float alpha(float beta);
int   FloatToInt(float X);

float Fs = 24950;         /* Fs is sample rate for acquired data */

void PrintCoefficents(float Fo,float Q)
{
  float h_bw,t,p,b,g,a ;  /* h_bw is half band-width of filter */

  h_bw = Fo/(2*Q) ;
  t    = theta(Fo,Fs) ;
  p    = phi(t,Q) ;
  b    = beta(p) ;
  g    = gamma(b,t) ;
  a    = alpha(b) ;

  printf("  dc.W  $%04X    ; %5.0f Hz, gamma coeff,     Q = %8.2f\n",
         FloatToInt(g),  Fo,  Q) ;
  printf("  dc.W  $%04X    ; %5.0f Hz, -beta coeff, h_bw = %7.1f\n",
         FloatToInt(-b), Fo, h_bw) ;
  printf("  dc.W  $%04X    ; %5.0f Hz, alpha coeff.\n",
         FloatToInt(a),  Fo) ;
}

float theta(float Fo,float Fs)
{
  return ((2.0 * M_PI * Fo)/Fs);
}


float phi(float theta, float Q)
{
  float X;
  X = theta/(2*Q);
  if( X > M_PI/4 )  X = 0.76398;
  return (X) ;
}


float beta(float X)
{
  float tanX;
  tanX = tan(X);
  return ( 0.5 * (1.0 - tanX)/(1.0 + tanX) );
}


float gamma(float beta,float theta)
{
  return (0.5 + beta) * cos(theta);
}


float alpha(float beta)
{
  return (0.5 - beta)/2.0;
}


int FloatToInt(float x)
{
  if ((x > 1.0) || (x < -1.0))
    {
      fprintf(stderr,"Cannot convert %f.\n",x);
      return 0;
    }
  else return (int)(x * 32768.0);
}


void main(int argc, char *argv[])
{
  float Fo,Q,h_bw ;

  if (argc < 2)              /* argc is no. of arguments plus one */
  {
    printf("Usage: coeff Fo, [Q], [h_bw]   Note: Either Q or , h_bw\n") ;
    exit(1) ;
  }
  sscanf(argv[1], "%f", &Fo) ;
        if (*argv[2] != ',')
         sscanf(argv[2], "%f", &Q ) ;
        else
         {
         sscanf(argv[3], "%f", &h_bw) ;
         Q = Fo/(2*h_bw) ;
         }
  PrintCoefficents( Fo, Q) ;
}
--------------------- end of COEFF.c ----------------------

Hope this helps,
Regards,
Bart.
Bart Provo    |provo_b@kosmos.wcc.govt.nz |School of Electronic Engineering
PO Box 47-105 |access via: PC/AT+modem on |Central Institute of Technology
TRENTHAM      |home phone, (answer phone) |Private Bag 39-807
Wellington    |     in NZ: (04)-5277-054  |Wellington Mail Centre,  NZ.
NEW ZEALAND.  |     to NZ:+64-4-5277-054  |Phn:(04)5277-089 Fax:(04)5276-374
Newsgroups: comp.dsp