📄 09.04pm_dn100_gas.c
字号:
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 + -