⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f_13_32_sqwavemeas.c

📁 * Use 10 MHz crystal frequency. * Use Timer0 for ten millisecond looptime. * Blink "Alive" LED e
💻 C
字号:

#include "config.h"
#include "serial.c"
#include "serio.c"

#if defined(__18CXX)
void my_gets (char *s);
//return a string from the console
void my_gets (char *s){
 char c;
 
 do {
  c = getche();
  *s = c;
  s++;
  } while (c != '\r');
}
#endif


// Has timer2 PWM generate sqware wave
// timer & CCP2 capture mode measures it

volatile unsigned int last_capture, this_capture;
volatile unsigned long delta,delta_old; // this must be long
volatile unsigned char tmr1_ov;  // timer 1 overflow cnt
volatile unsigned char capture_flag;

#if defined(HI_TECH_C)
void interrupt timer_isr(void)
#endif
#if defined(__18CXX)
#pragma interrupt timer_isr
void timer_isr(void)
#endif
{
  if (TMR1IF) {
    tmr1_ov++;  // increment timer1 overflow
    TMR1IF = 0;
  }
  if (CCP2IF) {
    CCP2IF = 0;   // 	CCP2IF = 0; clear capture interrupt flag
    this_capture = CCPR2;
    if (!tmr1_ov) { 
      // no overflow at all
      delta = this_capture - last_capture ;
    }
    else {
      delta = tmr1_ov-1;
      delta = (delta << 16);
      last_capture = 0 - last_capture;  // time to overflow
      delta = delta + last_capture;
      delta = delta + this_capture;
    }
    last_capture = this_capture;
    tmr1_ov = 0;
    capture_flag++;
  }
}

#define FOSCQ 29491200
#define TMR1PRE 1.0
#define TMR1TIC 1.0/(FOSCQ/4.0)*TMR1PRE
#define TMR2PRE 4.0

double period_float;
unsigned int meas_period,exp_period;
int pr2_val;

void main(void){
  serial_init(95,1); // 19200 in HSPLL mode, crystal = 7.3728 MHz 
  // initialize timer 1
  T1CKPS1 = 0;  T1CKPS0 = 0;// prescale by 1
  T1OSCEN = 0;  // disable the oscillator 
  TMR1CS = 0;  //use internal clock FOSC/4
  T1SYNC = 0;
  bitset(TRISC,1);// configure CCP2 as input
  // configure capture
  CCP2CON = 0x07; // capture every 16th edge
  CCP2IF = 0; // clear CCP2IF interupt flag 
  CCP2IE = 1;   // enable capture interrupt 
  // turn on timer1
  TMR1IF = 0; TMR1IE = 1; TMR1ON = 1;   // enable timer 1
  tmr1_ov = 0;
  pcrlf();printf("Enter PR2 Value: ");
#if defined(HI_TECH_C)	
  scanf("%d",&pr2_val); 
#endif
#if defined(__18CXX)
    {// MCC18 does not have scanf, just get string from console, use atoi
	  char buf[30];
	  my_gets(buf);  // get a string from console
	  pr2_val = atoi(buf);  // convert string to integer
	}
#endif   
  pcrlf();
  period_float =  ((pr2_val+1)*4*TMR2PRE*1.0e9)/FOSCQ;
  exp_period = (unsigned int) period_float;
  
  bitclr(TRISC,2);// set CCP1 as OUTPUT for pwm
  // configure timer2
  T2CKPS1=0;T2CKPS0=1;   // prescale of 4
  // set up PWM 
  PR2 = pr2_val;   // set period
  CCPR1L = (pr2_val >> 1); // 50% duty cycle 
  DC1B1=0; DC1B0=0;  
  CCP1M3 = 1;CCP1M2 = 1;// PWM Mode 
  TMR2ON=1;

  printf("Squarewave Measure Enabled"); pcrlf();
  IPEN = 0; PEIE = 1;  GIE = 1;  // enable interrupts 
  while(1) {
    capture_flag = 0;
    while(!capture_flag); // wait for capture
    delta_old = delta >> 4;  // divide by 16 for true freq
    period_float = (delta_old * TMR1TIC)*1.0e9;
    meas_period = (unsigned int) period_float;
    printf ("Expected period: %u (ns), Measured period: %u (ns)", 
	    exp_period,meas_period);
    pcrlf();
    printf("Hit a key to continue.");pcrlf();
    getch();
  }
}

//for MCC18, place the interrupt vector goto
#if defined(__18CXX)
#if defined(HIGH_INTERRUPT)
#pragma code HighVector=HIGH_INTERRUPT
#else
#pragma code HighVector=0x0008  
#endif
void HighVector (void)
{
    _asm goto timer_isr _endasm
}
#pragma code
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -