
//ICC-AVR application builder : 2009-10-25 10:43:39
// Target : M16
// Crystal: 16.000Mhz
#include <iom16v.h>
#include <macros.h>
#define uint unsigned int
#define uchar unsigned char
#include "xianshi.c"
#include "delay.h"
#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=0m<8m++)
{
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=0n<8n++)
{
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=0i<4i++)
{
ad[3-i]=tem%10
tem=tem/10
}
for(i=0i<4i++)
{
show1(ad[i],i)
delay(5)
}
}
}
显示函数:
#include <iom16v.h>
#include <macros.h>
#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=0i<msi++)
{
for(j=0j<1141j++)
}
}
void show1(uchar j,uchar k)//显示函数
{
PORTB = ~BIT(k)
PORTA = tab2[j]
delay(1)
}
void show(uint ada)
{
uint i,ad[4]
for(i=0i<4i++)
{
ad[3-i]=ada%10
ada = ada/10
}
while(1)
{
for(i=0i<4i++)
{
show1((ad[i]),i)
delay(100)
}
}
}
程序我都调试过的,都是好的,有不会再问我。可以给分了吗?嘿嘿
/*********************************************************************
文件名
:
温度采集DS18B20.c
*
描述
:
该文件实现了用温度传感器件DS18B20对温度的采集,并在数码管上显示出来。
*
创建人
:
东流,2009年4月10日
*
版本号
:
2.0
***********************************************************************/
#include<reg52.h>
#define
uchar
unsigned
char
#define
uint
unsigned
int
#define
jump_ROM
0xCC
#define
start
0x44
#define
read_EEROM
0xBE
sbit
DQ
=
P2^3
//DS18B20数据口
unsigned
char
TMPH,TMPL
uchar
code
table[10]
=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
/********************************************************************
*
名称
:
delay()
*
功能
:
延时,延时时间大概为140US。
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
delay_1()
{
int
i,j
for(i=0
i<=10
i++)
for(j=0
j<=2
j++)
}
/********************************************************************
*
名称
:
delay()
*
功能
:
延时函数
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
delay(uint
N)
{
int
i
for(i=0
i<N
i++)
}
/********************************************************************
*
名称
:
Delay_1ms()
*
功能
:
延时子程序,延时时间为
1ms
*
x
*
输入
:
x
(延时一毫秒的个数)
*
输出
:
无
***********************************************************************/
void
Delay_1ms(uint
i)//1ms延时
{
uchar
x,j
for(j=0j<ij++)
for(x=0x<=148x++)
}
/********************************************************************
*
名称
:
Reset()
*
功能
:
复位DS18B20
*
输入
:
无
*
输出
:
无
***********************************************************************/
uchar
Reset(void)
{
uchar
deceive_ready
DQ
=
0
delay(29)
DQ
=
1
delay(3)
deceive_ready
=
DQ
delay(25)
return(deceive_ready)
}
/********************************************************************
*
名称
:
read_bit()
*
功能
:
从DS18B20读一个位值
*
输入
:
无
*
输出
:
从DS18B20读出的一个位值
***********************************************************************/
uchar
read_bit(void)
{
uchar
i
DQ
=
0
DQ
=
1
for(i=0
i<3
i++)
return(DQ)
}
/********************************************************************
*
名称
:
write_bit()
*
功能
:
向DS18B20写一位
*
输入
:
bitval(要对DS18B20写入的位值)
*
输出
:
无
***********************************************************************/
void
write_bit(uchar
bitval)
{
DQ=0if(bitval==1)
DQ=1
delay(5)
DQ=1
}
/********************************************************************
*
名称
:
read_byte()
*
功能
:
从DS18B20读一个字节
*
输入
:
无
*
输出
:
从DS18B20读到的值
***********************************************************************/
uchar
read_byte(void)
{
uchar
i,m,receive_data
m
=
1
receive_data
=
0
for(i=0
i<8
i++)
{
if(read_bit())
{
receive_data
=
receive_data
+
(m
<<
i)
}
delay(6)
}
return(receive_data)
}
/********************************************************************
*
名称
:
write_byte()
*
功能
:
向DS18B20写一个字节
*
输入
:
val(要对DS18B20写入的命令值)
*
输出
:
无
***********************************************************************/
void
write_byte(uchar
val)
{
uchar
i,temp
for(i=0
i<8
i++)
{
temp
=
val
>>
i
temp
=
temp
&
0x01
write_bit(temp)
delay(5)
}
}
/********************************************************************
*
名称
:
Main()
*
功能
:
主函数
*
输入
:
无
*
输出
:
无
***********************************************************************/
void
main()
{
float
tt
uint
temp
P2
=
0x00
while(1)
{
Reset()
write_byte(jump_ROM)
write_byte(start)
Reset()
write_byte(jump_ROM)
write_byte(read_EEROM)
TMPL
=
read_byte()
TMPH
=
read_byte()
temp
=
TMPL
/
16
+
TMPH
*
16
P0
=
table[temp/10%10]
P2
=
6
Delay_1ms(5)
P0
=
table[temp%10]
P2
=
7
Delay_1ms(5)
}
}
#include <reg52.h>#define uchar unsigned char
#define uint unsigned int
//数码管位定义
sbit dula = P2^6
sbit wela = P2^7
#define OK 1
#define ERROR 0
#define NUMBER 20
#define SIZE 5
sbit dht11 = P2^0
uchar status
//存放五字节数据的数组
uchar value_array[SIZE]
/*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
uchar flag
//数码管编码
uchar code array[]= {
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f
}
int temp_value, humi_value
void InitTime(void)
//void Delay_1ms(uint ms)
void SMG_Display(uint value)
void Delay_1ms(uint ms)
{
uint x, y
for(x = msx >0x--)
{
for(y = 124y >0y--)
}
}
void Delay_10us(void)
{
unsigned char i
i--
i--
i--
i--
i--
i--
}
/*读一个字节的数据*/
uchar ReadValue(void)
{
uchar count, value = 0, i
status = OK//设定标志为正常状态
for(i = 8i >0i--)
{
//高位在先
value <<= 1
count = 0
//每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
while(dht11 == 0 &&count++ <NUMBER)
if(count >= NUMBER)
{
status = ERROR//设定错误标志
return 0//函数执行过程发生错误就退出函数
}
//26-28us 的高电平表示该位是0,为70us 高电平表该位1
Delay_10us()
Delay_10us()
Delay_10us()
//延时30us 后检测数据线是否还是高电平
if(dht11 != 0)
{
//进入这里表示该位是1
value++
//等待剩余(约40us)的高电平结束
while(dht11 != 0 &&count++ <NUMBER)
{
dht11 = 1
}
if(count >= NUMBER)
{
status = ERROR//设定错误标志
return 0
}
}
}
return (value)
}
//读一次的数据,共五字节
uchar ReadTempAndHumi(void)
{
uchar i = 0, check_value = 0,count = 0
EA = 0
dht11 = 0//拉低数据线大于18ms 发送开始信号
Delay_1ms(20)//需大于18 毫秒
dht11 = 1//释放数据线,用于检测低电平的应答信号
//延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
Delay_10us()
Delay_10us()
Delay_10us()
Delay_10us()
if(dht11 != 0) //检测应答信号,应答信号是低电平
{
//没应答信号
EA = 1
return ERROR
}
else
{
//有应答信号
while(dht11 == 0 &&count++ <NUMBER)//等待应答信号结束
if(count >= NUMBER) //检测计数器是否超过了设定的范围
{
dht11 = 1
EA = 1
return ERROR//读数据出错,退出函数
}
count = 0
dht11 = 1//释放数据线
//应答信号后会有一个80us 的高电平,等待高电平结束
while(dht11 != 0 &&count++ <NUMBER)
if(count >= NUMBER)
{
dht11 = 1
EA = 1
return ERROR//退出函数
}
//读出湿.温度值
for(i = 0i <SIZEi++)
{
value_array[i] = ReadValue()
if(status == ERROR)//调用ReadValue()读数据出错会设定status 为ERROR
{
dht11 = 1
EA = 1
return ERROR
}
//读出的最后一个值是校验值不需加上去
if(i != SIZE - 1)
{
//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
check_value += value_array[i]
}
}//end for
//在没用发生函数调用失败时进行校验
if(check_value == value_array[SIZE - 1])
{
//将温湿度扩大10 倍方便分离出每一位
humi_value = value_array[0] * 10
temp_value = value_array[2] * 10
dht11 = 1
EA = 1
return OK//正确的读出dht11 输出的数据
}
else
{
//校验数据出错
EA = 1
return ERROR
}
}
}
void main(void)
{
uchar mark = 0
//先等上电稳定
Delay_1ms(1000)
//因为读一次数据dht11 才会触发一次采集数据.
//即在先使用数据时采集一次数据
ReadTempAndHumi()
//因为在两次采集数据需一定的时间间隔,这里还可减少
Delay_1ms(3000)
//设定定时器
InitTime()
while(1)
{
//三秒读一次温湿度
if(flag == 60)
{
flag = 0
mark++
/*
//读温湿度,可检测函数调用是否失败,
//函数返回OK(1)表示成功,返回ERROR(0)表示失败
//OK和ERROR是在DHT11.H中定义的宏
*/
ReadTempAndHumi()
}
if(mark % 2 == 0)
{
//显示温度
SMG_Display(temp_value)
}
else
{
//显示湿度
SMG_Display(humi_value)
}
}
}
//设定定时器
void InitTime(void)
{
TH0 = (65535 - 50000)/256
TL0 = (65535 - 50000)%256
TMOD = 0X01
TR0 = 1
ET0 = 1
EA = 1
}
//数码管显示函数
void SMG_Display(uint value)
{
uchar ge, bai, shi
ge = value % 10
shi = value % 100 / 10
bai = value % 1000 / 100
wela=1
P0 = 0XFE
wela=0
P0 = 0XFF
dula=1
P0 = array[bai]
dula=0
Delay_1ms(2)
wela=1
P0 = 0XFD
wela=0
P0 = 0XFF
dula=1
P0 = array[shi]
P0 |= 0x80/*显示小数点*/
dula=0
Delay_1ms(2)
wela=1
P0 = 0XFB
wela=0
P0 = 0XFF
dula=1
P0 = array[ge]
dula=0
Delay_1ms(2)
}
//中断函数
void timer(void) interrupt 1
{
TH0 = (65535 - 50000)/256
TL0 = (65535 - 50000)%256
flag++
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)