分享
 
 
 

很久以前写的一个应用于51上面的多功能控制采集系统的..学习板内核程序

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

作者:李金浩

单片机:At89S52

连接类型:232 |485 接口

校验方式:checksum

开发环境:keil C

仅供参考学习,请勿用于商业开发.

/***************************************************************************************

* 作者:李金浩 *

* E-MAIL:LTSoft918@163.com *

* 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();//返回错误信息

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有