中国IEEE
关于我们 | 会员登陆 | 收藏本站 | 留 言 薄
 

 | 网站首页 | 电子知识 | 单片机知识 | 电路设计 | 微电子技术 | SCADA系统 | 资源下载 | 给我留言 | 谷歌商城 | 视频教程 | ieee | 
热门搜索关键字: 单片机教程 | 三极管微电子 |  C语言汇编语言SCADA元器件IEEE |
cnieee.com baidu
栏目导航  
栏目更新推荐  
·8051单片机C语言数据采集程序
·99计数器C语言版本
·3x4矩阵键盘的扫描程序(C语言)
·51单片机串口调试程序(C语言)
·一些常用的软件滤波方法(C语言)
·一些常用的软件滤波方法
·volatile用法
·嵌入式实时程序设计中C/C++代码的优…
点击TOP(10)  
  • 此栏目下没有热点文章
  • 图片文章  

    C语言嵌入式系统编程…

    C语言嵌入式系统编程…

    C语言嵌入式系统编程…
     
    您现在的位置: 中国IEEE中国电气电子工程师网 >> 单片机知识 >> 编程语言 >> 单片机C语言 >> 正文

    8051单片机C语言数据采集程序
    文章来源:本站整理 点击数: 更新时间:2008-5-9 【字体:
    (欢迎光临中国IEEE,希望本文能对您有所帮助http://www.cnieee.com)


    相关文章:

    单片机实现数据远程监控
    用单片机实现高速数据采集

  • 上一个文章:

  • 下一个文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
    关于〖8051单片机C语言数据采集程序〗的最新评论:

     

    8051单片机C语言数据采集程序

    /8051单片机TLC1549数据采集程序源代码

    //单片机:At89S52

    //连接类型:232 |485 接口

    //校验方式:checksum

    //开发环境:keil C


    i nclude <stdio.h>
    i nclude <REGX51.H>
    i nclude "iic.h"

    #define uchar unsigned char
    #define uint unsigned int

    uint Timer_Pro_Flag=0;//0
    为显示处理,1为时序采集处理

    sbit TEST_CAP_VOL_CRLT=P1^0;//
    用于控制外部继电器
    sbit PWM_Pin=P3^7;//PWM
    输出
    sbit IrDA_in_Pin=P1^0;//
    红外脉冲输入检测脚

    bit PWMFlag=0;
    uchar OLD_TH0,OLD_TL0;


    #define MAXCMD_LENGTH 7

    #define AD_VOL_PER 1.04058 //
    正常采集时的电压校准值
    #define AD_Loop_PickVol_PER 1.04058 //CD4051
    循环采集时的电压校准值

    sbit WDTRST=0xA6;//At89S5x
    看门狗寄存器
    sbit ADCLK=P2^0;
    sbit ADOUT=P2^1;
    sbit ADCS=P2^2;
    //--------------------------
    /************CD4051---8
    1模拟开关芯片*****************/
    /*
    |------------------------------------------------------|
    | 4 2 1 |
    |-----------------------------------------------|------|
    |
    端口 | INH C B A | | |
    |------ 7 6 5 4 3 2 1 0 |
    正值 | 取反 |
    |
    通道 |--------------------------------|-------|------|
    |------|...............|8 4 2 1 | | |
    |------|---------------|----------------|-------|------|
    | 0 |0 0 0 0 0 0 0 0 | 0x00 | 0xff |
    | 1 |0 0 0 0 0 0 1 0 | 0x02 | 0xf7 |
    | 2 |0 0 0 0 0 1 0 0 | 0x04 | 0xfb |
    | 3 |0 0 0 0 0 1 1 0 | 0x06 | 0xf3 |
    | 4 |0 0 0 0 1 0 0 0 | 0x08 | 0xfd |
    | 5 |0 0 0 0 1 0 1 0 | 0x0A | 0xf8 |
    | 6 |0 0 0 0 1 1 0 0 | 0x0C | 0xf9 |
    | 7 |0 0 0 0 1 1 1 0 | 0x0e | 0xf1 |
    |---------------------------------------|-------|------|

    */
    uchar CD4051_NUM[]={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0e}; //0~7
    编码
    sbit CD4051_A=P1^1;
    sbit CD4051_B=P1^2;
    sbit CD4051_C=P1^3;
    sbit CD4051_INH=P1^4; //CD4051_INH
    1时,,所有通导都不导通

    bit CD4051_Vol_Conver_Flag=0; //0
    时为正常采集,1CD4051循环采集
    //--------------------------
    //LED
    显示

    //--------------------------
    uchar LedCount=0;
    uchar LED_BIT[5]; //
    用于显示的每一位数据码的内容
    uchar LED_NUM[]={0x00,0x10,0x20,0x40,0x80};//
    选择显示位
    //--------------------------------------------------------

    void SendByte(unsigned char word)
    {
    TI=0;
    SBUF=word;
    while(TI==0);
    TI=0;
    }

    uchar ComBuf[MAXCMD_LENGTH];//
    用于保存串口的数据

    /*---
    少量延时---*/
    void delay(uint t)
    {
    uint i=0;
    for(;i<=t;i++);
    }

    void Pluckdelay(uint t)
    {
    uint i=0,j;
    for(;i<=t;i++)
    for(j=1;j<=1000;j++);
    }
    /*=================================
    ComBuf[5]
    加入CheckSUM校验码
    算法:0x01+not(字节1+字节2+...+字节N)
    =================================*/
    void SetCheckSUM()
    {
    ComBuf[5]=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
    }
    /*=============================================================
    检测上位机发送来的ComBuf[5]checksum校验码和计算后的是否相等
    正确则返回:1
    错误则返回:0
    ==============================================================*/
    bit ISCheckSUM()
    {
    uchar crc;
    crc=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
    if(ComBuf[5]==crc)
    return 1;
    else
    {
    ComBuf[1]=crc;//
    如果错误,则返回计算后得到的CHECKSUM校验码
    ComBuf[2]=ComBuf[5];//
    返回原来上位机发送来的CHECKSUM校验码
    return 0;
    }
    }

    /*-----------------------------------
    * *
    *
    等待接收上位机发来的指令 *
    * *
    -------------------------------------*/
    void WaitComm()
    {
    uchar n=0;
    RI=0;
    while (1)
    {
    while(!RI);//
    等接收数据
    //-----------------
    ComBuf[n]=SBUF;
    RI=0;
    // SBUF=ComBuf[n];
    if (ComBuf[n]==0x7e) break;//
    接收到结束符则退出
    if (n>=MAXCMD_LENGTH)
    n=0;//
    接收10个字节,如果还没有接收到0x7e结束符,就重新记录
    else
    n++;
    }
    }


    /*-------------------------------
    * *
    *
    发送combuf数据至上位机 *
    * *
    --------------------------------*/
    void SendByteArray()
    {
    unsigned i;
    SetCheckSUM();//
    加入ComBuf[5]checkSUM校验码
    ComBuf[4]=P0;//
    取读本模块地址
    ComBuf[6]=0x7e;//
    结束符
    for(i=0;i<=MAXCMD_LENGTH-1;i++)
    {
    SendByte(ComBuf[i]);
    }
    }

    /*-------------------------------
    * *
    *
    送端口状态至上位机 *
    * *
    --------------------------------*/
    void GetP0()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P0_0; break;
    case 0x01: ComBuf[3]=P0_1; break;
    case 0x02: ComBuf[3]=P0_2; break;
    case 0x03: ComBuf[3]=P0_3; break;
    case 0x04: ComBuf[3]=P0_4; break;
    case 0x05: ComBuf[3]=P0_5; break;
    case 0x06: ComBuf[3]=P0_6; break;
    case 0x07: ComBuf[3]=P0_7; break;
    default:
    ComBuf[3]=P0;//
    8...则以上传整个port状态
    }
    }
    //--------------------

    void GetP1()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P1_0; break;
    case 0x01: ComBuf[3]=P1_1; break;
    case 0x02: ComBuf[3]=P1_2; break;
    case 0x03: ComBuf[3]=P1_3; break;
    case 0x04: ComBuf[3]=P1_4; break;
    case 0x05: ComBuf[3]=P1_5; break;
    case 0x06: ComBuf[3]=P1_6; break;
    case 0x07: ComBuf[3]=P1_7; break;
    default:
    ComBuf[3]=P1;//
    8...则以上传整个port状态
    }
    }
    //---------------
    void GetP2()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P2_0; break;
    case 0x01: ComBuf[3]=P2_1; break;
    case 0x02: ComBuf[3]=P2_2; break;
    case 0x03: ComBuf[3]=P2_3; break;
    case 0x04: ComBuf[3]=P2_4; break;
    case 0x05: ComBuf[3]=P2_5; break;
    case 0x06: ComBuf[3]=P2_6; break;
    case 0x07: ComBuf[3]=P2_7; break;
    default:
    ComBuf[3]=P2;//
    8...则以上传整个port状态
    }
    }
    //--------------
    void GetP3()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P3_0; break;
    case 0x01: ComBuf[3]=P3_1; break;
    case 0x02: ComBuf[3]=P3_2; break;
    case 0x03: ComBuf[3]=P3_3; break;
    case 0x04: ComBuf[3]=P3_4; break;
    case 0x05: ComBuf[3]=P3_5; break;
    case 0x06: ComBuf[3]=P3_6; break;
    case 0x07: ComBuf[3]=P3_7; break;
    default:
    ComBuf[3]=P3;//
    8...则以上传整个port状态
    }
    }
    //-------
    发送AT89S5x的指定端口状态到上位机-----
    void SendPortData()
    {
    switch (ComBuf[1])/*Port
    */
    {
    case 0x00: GetP0(); break;
    case 0x01: GetP1(); break;
    case 0x02: GetP2(); break;
    case 0x03: GetP3(); break;
    }

    /*--------------------*/
    SendByteArray();//
    发送数据
    }




    /*-------------------------------
    * *
    *
    各个端口的状态设定 *
    * *
    --------------------------------*/
    void SetP0()
    {
    switch(ComBuf[2])
    {
    case 0x00: P0_0=ComBuf[3]; break;
    case 0x01: P0_1=ComBuf[3]; break;
    case 0x02: P0_2=ComBuf[3]; break;
    case 0x03: P0_3=ComBuf[3]; break;
    case 0x04: P0_4=ComBuf[3]; break;
    case 0x05: P0_5=ComBuf[3]; break;
    case 0x06: P0_6=ComBuf[3]; break;
    case 0x07: P0_7=ComBuf[3]; break;
    default:
    P0=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP1()
    {
    switch(ComBuf[2])
    {
    case 0x00: P1_0=ComBuf[3]; break;
    case 0x01: P1_1=ComBuf[3]; break;
    case 0x02: P1_2=ComBuf[3]; break;
    case 0x03: P1_3=ComBuf[3]; break;
    case 0x04: P1_4=ComBuf[3]; break;
    case 0x05: P1_5=ComBuf[3]; break;
    case 0x06: P1_6=ComBuf[3]; break;
    case 0x07: P1_7=ComBuf[3]; break;
    default:
    P1=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP2()
    {
    switch(ComBuf[2])
    {
    case 0x00: P2_0=ComBuf[3]; break;
    case 0x01: P2_1=ComBuf[3]; break;
    case 0x02: P2_2=ComBuf[3]; break;
    case 0x03: P2_3=ComBuf[3]; break;
    case 0x04: P2_4=ComBuf[3]; break;
    case 0x05: P2_5=ComBuf[3]; break;
    case 0x06: P2_6=ComBuf[3]; break;
    case 0x07: P2_7=ComBuf[3]; break;
    default:
    P2=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP3()
    {
    switch(ComBuf[2])
    {
    case 0x00: P3_0=ComBuf[3]; break;
    case 0x01: P3_1=ComBuf[3]; break;
    case 0x02: P3_2=ComBuf[3]; break;
    case 0x03: P3_3=ComBuf[3]; break;
    case 0x04: P3_4=ComBuf[3]; break;
    case 0x05: P3_5=ComBuf[3]; break;
    case 0x06: P3_6=ComBuf[3]; break;
    case 0x07: P3_7=ComBuf[3]; break;
    default:
    P3=ComBuf[3];//
    8...则设置整个port状态
    }
    }

    /*=================================
    WritePortData()

    按上位机传来的格式进行端口的设置
    =================================*/
    void WritePortData()
    {
    switch (ComBuf[1])/*Port
    */
    {
    case 0x00: SetP0(); break;
    case 0x01: SetP1(); break;
    case 0x02: SetP2(); break;
    case 0x03: SetP3(); break;
    }
    }

    /*----------------------------------
    * SetEA() *
    * *
    *
    中断允许设定,(EA寄存器) *
    * ComBuf[1]==>0x00
    EA设定 *
    * 0x01
    为读取EA *
    ------------------------------------*/
    void SetEA()
    {
    if (ComBuf[1]==0x00)
    EA=ComBuf[3];
    else
    {
    ComBuf[3]=EA;
    SendByteArray();//
    发送数据
    }
    }

    /*---------------------------------------------------------------
    * *
    * float
    型转为2char,并发送至串行 *
    * void Convert_AD_VOL_ValueToChar() *
    * *
    ---------------------------------------------------------------*/
    void Convert_AD_VOL_ValueToChar(uint vol)
    {
    float temp_float_vol;
    unsigned int temp;
    uchar AD_Hight,AD_Low;

    temp_float_vol=vol*0.0048*AD_VOL_PER;
    temp=temp_float_vol*100;
    AD_Hight=temp /100;//
    取个位数
    AD_Low=temp-AD_Hight*100;//
    2位小数
    ComBuf[2]=AD_Hight;
    ComBuf[3]=AD_Low;
    SendByteArray();//
    发送数据
    }

    /*--------------------------------
    * *
    *
    预先采集一次AD数据 *
    * *
    *--------------------------------*/
    void Befor_Once_AD()
    {
    uchar i;

    ADCLK=ADOUT=0;
    //----------
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    ADCLK=1;
    ADCLK=0;
    }
    ADCS=1;
    delay(25);//
    两次转换间隔大于21us
    }
    /*---------------------------------------------------------------
    * GetAD() TLC1549
    数据采集 *
    * sbit ADCLK=P2^0; *
    * sbit ADOUT=P2^1; *
    * sbit ADCS=P2^2; *
    -----------------------------------------------------------------*/
    void GetAD()
    {
    uchar i=1,w,PickCount;
    uint vol;

    Befor_Once_AD();//
    预先采集一次AD数据

    //---------------

    if (ComBuf[1]==0)ComBuf[1]=0x01;
    PickCount=ComBuf[1];
    for(w=1;w<=PickCount;w++)
    {
    ADCLK=ADOUT=0;
    vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    vol<<=1;
    if(ADOUT)vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    //---------------
    ComBuf[1]=w;//
    发送第几次采集的序号
    Convert_AD_VOL_ValueToChar(vol);//
    float转为2char,并发送至串行口
    P2=0xff;//p2
    口置初始状态
    }
    }



    /*---------------------------------------------------------------
    * *
    * TLC1549
    数据软件滤波采集 *
    * *
    -----------------------------------------------------------------*/
    void GetAD_With_VOL_Filter()
    {
    uchar i,w,j,k,PickCount,AD_Hight=0,AD_Low=0;
    uint Vol=0,VolArray[10],temp;
    float SumVol=0;
    Befor_Once_AD();//
    预先采集一次AD数据
    //---------------
    //---------------
    PickCount=11;
    for(w=0;w<=PickCount;w++)
    {
    ADCLK=ADOUT=0;
    Vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    Vol<<=1;
    if(ADOUT)Vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    VolArray[w]=Vol;//
    保存采集来的数据
    //---------------
    P2=0xff;//p2
    口置初始状态
    }
    //-------
    按从小到大排序--------
    //
    选择排序法..
    for(i=0;i<=PickCount-1;i++)
    {
    k=i;
    for(j=PickCount+1;j<i;j++)
    {
    if(VolArray[j]>VolArray[k])k=j;
    if(k!=i)
    {
    temp=VolArray[k];
    VolArray[k]=VolArray[i];
    VolArray[i]=temp;
    }
    }
    }

    //----------累加计算平静均值------------
    //
    乎略最小和最大值
    for(i=1;i<=PickCount-1;i++)
    {
    SumVol=SumVol+VolArray[i];//
    累加结果
    }
    SumVol=SumVol/(PickCount-1)*0.0048;//
    电压值=平均值*介数
    /*------------------------------
    0
    时为正常采集,1CD4051循环采集
    因为CD4051通道存在电压消耗,
    所以和正常的直接采集的校准值不一样
    -------------------------------*/
    /*
    电压校准比*/
    if(CD4051_Vol_Conver_Flag)
    SumVol*=AD_Loop_PickVol_PER;//
    采用CD4051时的电压校准值
    else
    SumVol*=AD_VOL_PER;//
    直接输入时的电压校准值

    //----------------
    temp=SumVol*100;//
    保留2位小位
    AD_Hight=temp /100;//
    取个位数
    AD_Low=temp-AD_Hight*100;//
    2位小数
    //ComBuf[1]=w;//
    发送第几次采集的序号
    ComBuf[2]=AD_Hight;
    ComBuf[3]=AD_Low;
    SendByteArray();//
    发送数据
    }



    /*-------------------------------------------------------------------------*
    * *
    * CD4051_PickVol...8
    路选通TLC1549采集 *
    * *
    *-------------------------------------------------------------------------*/
    void CD4051_PickVol()
    {
    CD4051_Vol_Conver_Flag=1;
    P1=CD4051_NUM[ComBuf[1]];//CD4051
    通道选通
    // delay(2300);//
    通道切换时间间隔,避免电路的残余电
    GetAD_With_VOL_Filter();
    CD4051_Vol_Conver_Flag=0;
    }

    /*-------------------------------------------------------------------------*
    * *
    * CD4051_LoopPickVol()...8
    路巡检TLC1549采集 *
    * *
    *-------------------------------------------------------------------------*/
    void CD4051_LoopPickVol()
    {
    uchar i=0,w;
    w=ComBuf[1]-1;//
    通导号等于。。。通道数-1
    for(;i<=w;i++)
    {
    ComBuf[1]=i;//
    通道号
    CD4051_PickVol();
    }
    P1=0xff;//
    关闭通道
    }


    /*-------------------------------------------------------------------------*
    * *
    *
    电容放电计数测试 *
    * TestCapCount() *
    * *
    *-------------------------------------------------------------------------*/
    void TestCapCount()
    {

    uint Vol,TempVol=0xff,Count=0,temp1,temp2;
    uchar i,CAPDELAYTIME;
    float TEST_CAP_OUT_value="/0.05;"
    P1=CD4051_NUM[1];//CD4051
    通道选通,1号通道
    TEST_CAP_VOL_CRLT=0;//
    打开电源
    if (ComBuf[1]==0x00)//
    0x00时为电容测量方式,0x01为电压测量方式
    {
    for(i=0;i<=ComBuf[2];i++)delay(60000);//
    等待电容充电

    TEST_CAP_VOL_CRLT=1;//
    断开电源
    TEST_CAP_OUT_value="/0.01;//
    当为电容测量时。。下限电压"
    }
    CAPDELAYTIME=ComBuf[3];//
    延时常量
    //--------------
    P1_1=0;//
    打开LED状态指示
    while(TempVol*0.0048*AD_VOL_PER>=TEST_CAP_OUT_VALUE)//
    当放电到0V时退出
    {
    ADCLK=ADOUT=0;
    Vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    Vol<<=1;
    if(ADOUT)Vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    //---------------
    P2=0xff;//p2
    口置初始状态
    Count++;//
    计数
    ComBuf[0]=0x05;//
    利用软件滤波的处理过程显示
    if(Count>2)TempVol=Vol;//
    第一次的取值有可能是1,,去掉不要

    Convert_AD_VOL_ValueToChar(Vol);//
    转换并发送本次数据
    Pluckdelay(CAPDELAYTIME);//
    采集间隔时间,为ComBuf[4]*1000的时间常数
    }
    //
    从高到低取
    P1=0xff;//
    初始P1

    ComBuf[0]=0x0b;
    temp1=Count/1000;//
    取前1-2
    ComBuf[1]=temp1;
    temp2=Count/10-temp1*100;//
    得到3-4
    ComBuf[2]=temp2;
    ComBuf[3]=Count-(temp1*1000+temp2*10);
    SendByteArray();//
    发送数据
    }
    //--------------------------------------------------------------------------//

    //
    写一个字节到AT24C04EEPROM
    void WriteAT24C04()
    {
    uchar address,RomData;
    address=ComBuf[1];
    RomData=ComBuf[2];
    WriteByte_24c04(RomData,address);
    }

    //
    读取AT24C04EEPROM一个字节
    void ReadAT24C04()
    {
    ComBuf[2]=ReadByte_24c04(ComBuf[1]);
    SendByteArray();//
    发送数据
    }

    //=================================
    //
    看门狗设置
    //=================================
    //void watchdog()
    //{
    //WDTRST=0x1E;
    //WDTRST=0xE1;//
    喂狗指令
    //}


    void SetLedData()
    {
    uchar ShowData,ShowBit;
    Timer_Pro_Flag=0;//0
    为显示处理,1为时序采集处理
    ShowBit=ComBuf[1];
    ShowData=LED_NUM[ShowBit];//
    选择位
    ShowData|=ComBuf[2];//
    显示内容
    LED_BIT[ShowBit]=0x00;
    LED_BIT[ShowBit]=ShowData;
    TH0=(65536-4000)>>8;
    TL0=(65536-4000)&0xff;
    TR0=ComBuf[3];
    if(ComBuf[3]) P0=0x00;//
    关闭显示
    }

    /*=========================================
    PluckPulse----
    时序采集
    ===========================================*/
    void PluckPulse()
    {
    Timer_Pro_Flag=1;//0
    为显示处理,1为时序采集处理
    OLD_TH0=ComBuf[2];
    OLD_TL0=ComBuf[3];
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=ComBuf[1];//
    关闭或启动计时器
    }
    //------------
    /*=========================================
    PWM----
    时序采集
    ===========================================*/
    void PWM()
    {
    Timer_Pro_Flag=2;//0
    为显示处理,1为时序采集处理
    OLD_TH0=ComBuf[2];
    OLD_TL0=ComBuf[3];
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=ComBuf[1];//
    关闭或启动计时器
    }

    //------------
    void timer0(void) interrupt 1 using 1
    {
    //-------------------
    switch(Timer_Pro_Flag)
    {
    case 0:
    //LED
    显示处理
    TH0=(0xffff-4000)>>8;
    TL0=(0xffff-4000)&0xff;

    if (LedCount>4) LedCount=0;
    P0=0x00;
    P0=LED_BIT[LedCount++];
    break;
    case 1:
    //
    时序采集
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    SendByte(IrDA_in_Pin);//
    发送P1^0引脚状态
    break;
    case 2://
    模拟PWM输出
    if(!PWMFlag)
    {
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=1;
    PWMFlag=1;
    PWM_Pin=0;
    }
    else
    {
    PWM_Pin=1;
    TR0=0;
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=1;
    PWMFlag=0;
    }
    break;
    }
    }




    /*===================================================================

    主程序开始处
    ===================================================================*/
    void main()
    {
    //
    晶振:11.0592,波特率:19200
    TMOD=0x21;
    TL1=0xfd;
    TH1=0xfd;
    SCON=0xd8;
    PCON=0x80;//
    高位为0时不倍频:9600pbf,1时倍频:19200bpf
    TR1=1;

    //------------------
    // TMOD=0x01;//
    工作在定时器方式1,16位计数器
    TH0=(65536-4000)/256;
    TL0=(65536-4000)%256;
    ET0=1;
    EA=1;//
    中断允许
    //-------------

    while(1)
    {
    WaitComm();//
    等待接收数据
    //
    校对checksum校验码是否正确,如正确则进行相关的操作
    if(ISCheckSUM())
    {
    switch (ComBuf[0])
    {
    case 0x01:WritePortData(); break; //
    响应上位机发送的写操作
    case 0x02:SendPortData(); break; //
    响应上位机发送的读操作
    case 0x03:SetEA();break; //
    中断允许设定
    case 0x04:GetAD();break; //TLC1549
    数据采集
    case 0x05:GetAD_With_VOL_Filter();break;//
    采软件滤软件的TLC1549数据采集
    case 0x06:CD4051_PickVol();break; //CD4051--8
    1TLC1549采集
    case 0x07:CD4051_LoopPickVol();break; //8
    路巡检TLC1549采集
    case 0x08:ReadAT24C04();break; //
    读取AT24C04EEPROM一个字节
    case 0x09:WriteAT24C04();break; //
    写一个字节到AT24C04EEPROM
    case 0x0a:SetLedData();break; //
    设定显示的数据
    case 0x0b:TestCapCount();break; //
    电容放电时间计数测试
    case 0x0c:PluckPulse();break; //
    时序采集
    case 0x0d:PWM();break; //
    控制P2_7模拟输出PWM
    }
    }
    else//
    如检验错误则返回上位机错误信息
    {
    ComBuf[0]=0xFF;
    SendByteArray();//
    返回错误信息
    }
    }
    }

     


    i nclude <stdio.h>
    i nclude <REGX51.H>
    i nclude "iic.h"

    #define uchar unsigned char
    #define uint unsigned int

    uint Timer_Pro_Flag=0;//0
    为显示处理,1为时序采集处理

    sbit TEST_CAP_VOL_CRLT=P1^0;//
    用于控制外部继电器
    sbit PWM_Pin=P3^7;//PWM
    输出
    sbit IrDA_in_Pin=P1^0;//
    红外脉冲输入检测脚

    bit PWMFlag=0;
    uchar OLD_TH0,OLD_TL0;


    #define MAXCMD_LENGTH 7

    #define AD_VOL_PER 1.04058 //
    正常采集时的电压校准值
    #define AD_Loop_PickVol_PER 1.04058 //CD4051
    循环采集时的电压校准值

    sbit WDTRST=0xA6;//At89S5x
    看门狗寄存器
    sbit ADCLK=P2^0;
    sbit ADOUT=P2^1;
    sbit ADCS=P2^2;
    //--------------------------
    /************CD4051---8
    1模拟开关芯片*****************/
    /*
    |------------------------------------------------------|
    | 4 2 1 |
    |-----------------------------------------------|------|
    |
    端口 | INH C B A | | |
    |------ 7 6 5 4 3 2 1 0 |
    正值 | 取反 |
    |
    通道 |--------------------------------|-------|------|
    |------|...............|8 4 2 1 | | |
    |------|---------------|----------------|-------|------|
    | 0 |0 0 0 0 0 0 0 0 | 0x00 | 0xff |
    | 1 |0 0 0 0 0 0 1 0 | 0x02 | 0xf7 |
    | 2 |0 0 0 0 0 1 0 0 | 0x04 | 0xfb |
    | 3 |0 0 0 0 0 1 1 0 | 0x06 | 0xf3 |
    | 4 |0 0 0 0 1 0 0 0 | 0x08 | 0xfd |
    | 5 |0 0 0 0 1 0 1 0 | 0x0A | 0xf8 |
    | 6 |0 0 0 0 1 1 0 0 | 0x0C | 0xf9 |
    | 7 |0 0 0 0 1 1 1 0 | 0x0e | 0xf1 |
    |---------------------------------------|-------|------|

    */


    uchar CD4051_NUM[]={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0e}; //0~7
    编码
    sbit CD4051_A=P1^1;
    sbit CD4051_B=P1^2;
    sbit CD4051_C=P1^3;
    sbit CD4051_INH=P1^4; //CD4051_INH
    1时,,所有通导都不导通

    bit CD4051_Vol_Conver_Flag=0; //0
    时为正常采集,1CD4051循环采集
    //--------------------------
    //LED
    显示
    //--------------------------
    uchar LedCount=0;
    uchar LED_BIT[5]; //
    用于显示的每一位数据码的内容
    uchar LED_NUM[]={0x00,0x10,0x20,0x40,0x80};//
    选择显示位
    //--------------------------------------------------------

    void SendByte(unsigned char word)
    {
    TI=0;
    SBUF=word;
    while(TI==0);
    TI=0;
    }

    uchar ComBuf[MAXCMD_LENGTH];//
    用于保存串口的数据

    /*---
    少量延时---*/
    void delay(uint t)
    {
    uint i=0;
    for(;i<=t;i++);
    }

    void Pluckdelay(uint t)
    {
    uint i=0,j;
    for(;i<=t;i++)
    for(j=1;j<=1000;j++);
    }
    /*=================================
    ComBuf[5]
    加入CheckSUM校验码
    算法:0x01+not(字节1+字节2+...+字节N)
    =================================*/
    void SetCheckSUM()
    {
    ComBuf[5]=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
    }
    /*=============================================================
    检测上位机发送来的ComBuf[5]checksum校验码和计算后的是否相等
    正确则返回:1
    错误则返回:0
    ==============================================================*/
    bit ISCheckSUM()
    {
    uchar crc;
    crc=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
    if(ComBuf[5]==crc)
    return 1;
    else
    {
    ComBuf[1]=crc;//
    如果错误,则返回计算后得到的CHECKSUM校验码
    ComBuf[2]=ComBuf[5];//
    返回原来上位机发送来的CHECKSUM校验码
    return 0;
    }
    }

    /*-----------------------------------
    * *
    *
    等待接收上位机发来的指令 *
    * *
    -------------------------------------*/
    void WaitComm()
    {
    uchar n=0;
    RI=0;
    while (1)
    {
    while(!RI);//
    等接收数据
    //-----------------
    ComBuf[n]=SBUF;
    RI=0;
    // SBUF=ComBuf[n];
    if (ComBuf[n]==0x7e) break;//
    接收到结束符则退出
    if (n>=MAXCMD_LENGTH)
    n=0;//
    接收10个字节,如果还没有接收到0x7e结束符,就重新记录
    else
    n++;
    }
    }


    /*-------------------------------
    * *
    *
    发送combuf数据至上位机 *
    * *
    --------------------------------*/
    void SendByteArray()
    {
    unsigned i;
    SetCheckSUM();//
    加入ComBuf[5]checkSUM校验码
    ComBuf[4]=P0;//
    取读本模块地址
    ComBuf[6]=0x7e;//
    结束符
    for(i=0;i<=MAXCMD_LENGTH-1;i++)
    {
    SendByte(ComBuf[i]);
    }
    }

    /*-------------------------------
    * *
    *
    送端口状态至上位机 *
    * *
    --------------------------------*/
    void GetP0()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P0_0; break;
    case 0x01: ComBuf[3]=P0_1; break;
    case 0x02: ComBuf[3]=P0_2; break;
    case 0x03: ComBuf[3]=P0_3; break;
    case 0x04: ComBuf[3]=P0_4; break;
    case 0x05: ComBuf[3]=P0_5; break;
    case 0x06: ComBuf[3]=P0_6; break;
    case 0x07: ComBuf[3]=P0_7; break;
    default:
    ComBuf[3]=P0;//
    8...则以上传整个port状态
    }
    }
    //--------------------
    void GetP1()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P1_0; break;
    case 0x01: ComBuf[3]=P1_1; break;
    case 0x02: ComBuf[3]=P1_2; break;
    case 0x03: ComBuf[3]=P1_3; break;
    case 0x04: ComBuf[3]=P1_4; break;
    case 0x05: ComBuf[3]=P1_5; break;
    case 0x06: ComBuf[3]=P1_6; break;
    case 0x07: ComBuf[3]=P1_7; break;
    default:
    ComBuf[3]=P1;//
    8...则以上传整个port状态
    }
    }
    //---------------
    void GetP2()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P2_0; break;
    case 0x01: ComBuf[3]=P2_1; break;
    case 0x02: ComBuf[3]=P2_2; break;
    case 0x03: ComBuf[3]=P2_3; break;
    case 0x04: ComBuf[3]=P2_4; break;
    case 0x05: ComBuf[3]=P2_5; break;
    case 0x06: ComBuf[3]=P2_6; break;
    case 0x07: ComBuf[3]=P2_7; break;
    default:
    ComBuf[3]=P2;//
    8...则以上传整个port状态
    }
    }
    //--------------
    void GetP3()
    {
    switch(ComBuf[2])
    {
    case 0x00: ComBuf[3]=P3_0; break;
    case 0x01: ComBuf[3]=P3_1; break;
    case 0x02: ComBuf[3]=P3_2; break;
    case 0x03: ComBuf[3]=P3_3; break;
    case 0x04: ComBuf[3]=P3_4; break;
    case 0x05: ComBuf[3]=P3_5; break;
    case 0x06: ComBuf[3]=P3_6; break;
    case 0x07: ComBuf[3]=P3_7; break;
    default:
    ComBuf[3]=P3;//
    8...则以上传整个port状态
    }
    }
    //-------
    发送AT89S5x的指定端口状态到上位机-----
    void SendPortData()
    {
    switch (ComBuf[1])/*Port
    */
    {
    case 0x00: GetP0(); break;
    case 0x01: GetP1(); break;
    case 0x02: GetP2(); break;
    case 0x03: GetP3(); break;
    }

    /*--------------------*/
    SendByteArray();//
    发送数据
    }




    /*-------------------------------
    * *
    *
    各个端口的状态设定 *
    * *
    --------------------------------*/
    void SetP0()
    {
    switch(ComBuf[2])
    {
    case 0x00: P0_0=ComBuf[3]; break;
    case 0x01: P0_1=ComBuf[3]; break;
    case 0x02: P0_2=ComBuf[3]; break;
    case 0x03: P0_3=ComBuf[3]; break;
    case 0x04: P0_4=ComBuf[3]; break;
    case 0x05: P0_5=ComBuf[3]; break;
    case 0x06: P0_6=ComBuf[3]; break;
    case 0x07: P0_7=ComBuf[3]; break;
    default:
    P0=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP1()
    {
    switch(ComBuf[2])
    {
    case 0x00: P1_0=ComBuf[3]; break;
    case 0x01: P1_1=ComBuf[3]; break;
    case 0x02: P1_2=ComBuf[3]; break;
    case 0x03: P1_3=ComBuf[3]; break;
    case 0x04: P1_4=ComBuf[3]; break;
    case 0x05: P1_5=ComBuf[3]; break;
    case 0x06: P1_6=ComBuf[3]; break;
    case 0x07: P1_7=ComBuf[3]; break;
    default:
    P1=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP2()
    {
    switch(ComBuf[2])
    {
    case 0x00: P2_0=ComBuf[3]; break;
    case 0x01: P2_1=ComBuf[3]; break;
    case 0x02: P2_2=ComBuf[3]; break;
    case 0x03: P2_3=ComBuf[3]; break;
    case 0x04: P2_4=ComBuf[3]; break;
    case 0x05: P2_5=ComBuf[3]; break;
    case 0x06: P2_6=ComBuf[3]; break;
    case 0x07: P2_7=ComBuf[3]; break;
    default:
    P2=ComBuf[3];//
    8...则设置整个port状态
    }
    }
    //=================================
    void SetP3()
    {
    switch(ComBuf[2])
    {
    case 0x00: P3_0=ComBuf[3]; break;
    case 0x01: P3_1=ComBuf[3]; break;
    case 0x02: P3_2=ComBuf[3]; break;
    case 0x03: P3_3=ComBuf[3]; break;
    case 0x04: P3_4=ComBuf[3]; break;
    case 0x05: P3_5=ComBuf[3]; break;
    case 0x06: P3_6=ComBuf[3]; break;
    case 0x07: P3_7=ComBuf[3]; break;
    default:
    P3=ComBuf[3];//
    8...则设置整个port状态
    }
    }

    /*=================================
    WritePortData()

    按上位机传来的格式进行端口的设置
    =================================*/
    void WritePortData()
    {
    switch (ComBuf[1])/*Port
    */
    {
    case 0x00: SetP0(); break;
    case 0x01: SetP1(); break;
    case 0x02: SetP2(); break;
    case 0x03: SetP3(); break;
    }
    }

    /*----------------------------------
    * SetEA() *
    * *
    *
    中断允许设定,(EA寄存器) *
    * ComBuf[1]==>0x00
    EA设定 *
    * 0x01
    为读取EA *
    ------------------------------------*/
    void SetEA()
    {
    if (ComBuf[1]==0x00)
    EA=ComBuf[3];
    else
    {
    ComBuf[3]=EA;
    SendByteArray();//
    发送数据
    }
    }

    /*---------------------------------------------------------------
    * *
    * float
    型转为2char,并发送至串行 *
    * void Convert_AD_VOL_ValueToChar() *
    * *
    ---------------------------------------------------------------*/
    void Convert_AD_VOL_ValueToChar(uint vol)
    {
    float temp_float_vol;
    unsigned int temp;
    uchar AD_Hight,AD_Low;

    temp_float_vol=vol*0.0048*AD_VOL_PER;
    temp=temp_float_vol*100;
    AD_Hight=temp /100;//
    取个位数
    AD_Low=temp-AD_Hight*100;//
    2位小数
    ComBuf[2]=AD_Hight;
    ComBuf[3]=AD_Low;
    SendByteArray();//
    发送数据
    }

    /*--------------------------------
    * *
    *
    预先采集一次AD数据 *
    * *
    *--------------------------------*/
    void Befor_Once_AD()
    {
    uchar i;

    ADCLK=ADOUT=0;
    //----------
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    ADCLK=1;
    ADCLK=0;
    }
    ADCS=1;
    delay(25);//
    两次转换间隔大于21us
    }

    /*---------------------------------------------------------------
    * GetAD() TLC1549
    数据采集 *
    * sbit ADCLK=P2^0; *
    * sbit ADOUT=P2^1; *
    * sbit ADCS=P2^2; *
    -----------------------------------------------------------------*/
    void GetAD()
    {
    uchar i=1,w,PickCount;
    uint vol;

    Befor_Once_AD();//
    预先采集一次AD数据

    //---------------

    if (ComBuf[1]==0)ComBuf[1]=0x01;
    PickCount=ComBuf[1];
    for(w=1;w<=PickCount;w++)
    {
    ADCLK=ADOUT=0;
    vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    vol<<=1;
    if(ADOUT)vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    //---------------
    ComBuf[1]=w;//
    发送第几次采集的序号
    Convert_AD_VOL_ValueToChar(vol);//
    float转为2char,并发送至串行口
    P2=0xff;//p2
    口置初始状态
    }
    }



    /*---------------------------------------------------------------
    * *
    * TLC1549
    数据软件滤波采集 *
    * *
    -----------------------------------------------------------------*/
    void GetAD_With_VOL_Filter()
    {
    uchar i,w,j,k,PickCount,AD_Hight=0,AD_Low=0;
    uint Vol=0,VolArray[10],temp;
    float SumVol=0;
    Befor_Once_AD();//
    预先采集一次AD数据
    //---------------
    //---------------
    PickCount=11;
    for(w=0;w<=PickCount;w++)
    {
    ADCLK=ADOUT=0;
    Vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    Vol<<=1;
    if(ADOUT)Vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    VolArray[w]=Vol;//
    保存采集来的数据
    //---------------
    P2=0xff;//p2
    口置初始状态
    }
    //-------
    按从小到大排序--------
    //
    选择排序法..
    for(i=0;i<=PickCount-1;i++)
    {
    k=i;
    for(j=PickCount+1;j<i;j++)
    {
    if(VolArray[j]>VolArray[k])k=j;
    if(k!=i)
    {
    temp=VolArray[k];
    VolArray[k]=VolArray[i];
    VolArray[i]=temp;
    }
    }
    }
    //----------
    累加计算平静均值------------
    //
    乎略最小和最大值
    for(i=1;i<=PickCount-1;i++)
    {
    SumVol=SumVol+VolArray[i];//
    累加结果
    }
    SumVol=SumVol/(PickCount-1)*0.0048;//
    电压值=平均值*介数
    /*------------------------------
    0
    时为正常采集,1CD4051循环采集
    因为CD4051通道存在电压消耗,
    所以和正常的直接采集的校准值不一样
    -------------------------------*/
    /*
    电压校准比*/
    if(CD4051_Vol_Conver_Flag)
    SumVol*=AD_Loop_PickVol_PER;//
    采用CD4051时的电压校准值
    else
    SumVol*=AD_VOL_PER;//
    直接输入时的电压校准值

    //----------------
    temp=SumVol*100;//
    保留2位小位
    AD_Hight=temp /100;//
    取个位数
    AD_Low=temp-AD_Hight*100;//
    2位小数
    //ComBuf[1]=w;//
    发送第几次采集的序号
    ComBuf[2]=AD_Hight;
    ComBuf[3]=AD_Low;
    SendByteArray();//
    发送数据
    }



    /*-------------------------------------------------------------------------*
    * *
    * CD4051_PickVol...8
    路选通TLC1549采集 *
    * *
    *-------------------------------------------------------------------------*/
    void CD4051_PickVol()
    {
    CD4051_Vol_Conver_Flag=1;
    P1=CD4051_NUM[ComBuf[1]];//CD4051
    通道选通
    // delay(2300);//
    通道切换时间间隔,避免电路的残余电
    GetAD_With_VOL_Filter();
    CD4051_Vol_Conver_Flag=0;
    }

    /*-------------------------------------------------------------------------*
    * *
    * CD4051_LoopPickVol()...8
    路巡检TLC1549采集 *
    * *
    *-------------------------------------------------------------------------*/
    void CD4051_LoopPickVol()
    {
    uchar i=0,w;
    w=ComBuf[1]-1;//
    通导号等于。。。通道数-1
    for(;i<=w;i++)
    {
    ComBuf[1]=i;//
    通道号
    CD4051_PickVol();
    }
    P1=0xff;//
    关闭通道
    }


    /*-------------------------------------------------------------------------*
    * *
    *
    电容放电计数测试 *
    * TestCapCount() *
    * *
    *-------------------------------------------------------------------------*/
    void TestCapCount()
    {

    uint Vol,TempVol=0xff,Count=0,temp1,temp2;
    uchar i,CAPDELAYTIME;
    float TEST_CAP_OUT_value="/0.05;"
    P1=CD4051_NUM[1];//CD4051
    通道选通,1号通道
    TEST_CAP_VOL_CRLT=0;//
    打开电源
    if (ComBuf[1]==0x00)//
    0x00时为电容测量方式,0x01为电压测量方式
    {
    for(i=0;i<=ComBuf[2];i++)delay(60000);//
    等待电容充电

    TEST_CAP_VOL_CRLT=1;//
    断开电源
    TEST_CAP_OUT_value="/0.01;//
    当为电容测量时。。下限电压"
    }
    CAPDELAYTIME=ComBuf[3];//
    延时常量
    //--------------
    P1_1=0;//
    打开LED状态指示
    while(TempVol*0.0048*AD_VOL_PER>=TEST_CAP_OUT_VALUE)//
    当放电到0V时退出
    {
    ADCLK=ADOUT=0;
    Vol=0;
    ADCS=0; //
    开启控制电路,使能DATA OUTI/O CLOCK
    for(i=1;i<=10;i++)
    {
    //
    给一个脉冲
    ADCLK=1;
    Vol<<=1;
    if(ADOUT)Vol|=0x01;
    ADCLK=0;
    }
    ADCS=1;
    delay(21);//
    两次转换间隔大于21us
    //---------------
    P2=0xff;//p2
    口置初始状态
    Count++;//
    计数
    ComBuf[0]=0x05;//
    利用软件滤波的处理过程显示
    if(Count>2)TempVol=Vol;//
    第一次的取值有可能是1,,去掉不要

    Convert_AD_VOL_ValueToChar(Vol);//
    转换并发送本次数据
    Pluckdelay(CAPDELAYTIME);//
    采集间隔时间,为ComBuf[4]*1000的时间常数
    }
    //
    从高到低取
    P1=0xff;//
    初始P1

    ComBuf[0]=0x0b;
    temp1=Count/1000;//
    取前1-2
    ComBuf[1]=temp1;
    temp2=Count/10-temp1*100;//
    得到3-4
    ComBuf[2]=temp2;
    ComBuf[3]=Count-(temp1*1000+temp2*10);
    SendByteArray();//
    发送数据
    }
    //--------------------------------------------------------------------------//

    //
    写一个字节到AT24C04EEPROM
    void WriteAT24C04()
    {
    uchar address,RomData;
    address=ComBuf[1];
    RomData=ComBuf[2];
    WriteByte_24c04(RomData,address);
    }

    //
    读取AT24C04EEPROM一个字节
    void ReadAT24C04()
    {
    ComBuf[2]=ReadByte_24c04(ComBuf[1]);
    SendByteArray();//
    发送数据
    }

    //=================================
    //
    看门狗设置
    //=================================
    //void watchdog()
    //{
    //WDTRST=0x1E;
    //WDTRST=0xE1;//
    喂狗指令
    //}


    void SetLedData()
    {
    uchar ShowData,ShowBit;
    Timer_Pro_Flag=0;//0
    为显示处理,1为时序采集处理
    ShowBit=ComBuf[1];
    ShowData=LED_NUM[ShowBit];//
    选择位
    ShowData|=ComBuf[2];//
    显示内容
    LED_BIT[ShowBit]=0x00;
    LED_BIT[ShowBit]=ShowData;
    TH0=(65536-4000)>>8;
    TL0=(65536-4000)&0xff;
    TR0=ComBuf[3];
    if(ComBuf[3]) P0=0x00;//
    关闭显示
    }

    /*=========================================
    PluckPulse----
    时序采集
    ===========================================*/
    void PluckPulse()
    {
    Timer_Pro_Flag=1;//0
    为显示处理,1为时序采集处理
    OLD_TH0=ComBuf[2];
    OLD_TL0=ComBuf[3];
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=ComBuf[1];//
    关闭或启动计时器
    }
    //------------
    /*=========================================
    PWM----
    时序采集
    ===========================================*/
    void PWM()
    {
    Timer_Pro_Flag=2;//0
    为显示处理,1为时序采集处理
    OLD_TH0=ComBuf[2];
    OLD_TL0=ComBuf[3];
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=ComBuf[1];//
    关闭或启动计时器
    }

    //------------
    void timer0(void) interrupt 1 using 1
    {
    //-------------------
    switch(Timer_Pro_Flag)
    {
    case 0:
    //LED
    显示处理
    TH0=(0xffff-4000)>>8;
    TL0=(0xffff-4000)&0xff;

    if (LedCount>4) LedCount=0;
    P0=0x00;
    P0=LED_BIT[LedCount++];
    break;
    case 1:
    //
    时序采集
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    SendByte(IrDA_in_Pin);//
    发送P1^0引脚状态
    break;
    case 2://
    模拟PWM输出
    if(!PWMFlag)
    {
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=1;
    PWMFlag=1;
    PWM_Pin=0;
    }
    else
    {
    PWM_Pin=1;
    TR0=0;
    TH0=OLD_TH0;
    TL0=OLD_TL0;
    TR0=1;
    PWMFlag=0;
    }
    break;
    }
    }




    /*===================================================================

    主程序开始处
    ===================================================================*/
    void main()
    {
    //
    晶振:11.0592,波特率:19200
    TMOD=0x21;
    TL1=0xfd;
    TH1=0xfd;
    SCON=0xd8;
    PCON=0x80;//
    高位为0时不倍频:9600pbf,1时倍频:19200bpf
    TR1=1;

    //------------------
    // TMOD=0x01;//
    工作在定时器方式1,16位计数器
    TH0=(65536-4000)/256;
    TL0=(65536-4000)%256;
    ET0=1;
    EA=1;//
    中断允许
    //-------------

    while(1)
    {
    WaitComm();//
    等待接收数据
    //
    校对checksum校验码是否正确,如正确则进行相关的操作
    if(ISCheckSUM())
    {
    switch (ComBuf[0])
    {
    case 0x01:WritePortData(); break; //
    响应上位机发送的写操作
    case 0x02:SendPortData(); break; //
    响应上位机发送的读操作
    case 0x03:SetEA();break; //
    中断允许设定
    case 0x04:GetAD();break; //TLC1549
    数据采集
    case 0x05:GetAD_With_VOL_Filter();break;//
    采软件滤软件的TLC1549数据采集
    case 0x06:CD4051_PickVol();break; //CD4051--8
    1TLC1549采集
    case 0x07:CD4051_LoopPickVol();break; //8
    路巡检TLC1549采集
    case 0x08:ReadAT24C04();break; //
    读取AT24C04EEPROM一个字节
    case 0x09:WriteAT24C04();break; //
    写一个字节到AT24C04EEPROM
    case 0x0a:SetLedData();break; //
    设定显示的数据
    case 0x0b:TestCapCount();break; //
    电容放电时间计数测试
    case 0x0c:PluckPulse();break; //
    时序采集
    case 0x0d:PWM();break; //
    控制P2_7模拟输出PWM
    }
    }
    else//
    如检验错误则返回上位机错误信息
    {
    ComBuf[0]=0xFF;
    SendByteArray();//
    返回错误信息
    }
    }
    }

     

     

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明网站地图 | 名站导航 | 管理登录 | 
    本站资源部分来自互联网,如侵犯您的权利,我们将予以删除  鲁ICP备08006092号
    本站欢迎同类网站做友情链接,QQ留言
    中国IEEE 中国电气电子工程师网 版权所有