Input capture mode of MC9S12XHZ512

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Input capture mode of MC9S12XHZ512

615 次查看
kdn
Contributor III

I am using Input capture mode of MC9S12XHZ512 for calculating frequency and duty cycle of square wave from 1KHz to 10KHz , I have attached image of setting i have done in codewarrior.

 

My problem is that when I try to display frequency on my LCD display I am getting random charter on , I also have problem with interrupt input capture mode I have enable input capture mode in codewarrior , but i'm not able to find it in program , I want to write my display and calculation code in interrupt sub routine of input capture mode. I have posted my code below.

 

I'm using 16MHz crystal

 

 

LCD_Cmd(0x80);

  

                  

         //  TM=65535*(TC0/16000000);

         //  TM=1/TM;

        

         t[i]=TC0;

        

          i++;

        

          if(i==2) {

          i=0;

         

        

        

         time_interval=(t[1]-t[0]);

         time_interval=(float)(0.0000000625*time_interval);

         frequency= 1/time_interval;

      

       

  

         sprintf(buffer,"%d",frequency);

 

         for(j=0;j<5;j++)

         {

         LCD_Data(buffer[j]);

         }

         }

       

18222_18222.pngINPUT caputre.png

标签 (1)
0 项奖励
回复
1 回复

410 次查看
lama
NXP TechSupport
NXP TechSupport

Hi,

i am not a fan of the PE SW solutions.

i would like t show you how to measure frequency with own setup. I think you you understand how to set the PE then you are also able to set the registers yourself and you have everything under your control.

//------------------------------------------------------------------------------

// Frequency Measurement

//------------------------------------------------------------------------------

#include <hidef.h>           /* common defines and macros */

#include <mc9s12xa512.h>     /* derivative information */

#include <stdio.h>                     /* include string functions              */

#pragma LINK_INFO DERIVATIVE "mc9s12xa512"

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Local types definitions

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#define     UBYTE       unsigned char

#define     SBYTE                char

#define     UWORD       unsigned  int

#define     UDWORD      unsigned  long int

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// PROGRAM DEFINITION

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#define BUSCLOCK                20000000UL  // Hz

#define TIMER_PRESCALER         2          // 1,2,4,8,16,32,64,128 - smaller values give more precise values but

                                           // it generates timer overflow more frequently

#define MAX_OVERFLOWS           1000L      // maximum allowed number of overflows

                                           // when overflows counter reaches this value it sends message

                                           // PERIOD BETWEEN TWO EDGES IS TO WIDE over the SCI

                                           // this value gives time interval:

                                           // T = TIMER_PRESCALER * MAX_OVERFLOWS / BUSCLOCK

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// DEPENDENT DEFINITIONS

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#if TIMER_PRESCALER==1

#define PRESCALER 0

#endif

#if TIMER_PRESCALER==2

#define PRESCALER 1

#endif

#if TIMER_PRESCALER==4

#define PRESCALER 2

#endif

#if TIMER_PRESCALER==8

#define PRESCALER 3

#endif

#if TIMER_PRESCALER==16

#define PRESCALER 4

#endif

#if TIMER_PRESCALER==32

#define PRESCALER 5

#endif

#if TIMER_PRESCALER==64

#define PRESCALER 6

#endif

#if TIMER_PRESCALER==128

#define PRESCALER 7

#endif

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Local functions definitions

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

static void Tim0_Init(void);

void  SCI0_Setup(void);       // set SCI0 communications parameters

void  sendValue(void);        // send value over the SCI0

void  PLL_Init(UBYTE synr, UBYTE refdv);

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// GLOBAL VARIABLES

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

static UDWORD udwPeriod;      // calcualted period - depends on BUSCLK and timer setup =

                              // = number of bus periods between two pulses

static UWORD  uwCh2ovfCnt;    // the number of main timer overflows between two pulses on Ch2

static UWORD  uwTimerOldValue=0;

static UWORD  uwTimerNewValue=0;

       SBYTE   str[200];

//----------------------------

typedef union uFlags

{ UBYTE  byte; struct { UBYTE f0 :1; UBYTE f1 :1; UBYTE f2 :1; UBYTE f3 :1;

                         UBYTE f4 :1; UBYTE f5 :1; UBYTE f6 :1; UBYTE f7 :1; }bit;

}tFlags;

static volatile tFlags  Flags;  // general purpose flags

#define WHEEL1_OVF_CNT_STOPS_FLAG    Flags.bit.f0

#define NEW_VALUE_PREPARED           Flags.bit.f1

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//                                  MAIN

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

void main(void)

{

  UWORD j,k;

  PLL_Init(4,3);                            // 20MHz BUSCLK from 16MHz OSCCLK

 

  Tim0_Init();                              // timer and channels initialization

  SCI0_Setup();                             // SCI communication parameters setup

  asm CLI;                                  // enable all interrupts            

                                            // variables initialization

  DDRB =0xFF;

  WHEEL1_OVF_CNT_STOPS_FLAG = TRUE;                    // set flag

  for(;;)                                   // main program loop

   {

     if(NEW_VALUE_PREPARED) sendValue();    // send measured value over SCI

   }

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Module: void  PLL_Init(UBYTE synr, UBYTE refdv)

// Description:    The function initalizes PLL

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

void  PLL_Init(UBYTE synr, UBYTE refdv)

{

CLKSEL &= 0x7F;  

REFDV = refdv;

SYNR  = synr;

while(!(CRGFLG_LOCK));

CLKSEL_PLLSEL = 1;

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Send Measured Value

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

void  sendValue(void)

{

static float f;

UBYTE i;

if(WHEEL1_OVF_CNT_STOPS_FLAG)                // Have overflows counter reached maximum value?

  {

   sprintf(str,"%s","PERIOD BETWEEN TWO RISING EDGES IS TO WIDE\n\r");

  }

else

  {

   // calculate time between two edges

   f = (((float)TIMER_PRESCALER)*((float)udwPeriod))/((float)BUSCLOCK);

   // prepare text to be sent

   sprintf(str,"f = %-10.3f [Hz]; T = %-10.6f [s]; count value = %-10.0f\n\r",1/f,f,(float)udwPeriod);

  }

i=0;

while(str[i]!='\0')                           // send message

  {

   while(!SCI0SR1_TC);                         // wait while TC=0 - transmition in progress

   SCI0DRL=str[i];

     i++;

  }

NEW_VALUE_PREPARED =FALSE;                    // clear flag = value has been sent

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Module: void Tim0_Init(void)

// Description: The function sets timer and channels

//              Channel2 - input capture on both edges in queue mode

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

static void Tim0_Init(void)

{

  TSCR2 = TSCR2_TOI_MASK | PRESCALER;  // timer ovf. int. enable; prescaller= given by definition

  uwTimerOldValue = 0;                 // set initial value

  TCTL4 = 0x10;                        // channel 2 input capture on rising edge

  ICSYS = ICSYS_BUFEN_MASK;            // input capt. and hold. registers enabled, interrupt on capture

  ICOVW = ICOVW_NOVW2_MASK;            // related capture register can be overwritten after every new capture

  TIE   = TIE_C2I_MASK;                // enable Ch2 interrupt

  TSCR1 = 0xE0;                        // enable timer, stop during freeze and wait

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Module: void Tim0ch0_ISR(void)

// Description:    The function serves capture channel 0 interrupt

//                      Channel1 - input capture on both edges in queue mode

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#pragma CODE_SEG NON_BANKED

interrupt 10 void Tim0ch2_ISR(void)

{

  unsigned int ovfs;

 

  uwTimerNewValue = TC2;               // read new captured value and clear flag

  ovfs = uwCh2ovfCnt;                  // save number of overflows to temporary variable

  uwCh2ovfCnt = 0;                     // clear number of overflows

  TFLG1 = TIE_C2I_MASK;                // clear interrupt flag

 

  PORTB=~PORTB;                        // show (PT0) incomming signal on port B

                                       //-----  Ch2 period calculation ---------

  if(!ovfs)                            // Did edges appear within one timer period?

    {

      udwPeriod = (UDWORD)(uwTimerNewValue - uwTimerOldValue);

    }

   else                                // some number of overflows has appeared between two edges

    {

      udwPeriod = (UDWORD)( ~uwTimerOldValue+1 ); // time in the first period

      udwPeriod+= (UDWORD)(  uwTimerNewValue);    // time in the last  period

      udwPeriod+= (UDWORD)((UDWORD)((ovfs-1)) * (UDWORD)(65536)); // time given by overflows

    }

  uwTimerOldValue = uwTimerNewValue;    // prepare new old value

  NEW_VALUE_PREPARED = TRUE;            // information for main routine

  WHEEL1_OVF_CNT_STOPS_FLAG = FALSE;    // clear flag

}

#pragma CODE_SEG DEFAULT

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Module: void Tim0ovf_ISR(void)

// Description: Main timer overflov service routine

//              The number of overflows of channel 2 capture is accumulated here

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#pragma CODE_SEG NON_BANKED

interrupt 16 void Tim0ovf_ISR(void)

{

  uwCh2ovfCnt++;                      // count overflows

  if(uwCh2ovfCnt>MAX_OVERFLOWS)

   {

     uwCh2ovfCnt = 0;

     WHEEL1_OVF_CNT_STOPS_FLAG = TRUE;

     sendValue();                     // send message to the PC each overflow of the timer overflows_counter

   }

  else

   { WHEEL1_OVF_CNT_STOPS_FLAG = FALSE;

   } 

  TFLG2_TOF = 1;                      // clear interrupt flag of main timer

}

#pragma CODE_SEG DEFAULT

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#pragma CODE_SEG DEFAULT

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// Module: void SCI0_Setup(void)

// Description: 8 data bits + 1 stop bit with speed 9600 bps.

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

void  SCI0_Setup(void)     //SCI0 is used fo PC Master communication

{

/*---------------------------------------------------------------------------*/

/* define serial protocol for SCI0:                                          */

/* 8 data + 1 stop bit; 9600 Bd; enable Rx interrupt, disable Tx interrupt   */

                      /*------------------------------------------------------*/

                      /* set serial communication baud rate (9600 Bd)         */

                      /*------------------------------------------------------*/

                      /*SCI baud rate= SCI Module Clock / (16 * SBR) // IREN=0*/

                      /*SCI baud rate= SCI Module Clock / (32 * SBR) // IREN=1*/

   SCI0BDH = 0x00;    /* prescaller value (depends on module clock frequency) */

   SCI0BDL = 0x82;    /* prescaller = 0x82    (BUS=20MHz)                     */

                      /*------------------------------------------------------*/

                      /* set serial protocol (1+8+1)                          */

                      /*------------------------------------------------------*/

   SCI0CR1 = 0x44;    /* loops sciswai rsrc   m    wake  ilt   pe    pt       */

                      /* 0-loops disabled                                     */

                      /* 1-SCI dis. in wait mode                              */

                      /* 0-RxTx intern. connected if loops=1                  */

                      /* 0-1 start+8 data+1 stop bit                          */

                      /* 0-IDLE mark wake up                                  */

                      /* 1-idle char. bit count begins after stop bit         */

                      /* 0-parity fction disabled                             */

                      /* 0 - odd parity                                       */

                      /*------------------------------------------------------*/

                      /* enable transmitter, receiver and Rx full interrupt   */

                      /*------------------------------------------------------*/

   SCI0CR2 = 0x2C;    /* tie   tcie    rie  ilie   te    re   rwu   sbk       */

                      /* 0-Tx empty intr disabled                             */

                      /* 0-Tx complete intr disabled                          */

                      /* 1-Rx full intr enabled                               */

                      /* 0-idle line intr disabled                            */

                      /* 1-transmitter enabled                                */

                      /* 1-receiver enabled                                   */

                      /* 0-normal operation                                   */

                      /* 0-no break characters                                */

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

0 项奖励
回复