DS2438和 ad7862的驱动程序Word格式文档下载.docx
《DS2438和 ad7862的驱动程序Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《DS2438和 ad7862的驱动程序Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。
//AD7862的输入端直接接低电平,这里就不用定义A0端了。
sbittempControl=P1^0;
//温度控制输出端口
sbithumControl=P1^1;
//湿度控制输出端口
//sbitKEY1=P3^3;
//sbitKEY2=P3^4;
//sbitKEY3=P3^5;
//sbitKEY4=P3^6;
//暂时不用按键!
sbitDQ=P3^7;
ucharbdatastatus;
//DS2438中的状态标志BTTE
sbitTB=status^4;
//温度转换标志位
sbitADB=status^6;
//AD转换标志位
ucharVA1LSB,VA1MSB,secCount=0,TXDCount=0;
ucharRXData,onCommFlag,outTempFlag,outHumFlag,sendDSFlag=1,i;
uintlastTemp=0x1E00,lastHum=0x0106,TT,HT;
uintCRCData;
ucharCRCDataMsb,CRCDataLsb;
uchar*TXPtr;
//CRC校验时需要的8位指针
ucharxdataTXDataTable[207]={0};
//内部的RAM不够使用,则使用外部的RAM。
//采用CRC-CCITT:
(由欧洲CCITT推荐)G(X)=X16+X12+X5+1多项式
uintcodeCRCTable[256]=
{//CRC余式表
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};
/******************************************************************************
延时函数
函数功能:
根据用户的需要产生延时时间。
******************************************************************************/
voidDelay(unsignedcharnum)//*********us精确延时,num*1.08507*2+5.42535us.
{
while(--num);
}
voidDel(uintnum)
CRC校验
对存入串口发送数组的数据进行CRC校验!
uintgetCRC(uchar*ptr,ucharlen)
uintcrc;
ucharda;
crc=0;
while((len--)!
=0)
{
da=(uchar)(crc/256);
//以8位二进制数的形式暂存CRC的高8位
crc<
<
=8;
//左移8位,相当于CRC的低8位乘以28
crc^=CRCTable[da^*ptr];
//高8位和当前字节相加后再查表求CRC,再加上以前的CRC
ptr++;
}
return(crc);
单总线驱动函数/1-WireCommunicationThroughSoftware
单总线器件的初始化,读写BIT,读写字节。
11.0592NHZ的晶振,一个指令周期大概1.08507us
voidResetDS2438(void)//复位单总线器件
do
{
DQ=0;
Delay(220);
//标准480us,H482.85615us,num*1.08507*2+5.42535us.
DQ=1;
Delay(32);
//标准70us,I74.86983us
while(DQ);
Delay(190);
//标准410us,J417.75195us
}//复位程序调试OK
unsignedcharReadBit(void)//读一BIT并返回
unsignedcharresult;
Delay
(1);
//标准6us,A7.59549us
Delay
(2);
//标准9us,E9.76563us
result=DQ;
Delay(23);
//标准55us,F55.33857us
//DQ=1;
需要释放总线?
returnresult;
ucharReadByte(void)//读一BYTE并返回
uchari,dataTemp=0x00;
for(i=0;
i<
8;
i++)
dataTemp>
>
=1;
if(ReadBit())
dataTemp|=0x80;
}
returndataTemp;
}//调试OK
voidWriteBit(unsignedcharBit)//写一位BIT
{
if(Bit)
{//写BIT1
Delay(28);
//标准64us,B66.18927us
else
{//写BIT0
Delay(25);
//标准60us,C59.67885us
//标准10us,D9.76563us
voidWriteByte(unsignedchardataTemp)//写一BYTE
inti;
WriteBit(dataTemp&
0x01);
系统初始化
对串口,定时器,AD7862,DS2438和输出初始化
voidsystemInit(void)
tempControl=1;
humControl=1;
//温湿度控制开关关闭。
CONVEST=1;
BUSY=0;
CS=1;
READ=1;
//AD7862的初始化
TMOD=0x21;
TH0=0x3C;
TL0=0xB0;
TH1=0xFD;
TL1=0xFD;
//波特率=11059200*2的SMOD次方/12/(256-X)/32。
TR0=1;
TR1=1;
//T1只需要计数而不需要中断!
工作方式2可以自动将TH1的值重装载到TL1中。
SCON=0x50;
//串口工作方式1,允许串行接收。
最好不要对SCON进行位操作,这样就可以避开串口方式0接收数据!
郭天祥的书P144。
ET0=1;
ES=1;
PS=1;
EA=1;
//串口初始化
获得AD7862转换后的数据
对AD7862操作并将VA1,VA2通道的12位的AD值取出。
voidgetAD7862(void)
while(TXDCount<
200)
CONVEST=0;
while(BUSY);
CS=0;
READ=0;
TXDataTable[TXDCount+1]=DATALSB;
TXDataTable[TXDCount]=DATAMSB;
//读取VA1的值
TXDCount+=2;
//停止接收数据
TXDCount=0;
获得DS2438的输出数据
对DS2438操作,并将温度和湿度值值取出,存入串口发送数据数组中。
voidgetDigital(void)
ResetDS2438();
WriteByte(0xCC);
WriteByte(0x44);
//CONVERTT,Temperatureconversiontakesupto10ms
ResetDS2438();
WriteByte(0xB4);
//CONVERTV,A/Dconversiontakesupto4ms.
//Del(5000);
//0.8s,保证温湿度转换的时间。
do
WriteByte(0xB8);
WriteByte(0x00);
//IssueRecallMemorypage00hcommand
WriteByte(0xBE);
//IssueReadSP00hcommand,这两句的顺序不能变!
status=ReadByte();
//读状态寄存器
while((TB||ADB)!
=0);
TXDataTable[DSTLCount]=ReadByte();
TXDataTable[DSTMCount]=ReadByte();
//读温度的值
TXDataTable[DSHLCount]=ReadByte();
TXDataTable[DSHMCount]=ReadByte();
//读DS2438的AD的值
TT=(TXDataTable[DSTMCount]<
8)+TXDataTable[DSTLCount];
HT=(TXDataTable[DSHMCount]<
8)+TXDataTable[DSHLCount];
主程序
从外围电路获取数据,并和上位机通信。
voidmain(void)
systemInit();
while
(1)
if(onCommFlag==1)
getAD7862();
//不停的采集100个电压值,当开始通信命令先来以后
if(sendDSFlag==1)
{
//do
//{
getDigital();
//这里先不纠错!
//}//不停采集数据,但是不送到数据发送缓冲数组,而是暂存,每秒传一次。
//while(((TT-lastTemp)>
30)||((lastTemp-TT)>
30)||((HT-lastHum)>
30)||((lastHum-HT)>
30));
//在这里纠错!
//lastTemp=TT;
//lastHum=HT;
TXDataTable[STATUS]=onDS;
//温湿度数据位有效
sendDSFlag=0;
//每次CRC校验后等待下一秒时间,再进行数据交换和CRC校验,这样防止在获取AD和数字量时被T1中断,从而CRC不正确。
TXDataTable[STATUS]=offDS;
//温湿度数据位无效
TXPtr=TXDataTable;
//将要传送的数组的首地址赋给TXPer指针。
CRCData=getCRC(TXPtr,205);
TXDataTable[CRCLCount]=(uchar)CRCData;
CRCData>
TXDataTable[CRCMCount]=(uchar)CRCData;
ES=0;
//开始发送数据每次发送207字节,而且要管中断?
207;
SBUF=TXDataTable[i];
while(!
TI);
TI=0;
if(outTempFlag==1)
tempControl=0;
else
}//温度开关控制
if(outHumFlag==1)
humControl=0;
}//湿度开关控制
//串口关闭后,下位机复位。
sendDSFlag=1;
串口中断程序
接收串口数据,将串口时间标志位置一
voidserialInt(void)interrupt4using0
RI=0;
RXData=SBUF;
switch(RXData)
case(0x01):
onCommFlag=1;
//串口通信开始标志
break;
case(0x02):
onCommFlag=0;
case(0x03):
outTempFlag=1;
//温度输出标志
case(0x04):
outTempFlag=0;
case(0x05):
outHumFlag=1;
//湿度输出标志
case(0x06):
outHumFlag=0;
default:
/********************************