?? 89c52電流采集.c
字號:
_MDEL_=0; //small編譯模式
/*****************文件包括******************/
#include<reg52.h>
#include<absacc.h>
#include <intrins.h>
/*****************宏定義******************/
#define uchar unsigned char
#define uint unsigned int
#define tranad 0X7000 //傳輸數(shù)據(jù)存放在ram中的首地址
#define r6264 0X8000 //6264首地址
#define fifo1 XBYTE[0XC000] //fifo1 地址
#define fifo2 XBYTE[0XE000] //fifo2 地址
/*****************函數(shù)說明******************/
/*****************intrins.h內(nèi)包括的函數(shù)******************/
void _nop_(void); //空操作函數(shù)
unsigned char _cror_(unsigned char val,unsigned char n);//右移函數(shù)
/*****************自定義函數(shù)******************/
void delay(uint time); //延時時間為(time*2+2)
void initsys(void); //系統(tǒng)初始化
void resetfifo(void); //復位FIFO
void resetram(void); //ram初始化
void writeram(uchar ctime,uint dnumw); //把從FIFO讀的數(shù)據(jù)寫到RAM
void startad(void); //跟下降沿取得同步就啟動采集
void averdata(uchar avertime,uint dnuma); //疊加后取平均
void mazhizhuanhuan(uint dnum,uint datanum); //把從000-fff編碼的數(shù)據(jù)轉換成從800-7ff的編碼
void readram(uint qsaddr); //把從RAM的數(shù)據(jù)傳送給PC機
void transmitdata(void); //傳送ASCII緩沖區(qū)的內(nèi)容給PC機
void startadt(void); //采集電流下降沿,計算下降時間
void mazhinihuan(uint dnumn,uint datanumn); //碼制逆轉換
void avcurret(void); //取平均電流并傳數(shù)
void timecm(void); //關斷時間計算程序
/*****************管腳定義*******************/
sbit AD_START=P1^0; //ad采集信號
sbit FIFO_RS=P1^1; //FIFO 復位信號
sbit LEDRED=P1^2; //紅燈顯示
sbit LEDGREED=P1^3; //綠燈顯示
sbit PC_TEM=P1^4; //通信選擇信號
sbit TBOUT=P1^5; //同步信號
sbit ASRESET=P1^6; //fifo輔助復位信號
sbit MODE=P1^7; //模式選擇
sbit key=P3^3; //按鍵信號
sbit elect_r=P3^4; //反饋電阻的選擇(放大倍數(shù)選擇)
/*****************變量定義***************************/
uchar data yxxhtime; //采集次數(shù)
/*****************主函數(shù)***************************/
void main(void)
{
mainstart:
AD_START=1;
SP=0x60;
yxxhtime=0;
initsys();
resetfifo(); //FIFO復位
startad(); //與tem_單片機通信
/*****************測量電流和關斷時間******************/
for(yxxhtime=0;yxxhtime<14;yxxhtime++) //直到有效的循環(huán)次數(shù)為14時才停止采集與疊加
{
resetfifo(); //FIFO復位
startad(); //開始采集
writeram(yxxhtime,200); //寫存儲器
}//end for 14 times
averdata(yxxhtime,100); //取平均值
avcurret();
mazhinihuan(1000,1);
readram(1000);
/*****************測量關斷時間******************/
for(yxxhtime=0;yxxhtime<14;yxxhtime++)
{
resetfifo(); //FIFO復位
startadt(); //開始采集
writeram(yxxhtime,1000); //寫存儲器
}// end for
averdata(yxxhtime,500);
timecm();
transmitdata();
goto mainstart; //循環(huán)
}
/*****************主函數(shù)結束******************/
/*****************子函數(shù)定義******************/
void delay(uint time) //延時時間為(time*2+2)
{
uint data s;
for(s=0;s<time;s++)
_nop_();
}
void initsys(void) //系統(tǒng)初始化
{
P0=0xff; ////////
P1=0xff; //可有//
P2=0xff; //可無//
P3=0xff; ////////
PC_TEM=0;
AD_START=1;
TR0=TR1=0;
TF0=TF1=0;
PC_TEM=0; //選擇和tem控制板通訊
TMOD=0x21; //定時器0方式1,定時20ms左右
TH0=0xdd; //定時20ms
TL0=0x00;
PCON=0x00;
TH1=0xf4;//fd;//fa; //波特率為2400//9600//4800
TL1=0xf4;
TR1=1; //啟動定時器1
SCON=0x40; //設置串行口為10位異步收發(fā),不允許接收
TI=0;
}
void resetfifo(void) //復位FIFO
{
FIFO_RS=1;
delay(5);
ASRESET=0;
delay(5); //復位fifo
AD_START=1;
delay(5); //fifo復位的時候,R,W都要是高電平
FIFO_RS=0;
delay(5);
delay(5);
delay(5);
FIFO_RS=1;
delay(5);
delay(5);
ASRESET=1;
delay(5);
delay(5);
}
/*****************采集程序定義******************/
/*****************采集程序1******************/
void startad(void)
{
TBOUT=1; //檢測同步信號
do{_nop_();}while(TBOUT==0); //0
//TBOUT=1;
do{_nop_();}while(TBOUT==1); //1 //上升沿采集
delay(150); //150 //38ms
AD_START=0; //開始采集
delay(3200);
AD_START=1; //采集結束
}
/*****************采集程序2******************/
void startadt(void) //用于采集下降沿時間
{
TBOUT=1; //檢測同步信號
do{;}while(TBOUT==1); //1
//TBOUT=1;
do{;}while(TBOUT==0); //0 //下降沿開始采集
AD_START=0; //開始采集
delay(3200);
AD_START=1; //采集結束
}
/*****************寫ram程序******************/
void writeram(uchar ctime,uint dnumw) //把從FIFO讀的數(shù)據(jù)寫到RAM (讀了500個數(shù)據(jù))
{
uint data i;
uchar data databuf;
_nop_();
databuf=fifo1;
databuf=fifo2; //把fifo中前2個無效數(shù)據(jù)丟棄
databuf=fifo1;
databuf=fifo2;
if(ctime==0)
{
for(i=0;i<dnumw;i++)
{
databuf=fifo2;
XBYTE[i]=databuf;
i++;
databuf=fifo1;
_nop_();
XBYTE[i]=databuf;
_nop_();
}//end for
mazhizhuanhuan(0,dnumw/2); //轉換
}//end if
else
{
for(i=0;i<dnumw;i++)//for 2
{
databuf=fifo2;
_nop_();
XBYTE[i+1000]=databuf;
i++;
databuf=fifo1;
_nop_();
XBYTE[i+1000]=databuf;
_nop_();
}//end for2
mazhizhuanhuan(500,dnumw/2); //轉換
for(i=0;i<dnumw/2;i++) //for 3 //疊加
{
int data number1,number2;
number1=XWORD[i];
number2=XWORD[i+500];
number1=number1+number2;
XWORD[i]=number1;
_nop_();
}//end for3
}//end else
}
/*****************碼制轉換程序******************/
void mazhizhuanhuan(uint dnum,uint datanum)
{
uint data i=0;
uint data datatemp;
datatemp=((XWORD[2+dnum]+XWORD[4+dnum]+XWORD[6+dnum]+XWORD[8+dnum])/4);
if((datatemp&0x0fff)>0x0800) //整體是負值
{ for(i=0;i<datanum;i++)
{
datatemp=XWORD[i+dnum];
datatemp=(0x1000-datatemp);
if((datatemp&0x0fff)<0x0800)
{
datatemp=datatemp|0x0800;
XWORD[i+dnum]=datatemp&0x0fff;
}//end if
else
{
datatemp=datatemp&0x07ff;
XWORD[i+dnum]=datatemp&0x0fff;
}//end else
}//end for
}//end if
else //整體是正值
{
for(i=0;i<datanum;i++)
{
datatemp=XWORD[i+dnum];
if((datatemp&0x0fff)<0x0800)
{
datatemp=datatemp|0x0800;
XWORD[i+dnum]=datatemp&0x0fff;
}//end if
else
{
datatemp=datatemp&0x07ff;
XWORD[i+dnum]=datatemp&0x0fff;
}// end else
}//end for
}//end else
delay(2);
}
/*****************電壓計算程序******************/
void readram(uint qsaddr) //把從RAM的數(shù)據(jù)計算并存入到指定空間
{
uint data temp1;
uint data templong;
// uint data i;
float data fdata;
_nop_();
// for(i=0;i<datalong;i++)
// {
temp1=XWORD[qsaddr];
if(temp1>=0x0800) //判斷正負號
{
XBYTE[tranad+0]='-';
temp1=0x1000-temp1;
}
else
XBYTE[tranad+0]=' '; //dd.d
fdata=temp1; //把十六進制數(shù)變換成實際電壓值
fdata=fdata*100*140/4096; //1000*10/4096;//100*125/4096; //19 1000*10/4096;// //10
XBYTE[tranad+8]='.';
templong=fdata;
XBYTE[tranad+6]=templong/1000+0x30;
if(XBYTE[tranad+6]==0x30)
XBYTE[tranad+6]=' ';
templong=templong%1000;
XBYTE[tranad+7]=templong/100+0x30;
templong=templong%100;
XBYTE[tranad+9]=templong/10+0x30;
templong=templong%10;
XBYTE[tranad+10]=templong+0x30;
// }
}
/*****************數(shù)據(jù)傳輸程序******************/
void transmitdata(void) //傳送ASCII緩沖區(qū)的內(nèi)容給tem控制板
{ uchar data bufs;
uchar data i=0;
SBUF=0x0f;
_nop_();
while(TI==0);TI=0;
SBUF=0x00;
_nop_();
while(TI==0);TI=0;
for(i=1;i<11;i++)
{ _nop_();
bufs=XBYTE[tranad+i];
bufs=bufs&0xf0;
bufs=_cror_(bufs,4);
SBUF=bufs;
_nop_();
while(TI==0);TI=0;
bufs=XBYTE[tranad+i];
SBUF=bufs&0x0f;
_nop_();
while(TI==0);TI=0;
}
}
/*****************數(shù)據(jù)平均程序******************/
void averdata(uchar avertime,uint dnuma)
{
uint data i=0;
uint data k=0;
// uchar data j=avertime;
// delay(2);
for(i=0;i<dnuma;i++)
{ k=XWORD[i];
XWORD[i]=(k/avertime)&0x0fff;
}
}
/*****************碼制逆轉換程序******************/
void mazhinihuan(uint dnumn,uint datanumn)
{ uint data i,dtemp;
for(i=0;i<datanumn;i++)
{
dtemp=XWORD[i+dnumn];
if(dtemp>=0x0800)
{
XWORD[i+dnumn]=(dtemp&0X07ff);
}//end if
else
{
XWORD[i+dnumn]=(dtemp|0x0800)&0x0fff;
}//end else
}//end for
}//end mazhinihuan
/*****************電流平均程序******************/
void avcurret(void)
{
//uint data cucount=0;
//uint data cucount1=0;
float data avdata=0;
uchar data cutime;
_nop_();
//mazhizhuanhuan(0,14);
for(cutime=0;cutime<100;cutime++)
{
avdata=avdata+XWORD[cutime];
}
XWORD[1000]=avdata/100;
} //end avcurrent
/*****************關斷時間計算程序******************/
void timecm(void)
{
// char data temp3;
uint data i,timedata;
i=0;
while((XWORD[i]>0x0808)&&(i<500))
{
i++;
}//end while
if((i>499)||(XBYTE[tranad+6]==' '&&XBYTE[tranad+7]==0x30&&XBYTE[tranad+9]<0x32))
{
//overtime=0x0f0f;
timedata=0x0000;
}//end if i>499
else
{
//overtime=0x0505;
timedata=i;
}//end else
XBYTE[tranad+1]=timedata/100+0x30;
//temp3=XBYTE[tranad+1];
if(XBYTE[tranad+1]==0x30)
XBYTE[tranad+1]=' ';
timedata=timedata%100;
XBYTE[tranad+2]=timedata/10+0x30;
if((XBYTE[tranad+1]==' ')&&(XBYTE[tranad+2]==0x30))
XBYTE[tranad+2]=' ';
timedata=timedata%10;
XBYTE[tranad+3]=timedata+0x30;
XBYTE[tranad+4]='.';
XBYTE[tranad+5]=0x30;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -