📄 相开始检测.txt
字号:
用【 小 | 中 | 大 】字体浏览
C51编程:请进,急!!!! [潞潞] [89次] 01-11-7 下午 06:29:51
帮我看看,在仿真器上能运行正确。我烧片子后结果不对。通讯很好,A/D数据也采的正
确。当传回来时数据全变为0了。
全局变量 I_a, I_b, i_c 好象被改了。可用仿真器没这现象。
//********************
#include <reg51f.H>
#include <stdio.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define ADDR_H 0x31
#define ADDR_L 0x31
#define Vsta 0.00061
#define Rq 245
//typedef struct DAT_str{float a;float b;float c;}coll_float_type;
//typedef struct DAT_str_int{uint a,b,c;}coll_int_type;
sbit en_ph = P3^6;
sbit en_485 = P3^7;
sbit sel_wave = P1^6;
sbit cstart = P0^3;
sbit sclk = P0^4;
sbit sdo = P0^5;
sbit sdi = P0^6;
sbit ad_cs = P0^7;
sbit h_50 = P1^3;
sbit sel_0 = P1^7;
sbit sw1_a = P0^0;
sbit sw1_b = P0^1;
sbit sw1_c = P0^2;
sbit swg_a = P1^0;
sbit swg_b = P1^1;
sbit swg_c = P1^2;
uint idata Dly_time=0; //通道延时时间的记数值
bit bdata F_ad; //ad检测完
bit bdata F_pca;
#define ZLEN 2 /* size of serial transmission buffer */
uchar idata outbuf[ZLEN]; /* storage for transmission buffer */
uchar idata *outlast=outbuf; //最后由中断传输出去的字节位置
uchar idata *putlast=outbuf; //最后放入发送缓冲区的字节位置
#define ILEN 8 /* size of serial receiving buffer */
uchar idata inbuf[ILEN];
uchar idata *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置
uchar idata *getlast=inbuf; //最后取走的字节位置
uchar idata rt_buf[12];
uchar idata cc[4];
uchar idata dd[2];
float idata I_a; //电流
float idata I_b;
float idata I_c;
uint idata T_a; //pca记数值
uint idata T_b;
uint idata T_c;
bit bdata F_outbuf; //输出缓冲区非空标志 有=1
bit bdata F_inbuf; //接收缓冲区非空标志 有=1
bit bdata F_inbuf_ful; //输入缓冲区满标志 满=1
bit bdata F_r_ok; //接收正确 正确=1
bit bdata F_r_null; //接收无效 无效=1
bit bdata F_fault; //系统故障标志 有=1
uchar code hex_[]={"0123456789ABCDEF"};
uchar code bin_[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0,0,0,0,0,0,0,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
void reply_ok(void);
void reply_err(void);
void look(uchar p);
void msec(uint x);
uint tx_data_h(uchar bag_l,uchar order,uchar parameter);
uint puthex(uchar c);
void tx_data_end(uint s);
uint put_int_hex(uint s);
uint putf_hex(float ff);
//*******************************************
void msec(uint x) /* delay (x/10)ms time */
{
uchar idata j;
while(x != 0)
{
x--;
for (j=0;j<125;j++)
{;}
}
}
//**************************
uint AD_result(void)
{
uchar idata i;
ulong idata ad_res=0;
uint idata max_tem=0;
uint idata min_tem=0;
ulong idata ad_mux=0;
F_ad = 0; //OPEN A/D
AD_rw(0x0000); //选0通道
while(F_ad == 0){};
F_ad = 0;
ad_res = AD_rw(0x0000);
max_tem = ad_res;
min_tem = ad_res;
while(F_ad == 0){};
for(i=0;i<7;i++)
{
F_ad = 0;
ad_res = AD_rw(0x0000);
while(F_ad == 0){};
max_tem = (max_tem>ad_res)?max_tem:ad_res;
min_tem = (min_tem<ad_res)?min_tem:ad_res;
ad_mux += ad_res;
}
ad_res = (ad_mux-max_tem-min_tem)/5;
return(ad_res);
}
//*******************************
//开关切换
//WZL
//2001/09/12
//*******************************
void switch_key(uchar q)
{
uchar o;
o = q;
switch(o)
{
case 0: //50HZ
sw1_a = 0;
sw1_b = 0;
sw1_c = 0;
break;
case 1: //A相
sw1_a = 1;
sw1_b = 0;
sw1_c = 0;
break;
case 2: //B相
sw1_a = 0;
sw1_b = 1;
sw1_c = 0;
break;
case 3: //C相
sw1_a = 1;
sw1_b = 1;
sw1_c = 0;
break;
case 4: //A+B+C相
sw1_a = 0;
sw1_b = 0;
sw1_c = 1;
break;
case 5: //OUT_PH
sw1_a = 1;
sw1_b = 0;
sw1_c = 1;
break;
default:
break;
}
msec(20);
}
//*******************************
//调整AD622放大倍数
//WZL
//2001/09/11
//*******************************
void adjust_gain(uchar n)
{
uchar o;
o = n;
switch (o)
{
case 0: //不放大
swg_a = 1;
swg_b = 1;
swg_c = 1;
break;
case 2: //放大2倍
swg_a = 1;
swg_b = 0;
swg_c = 0;
break;
case 3: //放大3倍
swg_a = 0;
swg_b = 1;
swg_c = 0;
break;
case 5: //放大5倍
swg_a = 1;
swg_b = 1;
swg_c = 0;
break;
case 10: //放大10倍
swg_a = 0;
swg_b = 0;
swg_c = 1;
break;
case 20: //放大20倍
swg_a = 1;
swg_b = 0;
swg_c = 1;
break;
case 50: //放大50倍
swg_a = 0;
swg_b = 1;
swg_c = 1;
break;
case 100: //放大100倍
swg_a = 0;
swg_b = 0;
swg_c = 0;
break;
default:
break;
}
msec(20);
}
//*******************************
//自动赠言调节
//WZL
//2001/09/11
//*******************************
uint auto_adjust_gain(void)
{
uint idata gain=0;
uint idata o;
o = AD_result();
if(o<=4050&o>=1200)
{
gain = 1;
}
else
{
msec(20);
adjust_gain(0);
o = AD_result();
if(o >= 4080){adjust_gain(0);gain=0;}
else if(o<=35){adjust_gain(100);gain=100;}
else if(o>35&o<=100){adjust_gain(50);gain=50;}
else if(o>100&o<=180){adjust_gain(20);gain=20;}
else if(o>180&o<=350){adjust_gain(10);gain=10;}
else if(o>350&o<=700){adjust_gain(5);gain=5;}
else if(o>700&o<=1000){adjust_gain(3);gain=3;}
else if(o>1000&o<=1300){adjust_gain(2);gain=2;}
else {adjust_gain(0);gain=1;}
msec(20);
}
msec(10);
return(gain);
}
//*******************************
//检测一相泄漏电流参数
//WZL
//2001/09/11
//*******************************
float detect_leak_i(uint gain)
{
uchar idata i;
uint idata ad=0;
float idata I_leak=0;
if(gain == 0)
{
F_fault = 1;
look(0x77);
}
else
{
ad = AD_result();
for(i=0;i<5;i++)
{
ad = (ad + AD_result())/2;
}
I_leak = (float)(ad);
look(0x2e);
// I_leak = (ad*Vsta)/(gain*10*Rq);
}
return(I_leak);
}
//*******************************
//检测一相参数
//WZL
//2001/09/11
//*******************************
void detect_one_para(uchar ph)
{
uint idata phasic;
float idata I_leak;
uint idata gain;
uchar n;
uint sum;
n = ph;
adjust_gain(0);
switch_key(n); //切换信号
msec(20);
gain = auto_adjust_gain(); //自动增益调节
// phasic = detect_ph(1); //检测相位
I_leak = detect_leak_i(gain); //检测泄漏电流
switch (n)
{
case 1:
T_a = 3345;
I_a = I_leak;
sum = tx_data_h(19,'W','A');
sum += put_int_hex(T_a); // A
相记数值
sum += putf_hex(I_a);
tx_data_end(sum);
break;
case 2:
T_b = phasic;
I_b = I_leak;
break;
case 3:
T_c = phasic;
I_c = I_leak;
break;
default:
F_fault = 1;
break;
}
}
(续1) [潞潞] [23次] 01-11-7 下午 06:33:33
//*****************************
//发一个字节时间
//******************************
void tx_delay()
{
uint idata O;
uchar idata i;
O = 49;
do
{
i=(0-TH1);
do
{
i--;
}
while(i!=0);
O--;
}
while(O!=0); //延时一个字节发送时间
}
//*****************************
//*****************************
//放入一个字节到发送缓冲区
//WZL
//2001/08/18
//*****************************
putbyte(char c)
{
ES=0; /*暂停串行中断,以免数据比较时出错? */
if(outlast == putlast )
{
tx_delay();
}
*putlast = c; //放字节进入缓冲区
putlast++; //发送缓冲区指针加一
if (putlast == outbuf+ZLEN) putlast = outbuf; //指针到了顶部换到底部
if (!F_outbuf) {F_outbuf=1;TI=1; } //缓冲区开始为空置为有,启动发送
ES=1;
}
//*************************************
//发送一个字节的hex码,分成两个字节
//************************************
uint puthex(uchar c)
{
uchar idata ch;
uint idata sum=0;
ch=(c>>4)&0x0f;
putbyte(hex_[ch]);
sum += hex_[ch];
ch=c&0x0f;
putbyte(hex_[ch]);
sum += hex_[ch];
return(sum);
}
//*************************************
//发int数2字节HEX码
//wzl
//2001/08/28
//*************************************
uint put_int_hex(uint s)
{
uint idata sum=0;
union dat
{
uint t;
struct{uchar f1;uchar f2;}uc;
}x;
x.t = s;
sum += puthex(x.uc.f1); //校验和
sum += puthex(x.uc.f2);
return(sum);
}
//*************************************
//发FLOAT数4字节HEX码
//wzl
//2001/08/28
//*************************************
uint putf_hex(float ff)
{
uint idata sum=0;
union dat
{
float f;
struct{uchar f1;uchar f2;uchar f3;uchar f4;}uc;
}x;
x.f = ff;
sum += puthex(x.uc.f1);
sum += puthex(x.uc.f2);
sum += puthex(x.uc.f3);
sum += puthex(x.uc.f4);
return(sum);
}
//*************************************
//从接收缓冲区取一个byte,如不想等待则在调用时检测F_inbuf是否为1。
//WZL
//2001/08/18
//************************************
uchar getbyte (void)
{
uchar idata c ;
while (!F_inbuf); //缓冲区空等待
ES=0;
c = *getlast; //取数据
getlast++; //最后取走的数据位置加一
F_inbuf_ful=0; //输入缓冲区的满标志清零
if (getlast == inbuf+ILEN) getlast=inbuf; //地址到顶部回到底部
if (getlast == inlast) F_inbuf=0; //地址相等置接收缓冲区空空标
志,再取数要检该标志
ES=1;
return (c); //取回数据
}
//*****************************************
//接收一行数据,必须定义放数据串的指针位置和大小
//wzl
//2001/08/20
//*****************************************
uint getline (uchar *line, unsigned char n)
{
uchar idata cnt = 0; //定义已接收的长度
uchar idata c=0xff;
uint idata sum=0;
while (cnt < n && c != 0x00) //数目到了,回车或ESC停止
{
c = getbyte ();
if ((c <= 0x2d) && (c >= 0x5a)) //读一个字节,如果不是有效
字符,换成紷束符
{
c = 0x00;
F_r_null = 1;
}
*line = c; //其他字符取入,回显
line++; //指针加一
cnt++; //总数目加一
sum += c;
}
*line = 0;
return(sum); //再加上停止符0
}
//****************************
//****************************
uchar get_l(void)
{
uchar idata i;
uchar idata sum=0;
getline(dd,2);
for(i=0;i<2;i++)
{
sum = (sum<<4)|bin_[(dd[i]-0x30)];
}
return(sum);
}
//****************************
//接收校验和
//WZL
//2001/09/28
//****************************
uint get_sum(void)
{
uchar idata i;
uint idata sum=0;
getline(cc,4);
for(i=0;i<4;i++)
{
sum = (sum<<4)|bin_[(cc[i]-0x30)];
}
return(sum);
}
//***************************
//串口初始化
//wzl
//2001/07/22
//***************************
void serial_init(void)
{
SCON = 0x50; // mode 1: 8-bit UART, enable receiver
TMOD |= 0x20; // timer 1 mode 2: 8-Bit reload
PCON |= 0x00;
TH1 = 0xfd; //baud*2 /* reload value 4800 baud */
TR1 = 1;
en_485 = 0;
ES = 1;
}
//***********************************
//接收数据
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -