⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 相开始检测.txt

📁 c51经典子程序代码全集
💻 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 + -