单片机用AT89S52,使用的温度传感器是18B20,可以测量并存储当前温度,使用I2C总线协议

2024-11-26 15:02:10
推荐回答(3个)
回答1:

这是我用51编写的,希望对你有帮助

//调用一次读取温度,所有点的温度值就都保存到数组中了,对这个数组就可以随意操作了
//实现多点采样,一个18b20占用一个I/O口,同样是采用轮询的方式采样,不过这里只有读取数据时是采用轮询的,
//写数据是同时进行的,直到发送温度转换指令,这就节省的很多时间,也就是轮询一次只需要等待原来的一次的转换时间,
//读取和原来独立是一样。(即同时转换,轮流读取)
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////磨没////////////////////////////////////////////////////////////////////////////////////////////////////////////////////桐告////////////
/*********************************************************************************/
// 18b20子程局游明序
/*********************************************************************************/
/************************ROM操作命令代码:
读取ROM 0x33
匹配ROM 0x55 发送该命令后,接着发送64位ID编号,之后就可以直接发送操作命令,这时只有匹配的才做出响应。
搜索ROM 0xf0
跳过ROM 0xCC
告警搜索指令 0xec

*************************RAM操作命令代码:
温度转换 0xbe
读取暂存器 0xbe
写入暂存器 0x4e 发出向内部RAM 3、4字节写上下限温度数据命令 区分于写功能(用来写入所有指令的)
复制RAM到EEPROM 0x48 对RAM中第3、4字节的操作
恢复EEPROM到RAM 0xb8
读取供电方式 0xb4 寄生供电时18b20发回“0”,外接电源供电发回“1”。

**********************************************************************************/
/*********************************************************************************/
#define port P2 //定义18b20端口
sbit buzzer=P1^3; //蜂鸣器端口
unsigned char account; //定义全局变量
/**************************改变端口采样点用的数组*********************************/
unsigned char change[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f} ;
unsigned char change2[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80} ;
/*********************************************************************************/
/**************************温度存储用数组*****************************************/
unsigned char save_temp[8]={0};
/*********************************************************************************/
//164显示程序
/*********************************************************************************/
unsigned char sheet[]={0x11,0x7D,0x23,0x29,0x4D,0x89,0x81,0x3D,0x01,0x09};
sbit disp_data=P1^0;
sbit disp_clk=P1^1;
void disp_164(unsigned int x)
{
unsigned char i,j=4,k;
while(j--)
{
k=sheet[x%10];
for(i=0;i<8;i++)
{
if(k&0x01)disp_data=1;
else disp_data=0;
disp_clk=0;disp_clk=1;disp_clk=0;
k=k>>1;
}
x/=10;
}
}
/*********************************************************************************/
//18b20初始化
/*********************************************************************************/
void Init18B20(void)
{
unsigned char qq=0;
port=0; //DQ=0;
qq=250;while(qq)qq--; //Delay15(33);//至少延时480us
port=0xff; //DQ=1;
qq=75;while(qq)qq--; //Delay15(10);//至少延时100us
//if(DQ==1) return 0; //初始化失败
// else return 1;
//DQ=1; Delay15(18);
}
/*********************************************************************************/
//18b20读取一个字节
/*********************************************************************************/
unsigned char Read18B20(void)
{
unsigned char i,temp,qq=0;
for(i=0;i<8;i++)
{
temp=temp>>1;
port&=change[account]; //DQ=0;
qq++; //_nop_();
port=0xff; //DQ=1;
qq=2;while(qq)qq--; //_nop_();_nop_();_nop_();_nop_();
if(port&change2[account]/*DQ==1*/)
{temp=temp|0x80;}
else
{temp=temp&0x7f;}
qq=15;while(qq)qq--; //Delay15(3);
port=0xff; //DQ=1;
}
return (temp);
}
/*********************************************************************************/
//18b20写一个字节
/*********************************************************************************/
void Write18B20(unsigned char temp)
{
unsigned char i,qq=0;
for(i=0;i<8;i++)
{
port=0; //port&=change[account];//DQ=0;
qq=7;while(qq)qq--; //Delay15(1);
if(temp&0x01)port=0xff; //DQ=ch&0x01;
else port=0; //port&=change[account];
qq=22;while(qq)qq--; //Delay15(3);
port=0xff; //DQ=1;
temp=temp>>1;
qq++; //_nop_();
}
}
/*********************************************************************************/
//读取温度值
/*********************************************************************************/
void get_temp()
{
unsigned char qq=0;
unsigned int TemH,TemL,temp,save=0,kk=0;
Init18B20();
Write18B20(0xCC); //跳过ROM
qq++; // _nop_();
Write18B20(0x44); //发送温度转换指令
qq=100;while(qq)qq--; //Delay10ms(25);//等待1s转换
Init18B20();
Write18B20(0xCC); //跳过ROM
Write18B20(0xBE); //发送温度转换指令
for(account=0;account<8;account++)//设定采样点的数量
{
TemL=Read18B20(); //读低位温度值
TemH=Read18B20(); //读高位温度值
//Delay10ms(2);
temp=(TemH<<4)|(TemL>>4);
if(save_temp[account]!=temp)
save_temp[account]=temp; //只有当前采样值和前一次不同时才保存
}

//return(TemH);
}
/*********************************************************************************/
/*********************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/***************************************************************************************/
// 矩阵键盘
/***************************************************************************************/
/******************************************/////****************************************/
/*****需要修改的参数*****/
/******************************************/////****************************************/
sbit horizontal1=P3^2; sbit vertical1=P1^7;
sbit horizontal2=P3^3; sbit vertical2=P1^6;
sbit horizontal3=P3^4; sbit vertical3=P1^0;
sbit horizontal4=P3^5; sbit vertical4=P2^3;
sbit horizontal5=P0^3; sbit vertical5=P2^4;
sbit horizontal6=P0^5; sbit vertical6=P2^5;
sbit horizontal7=P0^6; sbit vertical7=P2^6;
sbit horizontal8=P0^7; sbit vertical8=P2^7;

#define HANG 4
#define LIE 1
//sbit buzzer=P1^3;
#define vertical_check vertical1//&vertical2 //只有列数变化时要进行修改
unsigned char code key_tab[HANG][LIE]={1,
2,
3,
4
};
/******************************************/////****************************************/
/******************************************/////****************************************/
/***************************************************************************************/
/***************************************************************************************/
void key_init()
{
horizontal1=1; vertical1=1;
horizontal2=1; //vertical2=1;
horizontal3=1; //vertical3=1;
horizontal4=1; //vertical4=1;
//horizontal5=1; vertical5=1;
//horizontal6=1; vertical6=1;
//horizontal7=1; vertical7=1;
//horizontal8=1; vertical8=1;

}

/***************************************************************************************/
/***************************************************************************************/
void key_check()
{
horizontal1=0; vertical1=1;
horizontal2=0; //vertical2=1;
horizontal3=0; //vertical3=1;
horizontal4=0; //vertical4=1;
//horizontal5=0; vertical5=1;
//horizontal6=0; vertical6=1;
//horizontal7=0; vertical7=1;
//horizontal8=0; vertical8=1;
}
/**************************************************************************************/
/**************************************************************************************/

unsigned char get_vertical()
{
unsigned char temp=LIE, vertical_temp=0;
if(vertical1)
{
//P0=0x0f;
vertical_temp++;
if(--temp==0)goto eend;
if(vertical2)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical3)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical4)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical5)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical6)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical7)
{
vertical_temp++;
if(--temp==0)goto eend;
if(vertical8)
{
goto eend;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;
}
else goto eend ;

eend: ;
return(vertical_temp);
}
/***************************************************************************************/
/***************************************************************************************/
unsigned char get_key()
{
unsigned char horizontal=0,vertical=0,key_resault;
unsigned char delay1,delay2,temp;
key_init();
key_check();
if(vertical_check) goto key_over; //判断是否有按键按下,有按键按下时vertical_check为0,没有按键按下时vertical_check不为0
buzzer=0;
delay1=250;
while(delay1){delay1--;delay2=4;while(delay2)delay2--;} //延时5ms
buzzer=1;
key_init();
key_check();
if(vertical_check) goto key_over;
key_init();
for(temp=0;temp {

switch(temp)
{
case 0:{horizontal1=0;vertical=get_vertical();break;} //判断第1行是否有按键按下
case 1:{horizontal2=0;vertical=get_vertical();break;} //判断第2行是否有按键按下
case 2:{horizontal3=0;vertical=get_vertical();break;} //判断第3行是否有按键按下
case 3:{horizontal4=0;vertical=get_vertical();break;} //判断第4行是否有按键按下
case 4:{horizontal5=0;vertical=get_vertical();break;} //判断第5行是否有按键按下
case 5:{horizontal6=0;vertical=get_vertical();break;} //判断第6行是否有按键按下
case 6:{horizontal7=0;vertical=get_vertical();break;} //判断第7行是否有按键按下
case 7:{horizontal8=0;vertical=get_vertical();break;} //判断第8行是否有按键按下
default:break;
}
if(vertical==LIE) // 该行没有检测到按键按下,进行下一行
{
horizontal++;
}
else //检测到该行有按键按下,就要跳出不再检测了
{
key_resault=key_tab[horizontal][vertical]; goto key_over;
}
}

key_over:
return(key_resault);
}
/***************************************************************************************/
main()
{
unsigned char i=0,temp;
unsigned int kk=0;
while(1)
{
// for(j=0;j<6;j++) //设置要显示的采样点的数量
{

get_temp(); //调用一次读取温度,所有点的温度值就都保存到数组中了,接下来就可以随意的显示了
/*i++;
if(i!=50) goto tiaozhuan; //相当于延时
{
i=0;
P0=change[j]; //LED指示采样点的位置
buzzer=0; //蜂蜜器提示
kk=5000;
while(kk)kk--;
buzzer=1;
//disp_164(save_temp[j]);
} */
}
temp=get_key();
disp_164(save_temp[temp]);
}
}

回答2:

18B20,我记码带得应该是1-WIRE总迟扰芦线,即单线总线。你李袜应该还少了一个EEPROM吧?I2C总线应该是对存储器进行数据传输的协议吧?这种程序网上应该有的,你搜索一下。

回答3:

h我可以做的