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

📄 09.04pm_dn100_gas.c

📁 用单片机和DSP测量DN100管道的气体流量,使用涡街传感器
💻 C
📖 第 1 页 / 共 2 页
字号:
  P4DIR = 0xFF; //output

  //hpic <- val
  P5OUT |= BIT4;  //~HDS=1
  P5OUT &= ~(BIT5+BIT6+BIT7);//HCNT0=HCNT1=HR/~W=0
  P5OUT &= ~BIT3; //HBIL=0
  P5OUT &= ~BIT4;  //~HDS=0
  P4OUT = (char)val;
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpicw = HPI_chkrdy();
  if(re_hpicw!=0) return -1;
  P5OUT |= BIT3;  //HBIL=1
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = (val>>8);
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpicw = HPI_chkrdy();
  if(re_hpicw!=0) return -1;
  
  return 0;
}

int HPI_chkrdy(void)// check the HPI ready?
{
  int j=0;
  do{
      //等待HDRY=1
      if((P5IN&BIT0)!=0) break;
      for(delay=0;delay<10;delay++);
      j++;
    }while(((P5IN&BIT0)==0)&&(j<3));  
  if(j>=3)
    return -1;
  else
    return 0;
}
 

//430通过HPI口向DSP装载DSP的运行代码
int hpi_write(unsigned long addr, char* buf, unsigned long len)
{
  unsigned long i;
  
  re_hpiwrite = hpia_w(addr);
  if(re_hpiwrite!=0) return -1;
  
  for(i=0; i<(((len%2)==0)?(len/2):(len/2+1)); i++)
  {
    re_hpiwrite = hpid_w_inc(*(unsigned int*)(&buf[i*2]));
    if(re_hpiwrite!=0) break;
  }
  return re_hpiwrite;
}



int hpia_w(unsigned int val)//将430即将访问DSP的地址写入HPIA寄存器
{ 
  P4DIR = 0xFF; //output 
  hpic_w(0x1919);//430将HPIA写入DSP的高7位地址
  //hpia <- 0x00
  P5OUT |= BIT4;  //~HDS1=1
  P5OUT &= ~(BIT5+BIT7);//HCNT0=HR/~W=0
  P5OUT |= BIT6;//HCNT1=1
  P5OUT &= ~BIT3; //HBIL=0
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = 0x00;
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpiaw = HPI_chkrdy();
  if(re_hpiaw!=0) return -1;
  P5OUT |= BIT3;  //HBIL=1
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = 0x00;
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpiaw = HPI_chkrdy();
  if(re_hpiaw!=0) return -1;
  
  P4DIR = 0xFF; //output
  hpic_w(0x0909);//430将HPIA写入DSP的低16位地址
  //hpia <- val
  P5OUT |= BIT4;  //~HDS1=1
  P5OUT &= ~(BIT5+BIT7);//HCNT0=HR/~W=0
  P5OUT |= BIT6;//HCNT1=1
  P5OUT &= ~BIT3; //HBIL=0
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = (char)(val-1);
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpiaw = HPI_chkrdy();
  if(re_hpiaw!=0) return -1;
  P5OUT |= BIT3;  //HBIL=1
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = ((val-1)>>8);
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpiaw = HPI_chkrdy();
  if(re_hpiaw!=0) return -1;

  return 0;
}

int hpid_w_inc(unsigned int val)
{
  P4DIR = 0xFF; //output
  //hpid <- val
  P5OUT |= BIT4;  //~HDS1=1
  P5OUT &= ~(BIT5+BIT6); //HCNT1=HR/~W=0
  P5OUT |= BIT7; //HCNT0=1
  P5OUT &= ~BIT3; //HBIL=0
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = (char)val;
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpidwinc = HPI_chkrdy();
  if(re_hpidwinc!=0) return -1;
  P5OUT |= BIT3;  //HBIL=1
  P5OUT &= ~BIT4;  //~HDS1=0
  P4OUT = (val>>8);
  for(delay=0;delay<10;delay++);
  P5OUT |= BIT4; //~HDS1=1
  re_hpidwinc = HPI_chkrdy();
  if(re_hpidwinc!=0) return -1;
                                                                                            
  return 0;
}

unsigned int hpid_read(void)//430读取HPID寄存器数据,HPIA寄存器值自动加1
{
  unsigned int value=0, tmp;
  
  P4DIR = 0x00; //input  
  //hpic <- val
  P5OUT |= BIT4;  //~HDS1=1
  P5OUT &= ~BIT6;//HCNT1=0
  P5OUT |= (BIT7+BIT5);//HCNT0=HR/~W=1
  P5OUT &= ~BIT3; //HBIL=0
  P5OUT &= ~BIT4;  //~HDS1=0
  for(delay=0;delay<10;delay++);
  tmp = P4IN;
  value=tmp;
  P5OUT |= BIT4; //~HDS1=1
  re_hpidrnew = HPI_chkrdy();
  if(re_hpidrnew!=0) return 1;
  P5OUT |= BIT3;  //HBIL=1
  P5OUT &= ~BIT4;  //~HDS1=0
  for(delay=0;delay<10;delay++);
  tmp = P4IN;
  value|= (tmp<<8);
  P5OUT |= BIT4; //~HDS1=1
  re_hpidrnew = HPI_chkrdy();
  if(re_hpidrnew!=0) return 1;

  return value;
}

int hpi_run(void)
{
  int re_run;
  re_run = hpia_w(0x7e);
  if(re_run!=0) return -1;
  re_run = hpid_w_inc(0x0);
  if(re_run!=0) return -1;

  re_run = hpia_w(0x7f);
  if(re_run!=0) return -1;
  re_run = hpid_w_inc(DSP_ENTRY);
  if(re_run!=0) return -1;
  
  //if(P2IN&0X2) return -1;
  return 0;
}


//-------------------------- Pulse_calculate-------------------------------------
void Pulse_calculate(void)
{
//  number = 20;
  
  P1SEL |= BIT2;                          // P1.2 option select
  P1DIR = 0x1B;                           // P1.2 vortex pulse signal input                       
  CCTL1 = CM_1 + CCIS_0 + CAP + CCIE;     // Capture on rising edge, CCI1A, CAP
  TACTL =TASSEL_2 + ID_3 + MC_2 + TACLR;  // SMCLK, 1/4Smclk = 500KHz, Continuous mode, clear
  _EINT();                       // 打开全局中断  
  
  while(sysflag==1)
  {
     _BIS_SR(LPM1);            // Enter LPM1 w/ interrupt
     
     while(Taflag==1)
     {
        _DINT();
        
        for(int i=1;i<number+1;i++)  // calculate average f
        {
	  sum+=cap[i];
        }
        cap_n=sum/number;
        f = 250000.0/cap_n;
        if(f>500)                    // change cap number
        {
          number=100;
        }
        else if(f<300)
        {
          number=20;
        }
        else
        {
          number=50;
        }
        
        re2=(unsigned long int)(f * 1000);
        view=re2;                   // LCD display frequency         
        int_ascii(); 
        updisp();  
     //   Output(f);                // Pulse output     
   
        if(f<DN100_gas_lowlimit)
        {
           sysflag=2;
           TACTL|=MC_0;
           Taflag=0;
           sum=0;
           cap_cnt=0;
           break;
        }
        else
        {
          sum=0;
          cap_cnt=0;
          Taflag=0;
          CCTL1 = CM_1 + CCIS_0 + CAP + CCIE;     // Capture on rising edge, CCI1A, CAP 
          _EINT();
        }
     } // while(Taflag==1)

  }
}

//***********---------------- Pulse output--------------**********************
void Output(float f)                       // 脉冲输出子程序(脉冲输出函数)
{  
   long int a;
   P4DIR |= 0x01;                          // P4.0 output
   P4SEL |= 0x01;                          // P4.0 option select
   TBCCTL0 = OUTMOD_4;                     // CCR0 toggle mode
   if(f>100)
   { 
      a=2000000/(2*f);
      TBCTL = TBSSEL_2 + MC_1;             // SMCLK, up mode
   }
   else
    { 
      a=32768/(2*f);
     TBCTL = TBSSEL_1 + MC_1;              // ACLK, up mode
    }
   TBCCR0 = a-1;
}


/*-----------ADC12 initialize, Single Channel Rpt Mode, TA1 as Sample Trigger at 1000Hz(1ms)----------*/     
void ADC12_Init(void)
{
   P6SEL |= 0x01;                            // select A0 as input
   P6DIR &=~BIT0;
   ADC12CTL0 = ADC12ON + SHT0_1;             // Setup ADC12
   ADC12CTL1 = SHP + CONSEQ_2 + SHS_1;       // Timer triggers sampling, ADC12OSC
   ADC12MCTL0 = 0x00;                        // choose A0 as input
   ADC12IE = 0x0001;                         // Enable ADC12IFG.0
   
   P2SEL |= BIT3;                            // Set for TimerA1
   P2DIR |= BIT3;

   TACCR0 = 32;                              // Init TACCR0 w/ sample prd=CCR0+1
   TACCR1 = 16;                              // Trig for ADC12 sample & convert
   TACCTL1 = OUTMOD_3;                       // Set/reset
   TACTL = TACLR + TASSEL_1;                 // ACLK, clear TAR
}

//************------------------ FFT calculate-------------**********************
void FFT_calculate(void)
{
   HPI_Init();
   re_cal = hpi_write(DSP_ENTRY, (char*)dspcode, DSP_MAXSIZE);  //  write dspcode
    
   ADC12_Init();
   
   ADC12CTL0 |= ENC;              // Start conversion
   TACTL |= MC_1;                 // Start TimerA
   _EINT();                       // 打开全局中断
   
   dz=0x6000;
   re_cal = hpia_w(dz);//write data address
    
   while(1)
   { 
      _BIS_SR(LPM3);             // Enter LPM3 w/interrupt
       
      if(Rectangle_Windows)     // add Rectangle_Windows to ADvalue
      {
         ADValue = ADvalue;   
      }
      else                       // add Hanning_Windows to ADvalue
      {
         ADfloat = (float)ADvalue/4096.0*3.3;
         ADtemp = ADfloat * Hanning_Windows[AD_cnt];
         ADValue = ADtemp*4096.0/3.3;
      }
      
      if(AD_cnt<1024)
      {
        re_cal = hpid_w_inc(ADValue);
           
        if(AD_cnt<=9)
          {
             TEMP[AD_cnt]=ADValue;
          }
        AD_cnt++;         
      }
      else                            // >1024 FFT start DSP 
      {
        ADC12CTL0 &=~ENC;             // ENC=0时可以配置 
        TACTL &=~MC_1;                // Stop TimerB
        AD_cnt=0;
    
        re_cal = hpi_run();  
        for(long int i=0;i<40000;i++) i=i;
        
        dz=0x7001;  
        re_cal = hpia_w(dz); 
        
        for(int i=0;i<8;i++)
        {
           result[i/2]=hpid_read();
           i++;
        }
        result_f=result[0];
        power_spc1=(unsigned long int)result[1];
        power_spc2=(unsigned long int)result[2];
        power_spc3=(unsigned long int)result[3];
             
        result_f=result_f-1;
        re2=(unsigned long int)result_f;
        re2=re2*1000;
        fre1=re2;
          
        if(Rectangle_Windows)          //  Rectangle_Windows power-spectrum correction
        {
           if(power_spc1<=power_spc3)
           {
              re2 = power_spc2 + power_spc3;
              fre2 = power_spc3*1000/re2;
              fre = fre1 + fre2;
           }
           else
           {
              re2 = power_spc2 + power_spc1;
              fre2 = power_spc1*1000/re2;
              fre = fre1 - fre2;
           }
        }
        else                           //  Hannning_Windows power-spectrum correction
        {
           if(power_spc1<=power_spc3)
           {
              re2 = 2*power_spc3 - power_spc2;
              fre2 = re2*1000/(power_spc3 + power_spc2);
              fre = fre1 + fre2;
           }
           else
           {
              re2 = 2*power_spc1 - power_spc2;
              fre2 = re2*1000/(power_spc2 + power_spc1);
              fre = fre1 - fre2;
           }
        }    
        
        view=fre;
        int_ascii();
        updisp();
        
        f = fre/1000.0;
    //    Output(f); 
        if(f>DN100_gas_lowlimit)
        {
          sysflag=1;
          ADC12CTL0=0;
          P2SEL&=~BIT3;      
          CCR0=0;
          CCR1=0;
          CCTL1=0;
          TACTL=0;
        }
            
        break;

      }
   }
}


//------------------- Timer A0 interrupt service routine------------------------
#if VERSION>126
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A (void)
#else
interrupt[TIMERA1_VECTOR] void Timer_A(void)
#endif
{
    CCTL1&=~CCIFG;                          // clear CCI1A interrupt flag
    Newcapture = TACCR1;                    // Get current captured Pulse 
    Compare = Newcapture - Oldcapture;         // Pulse difference
    Oldcapture = TACCR1;                    // Save current captured Pulse
    cap[cap_cnt]=Compare;
    cap_cnt++;                                        
    if(cap_cnt>number)                                                                                                       
    { 
      CCTL1 = 0;
      Taflag= 1;
   }

    LPM1_EXIT;                              // Exit LPM1                
}


/**************************************************************************************
函数原型: void ADC12(void)
函数功能: ADC12中断服务子程序,将采样结果存放到变量ADvalue中
调用函数:无
入口参数: 无
出口参数: 无
***************************************************************************************/ 
#if VERSION>126
#pragma vector=ADC_VECTOR
__interrupt void ADC12(void)
#else
interrupt[ADC_VECTOR] void ADC12(void)
#endif
{
   ADvalue = ADC12MEM0;             // Move results
   
   LPM3_EXIT;//Exit LPM3
}

⌨️ 快捷键说明

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