📄 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 //传输数据存放在ram中的首地址
#define r6264 0X8000 //6264首地址
#define fifo1 XBYTE[0XC000] //fifo1 地址
#define fifo2 XBYTE[0XE000] //fifo2 地址
/*****************函数说明******************/
/*****************intrins.h内包括的函数******************/
void _nop_(void); //空操作函数
unsigned char _cror_(unsigned char val,unsigned char n);//右移函数
/*****************自定义函数******************/
void delay(uint time); //延时时间为(time*2+2)
void initsys(void); //系统初始化
void resetfifo(void); //复位FIFO
void resetram(void); //ram初始化
void writeram(uchar ctime,uint dnumw); //把从FIFO读的数据写到RAM
void startad(void); //跟下降沿取得同步就启动采集
void averdata(uchar avertime,uint dnuma); //叠加后取平均
void mazhizhuanhuan(uint dnum,uint datanum); //把从000-fff编码的数据转换成从800-7ff的编码
void readram(uint qsaddr); //把从RAM的数据传送给PC机
void transmitdata(void); //传送ASCII缓冲区的内容给PC机
void startadt(void); //采集电流下降沿,计算下降时间
void mazhinihuan(uint dnumn,uint datanumn); //码制逆转换
void avcurret(void); //取平均电流并传数
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; //反馈电阻的选择(放大倍数选择)
/*****************变量定义***************************/
uchar data yxxhtime; //采集次数
/*****************主函数***************************/
void main(void)
{
mainstart:
AD_START=1;
SP=0x60;
yxxhtime=0;
initsys();
resetfifo(); //FIFO复位
startad(); //与tem_单片机通信
/*****************测量电流和关断时间******************/
for(yxxhtime=0;yxxhtime<14;yxxhtime++) //直到有效的循环次数为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; //循环
}
/*****************主函数结束******************/
/*****************子函数定义******************/
void delay(uint time) //延时时间为(time*2+2)
{
uint data s;
for(s=0;s<time;s++)
_nop_();
}
void initsys(void) //系统初始化
{
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位异步收发,不允许接收
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读的数据写到RAM (读了500个数据)
{
uint data i;
uchar data databuf;
_nop_();
databuf=fifo1;
databuf=fifo2; //把fifo中前2个无效数据丢弃
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的数据计算并存入到指定空间
{
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; //把十六进制数变换成实际电压值
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;
// }
}
/*****************数据传输程序******************/
void transmitdata(void) //传送ASCII缓冲区的内容给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;
}
}
/*****************数据平均程序******************/
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 + -