📄 新建 文本文档 (2).txt
字号:
#include <AT89X52.H>
#include <INTRINS.h>
#ifndef I2C_H
#define I2C_H
typedef unsigned char uchar; //重新定义数据类型
typedef unsigned int uint;
const uchar WR24C02 = 0xa0; //读写控制命令 //EEPROM地址+写命令
const uchar RD24C02 = 0xA1; //EEPROM地址+读命令
sbit I2C_SCL = P2^4; //I/O口定义
sbit I2C_SDA = P2^4;
bit ErrorBit; //用户变量声明 //读写错误标志 1错误 0 正确
uchar idata ErrorCode; //错误码
uchar date_txd[18]={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8}; //发送数据存放数组
uchar date_rxd[18]={0}; //接收数据存放数组
uchar da=0;
//************************函数声明***************************
void Start(void);
void Stop(void);
void Ack(void);
void NoAck(void);
void TestAck(void);
void Write_I2c(uchar date);
uchar Read_I2c(void);
void DelayMs(uchar time);
void Write_Date(uchar StartAddress,uchar *date,uchar bytes);
void Read_Date(uchar StartAddress,uchar *date,uchar bytes);
#endif
unsigned char code Tab[]={0xff,0Xfd,0xff,0xfe,0xff,0xf7,0xff,0xfb,0xff,0xdf,0xff,0xef,0xff,0x7f,0xff,0xbf,
0Xfd,0xff,0xfe,0xff,0xf7,0xff,0xfb,0xff,0xdf,0xff,0xef,0xff,0x7f,0xff,0xbf,0xff};
unsigned char code codedisplay[]={0xFF,0xFF,0xFF,0xE7,0xDB,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xDB,0xE7,0xFF,0xFF,/*"0",0*/
0xFF,0xFF,0xFF,0xEF,0x8F,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"1",1*/
0xFF,0xFF,0xFF,0xC3,0xBD,0xBD,0xBD,0xFB,0xFB,0xF7,0xEF,0xDF,0xBD,0x81,0xFF,0xFF,/*"2",2*/
0xFF,0xFF,0xFF,0xC3,0xBD,0xBD,0xFB,0xE7,0xFB,0xFD,0xFD,0xBD,0xBB,0xC7,0xFF,0xFF,/*"3",3*/
0xFF,0xFF,0xFF,0xFB,0xF3,0xEB,0xDB,0xDB,0xBB,0xBB,0x81,0xFB,0xFB,0xE1,0xFF,0xFF,/*"4",4*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0xA7,0x9B,0xFD,0xFD,0xBD,0xBB,0xC7,0xFF,0xFF,/*"5",5*/
0xFF,0xFF,0xFF,0xE3,0xDB,0xBF,0xBF,0xA7,0x9B,0xBD,0xBD,0xBD,0xDB,0xE7,0xFF,0xFF,/*"6",6*/
0xFF,0xFF,0xFF,0x81,0xBB,0xBB,0xF7,0xF7,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xFF,0xFF,/*"7",7*/
0xFF,0xFF,0xFF,0xC3,0xBD,0xBD,0xBD,0xDB,0xE7,0xDB,0xBD,0xBD,0xBD,0xC3,0xFF,0xFF,/*"8",8*/
0xFF,0xFF,0xFF,0xE7,0xDB,0xBD,0xBD,0xBD,0xD9,0xE5,0xFD,0xFD,0xDB,0xC7,0xFF,0xFF};/*"9",9*/
unsigned char m;
unsigned int result,count=0;
void Start(void)
{ I2C_SDA = 1; //起始条件的数据信号
_nop_();
I2C_SCL = 1; //起始条件时钟信号
_nop_(); //信号建立时间>4.7us
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SDA = 0; //起始信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SCL = 0; //钳住I2C总线, 准备发送或者接受数据
_nop_();
_nop_();
}
void Stop(void)
{ I2C_SDA = 0; //结束条件的数据信号
_nop_();
I2C_SCL = 1; //结束条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SDA = 1; //结束信号
_nop_();
_nop_();
_nop_();
_nop_();
}
void Ack(void)
{ I2C_SDA = 0;
_nop_();
_nop_();
I2C_SCL = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SCL = 0;
_nop_();
_nop_();
I2C_SDA = 1;
}
void NoAck(void)
{ I2C_SDA = 1;
_nop_();
_nop_();
I2C_SCL = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SCL = 0;
_nop_();
_nop_();
}
void TestAck(void)
{ I2C_SDA = 1;
_nop_();
_nop_();
I2C_SCL = 1;
_nop_();
_nop_();
_nop_();
ErrorBit = I2C_SDA;
I2C_SCL = 0;
_nop_();
_nop_();
}
void Write_I2c(uchar date)
{ uchar i;
for(i=0;i<8;i++)
{
I2C_SDA=date&0x80; //送数据到数据线上
date<<=1;
_nop_();
I2C_SCL=1; //置时钟信号为高电平,使数据有效
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SCL=0;
_nop_();
_nop_();
}
}
uchar Read_I2c(void)
{ uchar i;
uchar byte = 0;
for(i = 0; i < 8; i++)
{ I2C_SCL = 0; //置时钟为低电平,准备接受数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
I2C_SCL = 1; //置时钟为高电平,使数据线数据有效
_nop_();
_nop_();
byte <<= 1;
byte |= I2C_SDA;
_nop_();
_nop_();
I2C_SCL = 0;
}
return(byte);
}
void DelayMs(uchar time)
{ uchar i;
do
{ for(i = 0; i < 125 ; i++); //*延时 8us x 125 = 1ms
}
while (time--);
}
void Write_Date(uchar StartAddress,uchar *date,uchar bytes)
{ uchar i = 0;
Start();
Write_I2c(WR24C02);
TestAck();
Write_I2c(StartAddress);
TestAck();
for(i = 0;i < bytes; i++)
{
Write_I2c(*date);
TestAck();
date++;
}
Stop();
DelayMs(20);
}
void Read_Date(uchar StartAddress,uchar *date,uchar bytes)
{ uchar i;
Start();
Write_I2c(WR24C02);
TestAck();
Write_I2c(StartAddress);
TestAck();
Start();
Write_I2c(RD24C02);
TestAck();
for (i = 0; i < bytes; i++)
{
*date= Read_I2c();
Ack();
date++;
}
NoAck();
Stop();
DelayMs(10);
}
void delay(void)
{ unsigned char i,j;
for(i=0;i<15;i++){ for(j=0;j<50;j++) ; }
}
unsigned char displaycount,x;
unsigned char displaybuf[8]={0,0,0,0,0,0,0,0};
unsigned char timecount;
unsigned char readdata[8];
unsigned long a,aa,bb;
sbit DQ=P2^6; //选P3.7口与DS18B20的数字信号输出端DQ相连
bit sflag;
bit resetpulse(void) //DS18B20初始化实现对DS18B20的复位
{ unsigned char pre;
unsigned char i;
DQ=0; //发出复位脉冲,将数据线下拉480μS-960μS
for(i=220;i>0;i--); //(改!!!!!!!!!!!!!!!!!!!!)
DQ=1; //DS18B20等待15μS-60μS
for(i=60;i>0;i--);
pre=DQ;
for(i=150;i>0;i--);
return(pre); // DS18B20返回60μS-240μS存在低脉冲,判断是否准备好接受或发送数据
}
void writecommandtods18b20(unsigned char command) //写时序
{
unsigned char i;
unsigned char j;
for(i=0;i<8;i++)
{
if((command & 0x01)==0) //写0时序
{
DQ=0; //拉低单总线至少60μS,保证DS18B20在15μS-45μS时可以正确地采样I/O总线上的低电平
for(j=35;j>0;j--);
DQ=1;
}
else //写1时序
{
DQ=0; //拉低单总线后,在15us之内就得释放
for(j=2;j>0;j--);
DQ=1;
for(j=33;j>0;j--);
}
command=_cror_(command,1);
}
}
unsigned char readdatafromds18b20(void) //读时序
{
unsigned char i;
unsigned char j;
unsigned char temp;
temp=0;
for(i=0;i<8;i++)
{
temp=_cror_(temp,1);
DQ=0; //单总线拉低后,读时序开始
_nop_();
_nop_();
DQ=1; //停止将数据线拉低,以读取数据
for(j=10;j>0;j--);
if(DQ==1)
{
temp=temp | 0x80;
}
else
{
temp=temp | 0x00;
}
for(j=20;j>0;j--); ////////////////////(改!!!!!!!!!!!!)
}
return(temp);
}
void main(void)
{ SCON=0;
Write_Date(0,date_txd,8);
Read_Date(0,date_rxd,8);
//while(resetpulse()); //写前调用初始化程序对DS18B20复位
//writecommandtods18b20(0xcc); //单片DS18B20工作,跳过读ROM中64位地址的过程
//writecommandtods18b20(0x44); //启动DS18B20进行温度转化,将结果存入内部RAM中
while(1)
{
for(m=0;m<16;m++)
{ SBUF=codedisplay[date_rxd[0]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[1]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[2]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[3]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[4]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[5]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[6]*16+m]; while(!TI) ; TI=0;
SBUF=codedisplay[date_rxd[7]*16+m]; while(!TI) ; TI=0;
//P2_0=0;P2_1=0;P2_1=1;P2_1=0;P2_0=1;
SBUF=Tab[2*m]; while(!TI) ; TI=0;
SBUF=Tab[2*m+1];while(!TI) ; TI=0;
P3_4=0;P3_4=1; P3_4=0;
delay();
/* count++;
if(count==600)
{ count=0;
while(resetpulse()); //写前调用初始化程序对DS18B20复位
writecommandtods18b20(0xcc); //单片DS18B20工作,跳过读ROM中64位地址的过程
writecommandtods18b20(0xbe); // 读DS18B20RAM中温度数据
readdata[0]=readdatafromds18b20(); //温度数据低8位赋值
readdata[1]=readdatafromds18b20(); //温度数据高8位赋值
sflag=0;
if((readdata[1] & 0xf8)!=0x00) //温度数据高5位为1时,温度为负值
{
sflag=1;
readdata[1]=~readdata[1]; //对负温度值进行取反加1操作
readdata[0]=~readdata[0];
result=readdata[0]+1;
readdata[0]=result;
if(result>255)
{
readdata[1]++;
}
}
readdata[1]=readdata[1]&0x07; //将代表符号的高5位数屏蔽
aa=625;bb=(readdata[1]*256+readdata[0]);
a=bb*aa; //计算实际温度值
displaybuf[0]=a/100000; //给各显示位赋温度值
displaybuf[1]=a%100000/10000;
displaybuf[2]=a%10000/1000;
displaybuf[3]=a%1000/100;
displaybuf[4]=a%100/10;
displaybuf[5]=a%10;
while(resetpulse());
writecommandtods18b20(0xcc);
writecommandtods18b20(0x44);
}*/
}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -