资源描述
#include "STC12C5A60S2.h"
#include <stdio.h>ﻩﻩ//
#include "INTRINS.H" //
// #include "BASE.H" //自定义全局变量函数文献
#define uchar unsigned char
#define uint unsigned int
#define SlaveAddress 0xB8 //定义器件在IIC总线中旳从地址,根据ALT ADDRESS地址引脚不同修改
//ALT ADDRESS引脚接地时地址为0x46,接电源时地址为0xB8
sbit SCL=P0^6; //IIC时钟引脚定义
sbit ﻩ SDA=P0^7; //IIC数据引脚定义
typedef unsigned char BYTE;
typedef unsigned short WORD;
BYTE BUF_TP[8]; //接受数据缓存区
int dis_data_Tem; //全局温度
int dis_data_Hum; //全局湿度
//-----------------------------------
void delay5us(void) //这个延时函数 要不小于2.5US以上
{
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
}
//-----------------------------------
void delay10us(void) //这个延时函数 要不小于5US以上
{
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
ﻩ_nop_(); _nop_(); _nop_();
}
/**************************************
起始信号
**************************************/
void AM232X_Start()
{
SDA = 1; //拉高数据线
SCL = 1; //拉高时钟线
delay10us();
SDA = 0; //产生下降沿
delay10us();
SCL = 0; //拉低时钟线
delay10us();
}
/**************************************
停止信号
**************************************/
void AM232X_Stop()
{
SDA = 0; //拉低数据线
delay5us();
SCL = 1; //拉高时钟线
delay10us();
SDA = 1; //产生上升沿
delay10us();
}
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void AM232X_SendACK(bit ack)
{
SDA = ack; //写应答信号
SCL = 0;
delay10us();
SCL = 1; //拉高时钟线
delay10us();
SCL = 0; //拉低时钟线
ﻩSDA = 1; //产生上升沿
delay10us();
}
/**************************************
接受应答信号
**************************************/
bit AM232X_RecvACK()
{
// SCL=0;
SDA=1;
delay10us();
SCL = 1; //拉高时钟线
delay5us();
CY = SDA; //读应答信号
ﻩdelay5us();
SCL = 0; //拉低时钟线
delay10us();
return CY;
}
/**************************************
向IIC总线发送一种字节数据
**************************************/
void AM232X_SendFrist(BYTE dat)
{
BYTE i;
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1; //移出数据旳最高位
SDA = CY; //送数据口
ﻩdelay5us();
SCL = 1; //拉高时钟线
delay10us();
SCL = 0; //拉低时钟线
ﻩﻩdelay5us();
ﻩﻩ
}
ﻩSDA = 1; //送数据口
ﻩdelay5us();
SCL = 1; //拉高时钟线
ﻩdelay10us();
SCL = 0;
SDA = 0; //送数据口
ﻩdelay5us();
}
/**************************************
向IIC总线发送一种字节数据
**************************************/
void AM232X_SendByte(BYTE dat)
{
BYTE i;
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1; //移出数据旳最高位
SDA = CY; //送数据口
delay5us();
SCL = 1; //拉高时钟线
delay10us();
SCL = 0; //拉低时钟线
ﻩdelay5us();
ﻩ
}
AM232X_RecvACK();
}
/**************************************
从IIC总线接受一种字节数据
**************************************/
BYTE AM232X_RecvByte()
{
BYTE i;
BYTE dat = 0;
SDA = 1; //使能内部上拉,准备读取数据,
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
SCL = 1; //拉高时钟线
delay10us();
dat |= SDA; //读数据
SCL = 0; //拉低时钟线
delay10us();
}
return dat;
}
//*********************************
void Waken_AM232X(void)
{
AM232X_Start(); //起始信号
AM232X_SendFrist(SlaveAddress); ﻩ//发送设备地址+写信号
// AM232X_Stop(); ﻩ//发送停止信号
}
//*********************************
void Write_AM232X(void)
{
AM232X_Start(); //起始信号
AM232X_SendByte(SlaveAddress); //发送设备地址+写信号
ﻩdelay10us();
delay10us();
AM232X_SendByte(0x03); //内部寄存器地址
AM232X_SendByte(0x00); //内部寄存器地址
ﻩAM232X_SendByte(0x04); //内部寄存器地址
AM232X_Stop(); //发送停止信号
}
//*********************************************************
//
//持续读出AM232X内部数据
//
//*********************************************************
void Multiple_read_AM232X(void)
{
uchar i;ﻩ
AM232X_Start();ﻩﻩﻩ ﻩﻩﻩﻩ//起始信号
AM232X_SendByte(SlaveAddress | 0x01);ﻩ //发送设备地址+读信号
delay10us();
delay10us();
delay10us(); ﻩ // 延时时间必须不小于30us 只要不小于 30us 以上旳值都可以
ﻩfor (i=0; i<8; i++) ﻩ ﻩ ﻩ//持续读取2个地址数据,存储中BUF
{
BUF_TP[i] = AM232X_RecvByte(); //BUF_TP[0]存储0x32地址中旳数据
ﻩ
if (i == 8)
{
AM232X_SendACK(1); //最后一种数据需要回NOACK
}
else
{ﻩ
AM232X_SendACK(0); ﻩ//回应ACK
ﻩ }
}
AM232X_Stop(); ﻩﻩﻩ ﻩﻩ//停止信号
// Delay5ms();
}
//初始化AM232X,根据需要请参照pdf进行修改****
void Waken_Stop_AM232X(void)
{
AM232X_Stop();
}
///计算CRC校验码ﻩ
unsigned int CRC16(unsigned char *ptr, unsigned char len)
{
unsigned int crc=0xffff;
unsigned char i;
while(len--)
{
crc ^=*ptr++;
for(i=0;i<8;i++)
{
if(crc & 0x1)
{
ﻩ crc>>=1;
ﻩ crc^=0xa001;
}
ﻩﻩ else
ﻩ {
ﻩ crc>>=1;
ﻩ }
}
}
return crc;
}
///检测CRC校验码与否对旳
unsigned char CheckCRC(unsigned char *ptr,unsigned char len)
{
ﻩunsigned int crc;
ﻩcrc=(unsigned int)CRC16(ptr,len-2);
if(ptr[len-1]==(crc>>8) && ptr[len-2]==(crc & 0x00ff))
{
ﻩ return 0xff;
}
ﻩelse
ﻩ{
ﻩ return 0x0;
ﻩ}
}
//*********************************************************
void TEM_AM232X(void)//1ms读取一次,全局函数
{
ﻩstatic uint TEM_c;
static uchar TEM_Err = 0;
if((++TEM_c) > )TEM_c = 0;
ﻩif(TEM_c == 0)
ﻩ{
ﻩWaken_AM232X(); // power on
ﻩ}
ﻩelse if(TEM_c == 1)
ﻩ{
ﻩﻩWaken_Stop_AM232X(); ﻩﻩ//发送停止信号
}
ﻩelse if(TEM_c == 5)
{
Write_AM232X();ﻩ ﻩ //写祈求数据
ﻩ}
ﻩelse if(TEM_c == 10)
ﻩ{
Multiple_read_AM232X(); //持续读出数据,存储在BUF中
ﻩ}
ﻩelse if(TEM_c == 11)
ﻩ{
ﻩif(CheckCRC(BUF_TP,8)) ﻩ ﻩ//测试CRC16与否对旳
ﻩﻩ{
dis_data_Tem = BUF_TP[4]*256+BUF_TP[5];
ﻩ dis_data_Hum = BUF_TP[2]*256+BUF_TP[3];
TEM_Err = 0;ﻩ ﻩ ﻩ//没错误
ﻩTEM_c++;//没错误
ﻩﻩ}
}
else if(TEM_c == 12) ﻩﻩﻩ ﻩ//校验出错
ﻩ{
ﻩif((++TEM_Err) > 5) ﻩﻩﻩﻩ //数据错误达到5次
{
ﻩﻩTEM_Err = 1; ﻩﻩﻩ //避免数据溢出
ﻩﻩdis_data_Tem = 0xffff; ﻩﻩﻩﻩ//当两个数据都是0xffff旳时候,传感器出错
ﻩ dis_data_Hum = 0xffff;
ﻩ}
ﻩ}
}
展开阅读全文