中科因仑“3+1”工程特种兵精英论坛
标题:
终于将温度传感器的程序做出来了,第一时间发出来给大家
[打印本页]
作者:
lucky80204
时间:
2014-7-28 18:42
标题:
终于将温度传感器的程序做出来了,第一时间发出来给大家
/*********************************************
//程序功能:使用温度传感器DS18B20测量环境温度
//接线方式:数码管的段选信号接I/O口的P0
P0^0~P0^7对应A~G DP
位选为P2^0~P2^3对应SL3-SL0
DS18B20接P2^7
//作 者:吴超
//日 期:2014/7/28
**********************************************/
#include <reg51.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define Disdata P0
#define discan P2
sbit DQ = P2^7; //DS18B20的输入输出端口
sbit DIN = P0^7; //小数点的位置
sfr P0M0 =0x94;
sfr P0M1 =0x93; //P0端口设置推挽输出的地址
uint h;
uint temp; //温度值
/**************温度小数部分用查表法***********/
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//数码管段选信号
uchar code dis_7[12]={
0x3F, //"0"的字形表,0B00111111
0x06, //"1"的字形表,0B00000110
0x5B, //"2"的字形表,0B01011011
0x4F, //"3"的字形表,0B01001111
0x66, //"4"的字形表,0B01100110
0x6D, //"5"的字形表,0B01101101
0x7D, //"6"的字形表,0B01111101
0x07, //"7"的字形表,0B00000111
0x7F, //"8"的字形表,0B01111111
0x6F, //"9"的字形表,0B01101111
0x00, // 全灭消隐
0x40, //"-"的字形表,0B01000000
};
uchar code scan_con[4]={0xFE,0xFD,0xFB,0xF7}; //列扫描控制字
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用
/***********************************************************************
//函数名称:delay(uint t)
//函数功能:延时程序 1*t us 系统时钟工作在12MHZ下,机器周期为1/12 us
_nop_()运行所需要时间为1个机器周期。do while函数占1个机器周期
t--占1个机器周期,10个_nop_()占10机器周期,共占12个机器周期
//入口参数:所要延时的时间 t t=n 就延时n us
//返回参数:无
***********************************************************************/
void delay(uint t)
{
do{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();
}while(t--);
}
/*********************************************************************
//函数名称:scan()
//函数功能:动态扫描显示温度值
//入口参数:无
//返回参数:无
*********************************************************************/
void scan()
{
char k;
for(k=0;k<4;k++)
{
Disdata = dis_7[display[k]]; //选择温度值,段选
if(k == 1)
DIN = 1; //点亮小数点
discan = scan_con[k]; //列扫描
delay(300); //延时300us
}
}
/************************************************************
//函数名称:ow_reset(void)
//函数功能:温度控制器复位。控制器Tx的复位脉冲的时间区间为480us~960us
//入口参数:无
//返回参数:无
************************************************************/
void ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;delay(8); //从高拉倒低
DQ=0;
delay(550); //复位脉冲的时间区间在480us~960us之间,本次延时550 us,进入DS18B20等待时间15~60us
DQ=1;
delay(66); //66 us 进入存在脉冲
presence=DQ; //presence=0 复位成功,继续下一步
}
delay(500); //延时500 us
presence=~DQ;
}
DQ=1; //拉高电平
}
/*写命令程序*/
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;delay(2); //从高拉倒低
DQ=0;delay(5); //5 us
DQ=val&0x01; //最低位移出
delay(66); //66 us
val=val/2; //右移1位
}
DQ=1;
delay(11); //延时11us
}
//
/****************DS18B20读1字节函数************************/
//从总线上取1个字节
uchar read_byte(void)
{
uchar i;
uchar value=0;
DQ=1;
delay(1); //延时 1us
for(i=8;i>0;i--)
{
DQ=1;
delay(2);
value>>=1;
DQ=0;delay(4); //4 us
DQ=1;delay(4); //4 us
if(DQ)
value|=0x80;
delay(66); //66 us
}
DQ=1;
return value;
}
/****************读出温度函数************************/
uint read_temp()
{
ow_reset(); //总线复位
delay(2000);
write_byte(0xcc); //发命令
write_byte(0x44); //发转换命令
ow_reset();
delay(11);
write_byte(0xcc); //发命令
write_byte(0xbe);
temp_data[0]=read_byte(); //读温度值的低字节
temp_data[1]=read_byte(); //读温度值的高字节
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 两字节合成一个整型变量。
return temp; //返回温度值
}
//
/****************温度数据处理函数************************/
//二进制高字节的低半字节和低字节的高半字节组成一字节,这个
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分
/********************************************************/
void work_temp(uint tem)
{
uchar n=0;
if(tem>6348) // 温度值正负判断
{
tem=65536-tem;
n=1; // 负温度求补码,标志位置1
}
display[4]=tem&0x0f; // 取小数部分的值
display[0]=ditab[display[4]]; // 存入小数部分显示值
display[4]=tem>>4; // 取中间八位,即整数部分的值
display[3]=display[4]/100; // 取百位数据暂存
display[1]=display[4]%100; // 取后两位数据暂存
display[2]=display[1]/10; // 取十位数据暂存
display[1]=display[1]%10; // 去个位数据暂存
/******************符号位显示判断**************************/
if(!display[3])
{
display[3]=0x0a; //最高位为0时不显示
if(!display[2])
{
display[2]=0x0a; //次高位为0时不显示
}
}
if(n)
{
display[3]=0x0b; //负温度时最高位显示"-"
}
}
/****************主函数************************/
void main()
{
P0M1 = 0x00;
P0M0 = 0xFF; //P0端口设置成推挽输出
Disdata=0x00; //初始化端口
discan=0x00;
for(h=0;h<4;h++) //开机显示"00.00"
{
display[h] = 0;
}
ow_reset(); //开机先转换一次
write_byte(0xcc); //Skip ROM
write_byte(0x44); //发转换命令
for(h=0;h<100;h++) //开机显示"00.00"
{
scan();
}
while(1)
{
work_temp(read_temp()); //处理温度数据
scan(); //显示温度值
}
}
复制代码
作者:
lucky80204
时间:
2014-7-28 18:44
代码有点长,没有进行分类,注释也不是很清楚,不好意思啊,各位看官见谅啊
作者:
伊海
时间:
2014-7-29 08:34
漂亮,
作者:
enlernzhang
时间:
2014-7-29 09:04
非常好,支持!!!
作者:
还你一世界
时间:
2014-7-29 11:41
这么牛逼!!毕业设计就靠他了!
作者:
SDC158477392
时间:
2014-7-29 15:23
不错不错,你知道代码不规范还不改,快回去改改
作者:
lucky80204
时间:
2014-7-29 15:56
我在改啊,等改好了,在编辑
作者:
墨奚
时间:
2014-7-30 11:04
整整两百多行
作者:
张衍波
时间:
2014-8-3 09:25
真牛,,
作者:
hxh
时间:
2014-8-6 09:06
来,精简精简
作者:
enlernzhang
时间:
2014-8-6 11:01
厉害厉害
作者:
jerryzhai
时间:
2014-8-7 08:57
preaty good
作者:
张衍波
时间:
2014-8-7 15:34
ding ,,,,,,,,,,,,,,,,,,,,
作者:
伊海
时间:
2014-8-10 15:46
写的不错,反复学习
作者:
dengjia
时间:
2014-8-18 16:30
可以赞一个
欢迎光临 中科因仑“3+1”工程特种兵精英论坛 (http://bbs.enlern.com/)
Powered by Discuz! X3.4