📄 dn100_gas.c
字号:
//***************************************************************************************************
// MSP430F149
// ______________________
// /|\| XT2IN|-
// | | | 4MHz
// --|RST XT2OUT|-
// | |
// sine_sig-->|P6.0/A0 XIN|-
// pulse_sig-->|P1.2/CCIA1 | 32768HZ
// | XOUT|-
// KEY1(>)-->|P1.5/TA0 |
// KEY1(F)-->|P1.6/TA1 P4.0/TB0|-->MCU_OUT
// KEY1(^)-->|P1.7/TA2 |
// | |
// DSP_nRST<-->|P2.0/ACLK P5.0 |<-->HD0
// nHINT<-->|P2.1/TAINCLK P5.1 |<-->HD1
// HCNTL0<-->|P3.0 P5.2 |<-->HD2
// HCNTL1<-->|P3.1 P5.3 |<-->HD3
// HR/~W <-->|P4.4 P5.4 |<-->HD4
// HDS<-->|P4.5 P5.5 |<-->HD5
// HBIL<-->|P3.2 P5.6 |<-->HD6
// HRDY<-->|P4.7 P5.7 |<-->HD7
// | |
// AVCC<--|VeREF+ P6.7/A7 |-->LCD_~CS
// | P6.6/A6 |-->LCD_~WR
// | P6.5/A5 |-->LCD_DATA
// | |
// | |
//******************************************************************************************************
/*******************************************************************************************************
Attention: The CPU is MSP430F149 [ACLK=32K, MCLK=XT/2=2MHz, SMCLK=XT/2=2MHz]
Function: When power-on, 430 calculate f through CAP(TA CCIA1). When f below 40Hz, FFT instead
of Pulse-in.
LCD display and pulse output.
Updated for IAR Embedded Workbench Version: 3.40
Author: XingJuan
latest changed: 2006.09.05
********************************************************************************************************/
#include <msp430x14x.h>
#include "dspcode-idle3.h"
//#include "Han_win.h"
#define VERSION 340
#define DN100_gas_lowlimit 100 // DN100 gas lower limit f = 40Hz
#define Rectangle_Windows 1 // Rectangle_Windows = 1
#define DSP_ENTRY 0x0300 //EHPI word address,so 0x0100/2=0x0080
#define DSP_MAXSIZE 0x3600 // max 0x4000(16k) bytes
//char sysflag; //system flag
char sysflag;
int delay;
// Pulse in-out
int cap_cnt = 0, number = 20;
unsigned int Compare, Newcapture, Oldcapture = 0;
char Taflag=0;
unsigned long int sum;
float cap_n;
float cap[301];
float f = 0.0;
signed char f_cnt = 5;
float fsum[6];
float f_sum, f_ave;
//FFT calculate variable definition
unsigned int result_f, dz, AD_cnt, ADvalue, TB_cnt, ADValue;
unsigned long int power_spc1, power_spc2, power_spc3;
//unsigned int TEMP[10];
unsigned int result[4];//存DSP得出的涡街频率值和对应的功率谱最大值及其左右两个谱值
unsigned int fre, fre1, fre2;
float ADtemp, ADfloat;
//HPI variable definition
int res, re_init, re_hpiinit, re_hpicw, re_hpiwrite, re_hpiaw, re_hpidwinc, re_hpidrnew, re_cal;
unsigned int re_add,add_value;
//lcd variable definition
int addr_buffer, buffer, count;
unsigned long int view;
unsigned long int re2;
char asc[8];//整型数数对应的8位ASCII码数组
char dis_up[6];//上排显示寄存器
char dis_down[8];//下排显示寄存器
const char addr_up[6]={0x0F,0x11,0x13,0x15,0x17,0x19};
const char addr_down[8]={0x0A,0x08,0x06,0x04,0x02,0x00,0x1C,0x1E};
const char downseg[11]={0xEB,0x60,0xC7,0xE5,0x6C,0xAD,0xAF,0xE0,0xEF,0xED,0x00};
const char upseg[11]={0xD7,0x06,0xE3,0xA7,0x36,0xB5,0xF5,0x07,0xF7,0xB7,0x00};
//delay subprogram
void msdelay(int);//msdelay: 1ms * n
//initialization program
void MSP430Init(void);//系统初始化子程序
//display program
void Disp_Init(void);
void wrcommand(void); // 写命令
void wr_act(void); // 上升沿控制
void wrdata(void); // 写数据
void int_ascii(void); // 将整型数转化为用于显示的ASC
void updisp(void); // 液晶上排显示程序
void downdisp(void); // 下排液晶显示程序
//HPI program
int HPI_Init(void);//上电后430初始化DSP的HPI接口
int HPI_reset(void);//430 offers a 200ms reset to DSP untill testing the HDRY=1
int HPI_chkrdy(void);// check the HPI ready?
//int hpi_write(unsigned long, unsigned short*, unsigned long);//430通过HPI口向DSP装载DSP的运行代码
int hpi_write(unsigned int, unsigned int*, unsigned long);//430通过HPI口向DSP装载DSP的运行代码
int hpi_run(void);
int hpic_w(unsigned int);
int hpia_w(unsigned int);//将430即将访问DSP的地址写入HPIA寄存器
unsigned int hpia_R(void);
int hpid_w_autoinc(unsigned int);
unsigned int hpid_R_autoinc(void);//430读取HPID寄存器数据,HPIA寄存器值自动加1
//system subprogram
void Pulse_calculate(void);
void FFT_calculate(void);
void Output(float);
//ADC12 initialization program
void ADC12_Init(void);
/*---------------------主程序启动-----------------------*/
void main(void)
{
WDTCTL=WDTPW+WDTHOLD; // STOP WDT
MSP430Init();
// _EINT(); // 打开全局中断
while(1)
{
switch(sysflag)
{
case 1:
Pulse_calculate();
break;
case 2:
FFT_calculate();
break;
default:
break;
}
}
}
//---------------------system initialization----------------------------------
void MSP430Init(void)
{
int i;
/*-------------------------------Osc initialize-------------------------
Purpose:
ACLK <- XT1, DIVA =1
MCLK <- XT2, DIVM =2
SMCLK <- XT2, DIVS =2
Note: XT1=32768Hz, XT2 = 4MHz
----------------------------------------------------------------------------*/
IE1 =0x00; // disabel Oscillator fault interrupt
BCSCTL1=0x00; // set XT2ON
BCSCTL2=SELM_2+DIVM_0+DIVS_0+SELS; // MCLK=SMCLK=2MHz
// 等待时钟源转换完成
do{
IFG1 &= ~OFIFG;
for(i=0;i<100;i++); // delay 50uS
}while(IFG1&OFIFG); // 查OSCFault,为0时转换完成
/*---------------port initialize---------------*/
// P1IES &= 0x1F; // P1.5~P1.7 key input interrupt by L-H drop
// P1IE |= 0xE0; // enable interrupt
// P1IFG &= 0x1F; // clear interrupt flag
P1DIR = 0;
P1DIR|= BIT0+BIT4;
P1SEL = BIT0+BIT4;
P2DIR = 0xFC; // P2.7:MCU_OUT output
// P2.0:DSPnRST, P2.1:nHINT(DSP向430申请中断) are input
P3DIR = 0xFF; // HD8-HD15
P3OUT = 0;
P4DIR = 0xFF; // HD0-HD7
P4OUT = 0;
P5DIR = 0xFE; // P5.0 HRDY, P5.4 HDS, P5.5 HRnW
P5OUT = 0xF8; //HBE0=0,HBE1=O
P6DIR = 0xFE; // P6.5=DATA; P6.6=~WR; P6.7=~CS
// P6.0:vortex sine-signal input
P6OUT|= 0xFE;
P6DIR&=~BIT0;
P6SEL = BIT0;
/*---------------LCD initialize---------------*/
Disp_Init();
view=0;
int_ascii();
updisp();
downdisp();
/*---------------system variable initialize---------------*/
sysflag=2; // clear system flag
}
void msdelay(int n) //mdelay: 1ms * n(MCLK: 4MHz)
{
unsigned int i, mdelay;
for(i=0;i<n;i++)
for(mdelay=0; mdelay<200; mdelay++);
}
int HPI_Init(void)
{
P5DIR &= ~BIT0; // HRDY input
re_hpiinit = HPI_reset(); // reset DSP for 20ms
if(re_hpiinit!=0) return -1;
/*----------------------BIT3=HINT=1->此位是DSP向430申请中断位,430通过向其写0实现0--------------------*/
re_hpiinit = hpic_w(0x0002); // 向HPIC写入09字节两遍
if(re_hpiinit!=0) return -1;
return 0;
}
int HPI_reset(void) // 430 offers a 20ms reset to DSP untill testing the HDRY=1
{
int j=0;
P2DIR|=BIT0; // P2.0:DSP_nRST=OUTPUT
do{
P2OUT|=BIT0;
msdelay(50);
P2OUT&=~BIT0; // reset DSP
msdelay(200); // delay: 0.1ms*20=20ms
P2OUT|=BIT0;
msdelay(50);
// wait untill HRDY=1
if((P5IN&BIT0)!=0) break;
j++;
}while(((P5IN&BIT0)==0)&&(j<10));
if(j==10)
return -1;
else
return 0;
}
int hpic_w(unsigned int val)
{
P4DIR = 0xFF; //output1
P3DIR = 0xFF; //output
P5OUT |= BIT4; //~HDS=1
P5OUT &= ~(BIT5+BIT6+BIT7);//HCNT0=HCNT1=HR/~W=0
P5OUT &= ~BIT4; //~HDS=0
P4OUT = val&0xff; //low 8 bit
P3OUT = (char)(val>>8); //high 8 bit
for(delay=0;delay<20;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 int addr, unsigned int* buf, unsigned long len)
{
unsigned long i;
re_hpiwrite = hpia_w(addr);
if(re_hpiwrite!=0) return -1;
for(i=0; i<len; i++)
{
re_hpiwrite = hpid_w_autoinc(*(unsigned int*)(&buf[i]));
if(re_hpiwrite!=0) break;
_NOP();
}
return 0;
}
int hpia_w(unsigned int val)//将430即将访问DSP的地址写入HPIA寄存器(000060h~003FFFh)
{
P4DIR = 0xFF; //output
P3DIR = 0xFF; //output
P5OUT |= BIT4; //~HDS1=1
P5OUT &= ~(BIT5+BIT6);//HCNT0=HR/~W=0
P5OUT |= BIT7;//HCNT1=1
P5OUT &= ~BIT4; //~HDS1=0
P4OUT = val&0xff; //low 8 bits
P3OUT = (char)(val>>8); //high 8 bits
for(delay=0;delay<20;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;
}
unsigned int hpia_R(void)//将430即将访问DSP的地址写入HPIA寄存器(000060h~003FFFh)
{
unsigned int value=0, tmp=0;
P4DIR = 0; //output
P3DIR = 0; //output
P5OUT |= BIT4; //~HDS1=1
P5OUT &= ~(BIT6);//HCNT0=HR/~W=0
P5OUT |= BIT7+BIT5;//HCNT1=1
P5OUT &= ~BIT4; //~HDS1=0
value=P4OUT;
tmp=P3OUT;
add_value=(tmp<<8)|value;
for(delay=0;delay<20;delay++);
P5OUT |= BIT4; //~HDS1=1
re_hpiaw = HPI_chkrdy();
//if(re_hpiaw!=0) return -1;
return add_value;
}
int hpid_w_autoinc(unsigned int val)
{
P4DIR = 0xFF; //output
P3DIR = 0xFF; //output
//P5OUT&=~(BIT1+BIT2);
P5OUT |= BIT4; //~HDS1=1
P5OUT &= ~(BIT5+BIT7); //HCNT1=HR/~W=0
P5OUT |= BIT6; //HCNT0=1
P5OUT &= ~BIT4; //~HDS1=0
P4OUT = val&0xff; //low 8 bits
P3OUT = (char)(val>>8); //high 8 bits
for(delay=0;delay<20;delay++);
P5OUT |= BIT4; //~HDS1=1
re_hpidwinc = HPI_chkrdy();
if(re_hpidwinc!=0) return -1;
//P5OUT|= BIT2;
//msdelay(1);
//P5OUT&=~BIT2;
return 0;
}
unsigned int hpid_R_autoinc(void)//430读取HPID寄存器数据,HPIA寄存器值自动加1
{
unsigned int value=0, tmp=0;
P4DIR = 0x00; //input
P3DIR = 0x00; //input
P5OUT |= BIT4; //~HDS1=1
P5OUT &= ~BIT7;//HCNT1=0
P5OUT |= (BIT6+BIT5);//HCNT0=HR/~W=1
P5OUT &= ~BIT4; //~HDS1=0
for(delay=0;delay<20;delay++);
tmp = P3IN;
value=P4IN;
value=(tmp<<8)|value;
P5OUT |= BIT4; //~HDS1=1
re_hpidrnew = HPI_chkrdy();
if(re_hpidrnew!=0) return 1;
return value;
}
int hpi_run(void) //excute the program
{
int re_run;
re_run = hpia_w(0x0061); //the address where DSP will begin to run
if(re_run!=0) return -1;
re_run = hpid_w_autoinc(0x0400);//0x0100/2=0x0080
if(re_run!=0) return -1;
//msdelay(2);
re_run = hpia_w(0x0060); //write no zero data to bit15~8 in order to run the program
if(re_run!=0) return -1;
re_run = hpid_w_autoinc(0xFF00);//300并不是一定的,只要保证第9位(从有数)以上不为零即可
if(re_run!=0) return -1;
return 0;
}
//************------------------ FFT calculate-------------**********************
void FFT_calculate(void)
{
//HPI_Init();
//re_cal = hpi_write(DSP_ENTRY, (unsigned short*)dspcode, DSP_MAXSIZE); // write dspcode
re_cal = hpi_write(DSP_ENTRY, (unsigned int*)dspcode, DSP_MAXSIZE); // write dspcode
re_hpiinit = hpic_w(0x0000); // 向HPIC写入00字节
ADC12_Init();
ADC12CTL0 |= ENC; // Start conversion
TACTL |= MC_1; // Start TimerA
_EINT(); // 打开全局中断
dz=0x3A00;
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;
}
if(AD_cnt<1024)
{
AD_cnt++;
}
else // >1024 FFT start DSP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -