给你一个DS18B20的温度采集程序!
//ICC-AVR application builder : 2009-10-25 10:43:39
// Target : M16
// Crystal: 16000Mhz
#include <iom16vh>
#include <macrosh>
#define uint unsigned int
#define uchar unsigned char
#include "xianshic"
#include "delayh"
#define CLR_DIR_1WIRE DDRD&=~BIT(4) //只要修改这里的参数就可以了
#define SET_DIR_1WIRE DDRD|=BIT(4) //里面什么都不用该!
#define CLR_OP_1WIRE PORTD&=~BIT(4)
#define SET_OP_1WIRE PORTD|=BIT(4)
#define CHECK_IP_1WIRE (PIND&0x10) //检测
unsigned char wmh,wml;
void init_1820()
{
SET_DIR_1WIRE; //设置PD4 为输出
SET_OP_1WIRE;
CLR_OP_1WIRE;
delay_nus(480); //480us以上
SET_OP_1WIRE;
CLR_DIR_1WIRE;
delay_nus(20); //15~60us
while(CHECK_IP_1WIRE);
SET_DIR_1WIRE;
SET_OP_1WIRE;
delay_nus(140); //60~240us
}
void write_1820(unsigned char x)
{
unsigned char m;
for(m=0;m<8;m++)
{
CLR_OP_1WIRE;
if(x&(1<<m)) //写数据了,先写低位的!
SET_OP_1WIRE;
else
{CLR_OP_1WIRE;}
delay_nus(40); //15~60us
SET_OP_1WIRE;
}
SET_OP_1WIRE;
}
unsigned char read_1820()
{
unsigned char temp,k,n;
temp=0;
for(n=0;n<8;n++)
{
CLR_OP_1WIRE;
SET_OP_1WIRE;
CLR_DIR_1WIRE;
k=(CHECK_IP_1WIRE); //读数据,从低位开始
if(k)
temp|=(1<<n);
else
temp&=~(1<<n);
delay_nus(50); //60~120us
SET_DIR_1WIRE;
}
return (temp);
}
unsigned int gettemp() //读取温度值
{
unsigned char temh,teml,wm0,wm1,wm2,wm3;
init_1820(); //复位18b20
write_1820(0xcc); // 发出转换命令
write_1820(0x44);
// delay_nms(800); //不延时也好使,不知道怎么回事!
init_1820();
write_1820(0xcc); //发出读命令
write_1820(0xbe);
teml=read_1820(); //读数据
temh=read_1820();
wm0=teml>>4; //只要高8位的低四位和低8位的高四位,温度范围0~99啦!
wm1=temh<<4;
wm2=wm1+wm0; //16进制转10进制
return wm2;
}
void main()
{
uint tem,ad[4],i;
port_init();
while(1)
{
tem = gettemp();
for(i=0;i<4;i++)
{
ad[3-i]=tem%10;
tem=tem/10;
}
for(i=0;i<4;i++)
{
show1(ad[i],i);
delay(5);
}
}
}
显示函数:
#include <iom16vh>
#include <macrosh>
#define uint unsigned int
#define uchar unsigned char
#pragma data:code
const uint tab1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00}; //共阳数码管代码表
const uint tab2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00};//共阴数码管代码表
void port_init(void)
{
DDRA = 0xFF;
DDRB = 0xFF;
DDRC = 0xFF;
DDRD = 0x00;
}
void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
void show1(uchar j,uchar k)//显示函数
{
PORTB = ~BIT(k);
PORTA = tab2[j];
delay(1);
}
void show(uint ada)
{
uint i,ad[4];
for(i=0;i<4;i++)
{
ad[3-i]=ada%10;
ada = ada/10;
}
while(1)
{
for(i=0;i<4;i++)
{
show1((ad[i]),i);
delay(100);
}
}
}
程序我都调试过的,都是好的,有不会再问我。可以给分了吗?嘿嘿
这是我自己用过的DS18B20的程序,有什么问题可以百度HI我,我这个是把温度显示到电脑上了,如果你要显示到LCD上的话可以在里面加一些子程序。
#include<reg52h>
#include<stdioh>
#define uint unsigned int
#define uchar unsigned char
sbit ds=P1^0;
bit flag;
uchar count_t0;
float f_temp;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=122;y>0;y--);
}
void init() // 串口初始化
{
TMOD=0x21;
SCON=0x50;
TH0=0x4c;
TL0=0x00;
TH1=0xf3;
TL1=0xf3;
EA=1;
ET0=1;
TR0=1;
TR1=1;
}
void timer0() interrupt 1
{
TH0=0x4c;
TL0=0x00;
if(++count_t0>=20)
{
count_t0=0;
flag=1;
}
}
void dsreset()
{
uint i;
ds=0;
i=103;
while(i>0)
i--;
ds=1;
i=4;
while(i>0)
i--;
}
bit read_bit()
{
uint i;
bit dat;
ds=0;i++;
ds=1;i++;i++;
dat=ds;
i=8;
while(i>0)
i--;
return dat;
}
uchar read_byte()
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=read_bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
void write_byte(uchar dat)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
ds=0;
i++;i++;
ds=1;
i=8;
while(i>0)
i--;
}
else
{
ds=0;
i=8;
while(i>0)
i--;
ds=1;
i++;i++;
}
}
}
void begin_change()
{
dsreset();
delay(1);
write_byte(0xcc);
write_byte(0x44);
}
float get_temp()
{
uchar a,b;
uint temp;
float f_temp;
dsreset();
delay(1);
write_byte(0xcc);
write_byte(0xbe);
a=read_byte();
b=read_byte();
temp=b;
temp<<=8;
temp=temp|a;
f_temp=temp00625;
temp=f_temp10+05;
f_temp=f_temp+005;
return f_temp;
}
void main()
{
init();
while(1)
{
if(flag==1)
{
flag=0;
begin_change();
TI=1;
printf("The tempeature is %f\n",get_temp());
while(!TI);
TI=0;
}
}
}
0KG 0000H
AJMP MAIN
;单片机内存分配申明!
TEMPER— L EOU 29H :用于保存读出温度的低8位
TEMPER— H EOU 28H :用于保存读出温度的高8位
FLAG1 EOU 38H ;是否检测到DS18B20标志位
PNFLAG EOU 68H :数据正负标志位
A
— BIT EQU 20H :数码管个位数存放内存位置
B—
BIT EOU 21H :数码管十位数存放内存位置
C
— BIT EOU 22H :数码管小数位数存放内存位置
T
— INTEGER EOU 26H :FORMAT后的整数部分
(integer),将两字节的温度整合成1字节
T—
DF EOU 27H :FORMAT后的小数部分(decimal
fraction),半字节的温度小数(存在低四位)
MAIN:
LCALL GET— TEMPER :调用读温度子程序
LCALL T— FORMAT:将读出的2字节温度格式化
LCALL ALARM :调用报警子程序
LCALL DISPLAY :调用数码管显示子程序
LCALL D1S:延时0.5秒后再测
AJMP MAIN
:这是DS18B20复位初始化子程序
INIT
一
1820: SETB P3.5
NOP
CLR P3.5
:主机发出延时537微秒的复位低脉冲
MOV R1.#2
TSR1: MOV RO.#250
DJNZ RO,$
DJNZ R1,TSR1
SETB P3.5 :然后拉高数据线
NOP
NOP
NOP
MOV RO.#25H
TSR2: JNB P3.5,TSR3 :等待DS18B20回应
DJNZ RO,TSR2 :延时
LJMP TSR4
TSR3: SETB FLAG1 :置标志位,表示DS1820存在
LJMP TSR5
TSR4: CLR FLAG1:清标志位,表示DS1820不存在
LJMP TSR7
TSR5: MOV RO,#120
TSR6: DJNZ RO,TSR6 :时序要求延时一段时间
TSR7: SETB P3.5
RFT
:读出转换后的温度值
GET TEMPER: :SETB P3.5
LCALL INIT
一1820 :先复位DS18B20
JB FLAG1,TSS2
RET :判断DS1820是否存在若DS18B20不存在
则返回
TSS2: MOV A,#OCCH :跳过ROM匹配
LCALL WRITE 1820
MOV A,#44H :发出温度转换命令
LCALL WRITE— — 1820
LCALL DISPLAY
LCALL INIT
一1820 :准备读温度前先复位
MOV A,#OCCH :跳过ROM匹配
LCALL WRITE l820
MOV A,#OBEH :发出读温度命令
LCALL WRITE 1820
LCALL READ
一18200 :将读出的温度数据保存到
28H/29H
RET
:写DS18B20的子程序(有具体的时序要求)
WRITE
一1820:MOV R2,#8 :一共8位数据
:CLR C
WR1: CLR P3.5
MOV R3.#6
DJNZ R3,$
RRC A
MOV P3.5,C
MOV R3.#23
DJNZ R3,$
SETB P3.5
NOP
DJNZ R2,WR1
SETB P3.5
RET
;读DS18B20的程序,从DS18B20中读出两个字节的温
度数据
READ一 18200:MOV 36H,#2 :将温度高位和低位
从DS18B20中读出
MOV R1,#29H :低位存人29H(TEMPER—L),高位
存人28H(TEMPER—H)
REO0: MOV R2,#8 :数据一共有8位
REO1: :CLR C
SETB P3.5
NOP
NOP
CLR P3.5
NOP
NOP
NOP
SETB P3.5
MOV R3.#9
RE10: DJNZ R3,RE10
MOV C.P3.5
MOV R3.#23
RE20: DJNZ R3,RE20
RRC A
DJNZ R2,REO1
MOV @R1.A
DEC Rl
DJNZ 36H,REO0
RET
⋯ 一整合读出的两字节温度(关于DS18B20读出的
2字节温度格式请参考资料)______⋯ 一
T FORMAT:
报警子程序
ALARM:
:显示子程序
DISPLAY:
:1MS延时(按12MHZ算)
D1MS: MOV R7.#250
11mm:nop
nop
DJNZ R7,11mm
RET
:1MS延时(按12MHZ算)
D1S: Mov R6.#4
LOOP2: mov R5,#l25: 一一---一一一一一一~ 250
LOOP1: LCALL D1mS
DJNZ R5,LOOP1
DJNZ R6,LOOP2
RET
:7段数码管0~9数字的共阳显示代码
NUMTAB: DB
OCOH,Of9H,Oa4H,ObOH,99H,92H,82H,Of8H,80H,90H
, 0ffH
XIAOSHU:DB
OOH,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,
07H,08H,08H,09H,09H
END
应用时直接调用发送接收子程就够了,数据处理可以用周航慈编制的
浮点数运算子程,很好用
以上就是关于基于单片机的温湿度采集与控制程序(C语言)全部的内容,包括:基于单片机的温湿度采集与控制程序(C语言)、51单片机系列温度采集LCD162显示温度系统C程序、做过DS18B20温度采集的请help me等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)