作者:李金浩
单片机:At89S52
连接类型:232 |485 接口
校验方式:checksum
开发环境:keil C
仅供参考学习,请勿用于商业开发.
/*************************************************************************************** * 作者:李金浩 * * E-MAIL:[email protected] * * QQ:67260745 * * 晶振:11.0592M 波特率:19200 At89S52 * * * * 模块地址设定:由P0口设定,模块地址用于多机通信 * =================================================================================== * * 0 1 2 3 4 5 6 * * |---------------------------------------------------------------------------------| * * |[操作符] | [port]| [位号] | [数据] | 模块地址 |CheckSUM |固定结束符 | * * |---------+-------+-----------------+---------+----------+----------+-------------| * * |错误:0xFF| XX | XX | XX | XX | XX | 0x7e | * * |---------+-------+-----------------+---------+----------+----------+-------------| * * |写:0x01 | 0~3 | 0~7|8为完全数据 | 数据 | XX | XX | 0x7e | * * |---------+-------+-----------------+---------+----------+----------+-------------| * * |读:0x02 | 0~3 | 0~7|8为完全数据 | XX | XX | XX | 0x7e | * * |---------+-------+-----------------+---------+----------+----------+-------------| * * |EA:0x03 | XX |00:写 .. 01读取 | 00(01) | XX | XX | 0x7e | * * |---------------------------------------------------------------------------------| *
*==========================TLC1549数据采集============================================* * ADCLK=P2^0 * * ADOUT=P2^1 * * ADCS=P2^2 * * 0 1 2 3 4 5 6 * * |---------------------------------------------------------------------------------| * * |[操作符] |采集次数 | 高位 | 低位 | 模块地址 | CheckSUM |固定结束符 | * * |---------+---------+---------------+---------+-----------+----------+------------| * * |AD:0x04 | XX | XX | XX | XX | XX | 0x7e | * * |---------------------------------------------------------------------------------| * GetAD_With_VOL_Filter:软件滤波采集 * 0 1 2 3 4 5 6 * * |----------------------------------------------------------------------------------| * * |[操作符] | 空 | 高位 | 低位 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+---------+---------------+---------+-----------+----------+-------------| * * |AD:0x05 | XX | XX | XX | XX | XX | 0x7e | * * |----------------------------------------------------------------------------------| *
8路切换采集 ---CD4051_PickVol CD4051---8选1模拟开关芯片 sbit CD4051_A=P1^1; sbit CD4051_B=P1^2; sbit CD4051_C=P1^3; sbit CD4051_INH=P1^4; //CD4051_INH为1时,,所有通导都不导通 * |----------------------------------------------------------------------------------| * | 0 1 2 3 4 5 6 | * * |----------------------------------------------------------------------------------| * * |[操作符] | 选通编号 | 高位 | 低位 | 模块地址 | CheckSUM | 固定结束符| * * |---------+-----------+---------- ----+---------+-----------+----------+-----------| * * |AD:0x06 | XX | XX | XX | XX | XX | 0x7e | * * |----------------------------------------------------------------------------------| * 0x07:8路巡检采集CD4051_LoopPickVol * |----------------------------------------------------------------------------------| * | 0 1 2 3 4 5 6 | * * |----------------------------------------------------------------------------------| * * |[操作符] | 最大通道数| 高位 | 低位 | 模块地址 | CheckSUM | 固定结束符| * * |---------+-----------+---------- ----+---------+-----------+----------+-----------| * * |AD:0x07 | XX | XX | XX | XX | XX | 0x7e | * * |----------------------------------------------------------------------------------| * *======================================================================================* *===============================AT24C04串行EEPROM操作==================================* * sbit SDA=P2^3;//SDA * * sbit SCL=P2^4;//SCL * * sbit WP=P2^5;//WP * * 0 1 2 3 4 5 6 * * |----------------------------------------------------------------------------------| * * |[操作符] | 地址 | 数据 | 片地址 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+---------+---------------+---------+-----------+----------+-------------| * * |读:0x08 | XX | XX | XX | XX | XX | 0x7e | * * |---------+---------+---------------+---------+-----------+----------+-------------| * * |写:0x09 | XX | XX | XX | XX | XX | 0x7e | * * |----------------------------------------------------------------------------------| * *======================================================================================*
*===================================4位数码管理显示====================================* * SetLedData() * * P0.0-P0.3==》显示的数据发送至74ls47 * * P0.4-P0.7==》数码管选择 * * uchar LED_BIT[4]; //用于显示的每一位数据码的内容 * * uchar LED_NUM[]={0x00,0x10,0x20,0x40,0x80};//选择显示位 * * 0 1 2 3 4 5 6 * * |-----------------------------------------------------------------------------------|* * |[操作符] | LEDNUM | 显示内容数据 | 开启/关闭 | 模块地址 | CheckSUM | 固定结束符 |* * |---------+---------+--------------+-----------+-----------+----------+-------------|* * |读:0x0A | XX | XX | XX | XX | XX | 0x7e |* * |---------+---------+--------------+-----------+-----------+----------+-------------|* * 开启/关闭===>0x00,关闭定时器中断 * * ===>0x01,开启定时器中断 * *======================================================================================*
*==================================容量测试============================================* * TestCapCount() * *电容充电控制: * * P0.0=1 断开 * * P0.1=0 闭合 * * 0 1 2 3 4 5 6 * * |----------------------------------------------------------------------------------| * * |[操作符] | 数据位1 | 数据位2 | 数据位3 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+------------+------------+---------+-----------+----------+-------------| * * | 0x0b | XX | XX | XX | XX | XX | 0x7e | * * |----------------------------------------------------------------------------------| * {上位机下传指令} 测量方式:0==>电量测方式 继电器自动开关 1==>电压采集方式 继电器等到放电结完后才关 * 0 1 2 3 4 5 6 * * |-----------------------------------------------------------------------------------| * * |[操作符] | 测量方式 |充电延时倍数| 采集间隔| 模块地址 | CheckSUM | 固定结束符 | * * |---------+------------+------------+----------+-----------+----------+-------------| * * | 0x0b | XX | XX | XX | XX | XX | 0x7e | * * |-----------------------------------------------------------------------------------| ****************************************************************************************
* 时序采集--{上位机下传指令} PluckPulse(); * 0 1 2 3 4 5 6 * * |------------------------------------------------------------------------------------| * * |[操作符] | 定时器起动 | TH0 | TL0 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+------------+------------+-----------+-----------+----------+-------------| * * | 0x0c | XX | XX | XX | XX | XX | 0x7e | * * |------------------------------------------------------------------------------------| 上传为无格式方式=====注意。。。。与现在的采集处理分开 ****************************************************************************************
* PWM输出--{上位机下传指令} PWM(); P2_7口 * 0 1 2 3 4 5 6 * * |------------------------------------------------------------------------------------| * * |[操作符] | 定时器起动 | TH0 | TL0 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+------------+------------+-----------+-----------+----------+-------------| * * | 0x0d | XX | XX | XX | XX | XX | 0x7e | * * |------------------------------------------------------------------------------------|
****************************************************************************************
*==========================未实现功能,网络接收模块选通 ===============================* * 2004-6-1 * * 当主机发送该指令时,下位如接收到的起始地址与自己相同,则进行相关操作 * * 当操作完成后,将起始地址加1,指向下一个模块地址,发送 * * 出去。其它模块接收到后重复先前的模块的作业... * * 直到:起始地址=结束地址,则完成本次作业。 * * 起始地址与自己不同,则只接收不做其它操作。 * * 该功能暂时未实际实行,假定中。。。。。HOHO... * * 0 1 2 3 4 5 6 * * |----------------------------------------------------------------------------------| * * |[操作符] | 起始地址 | 结束地址 | 空位 | 模块地址 | CheckSUM | 固定结束符 | * * |---------+------------+------------+---------+-----------+----------+-------------| * * | 0x0e | XX | XX | XX | XX | XX | 0x7e | * **************************************************************************************/
#include <stdio.h> #include <REGX51.H> #include "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时为正常采集,1为CD4051循环采集 //-------------------------- //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型转为2位char型,并发送至串行 * * 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 OUT和I/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 OUT和I/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转为2位char型,并发送至串行口 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 OUT和I/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时为正常采集,1为CD4051循环采集 因为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 OUT和I/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();//返回错误信息 } } }

|