蓝桥杯单片机温度教程
时间:2022-12-22 22:30:00
代码中的教程!如有错误,请指正
wdqd.c
/*这个是官方比赛时会给出的底层驱动,比赛时可以根据自己的写法补充*/
/*#include "reg52.h"sbit DQ = P1^4; ///单总线接口
///单总线延迟函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i )
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}//从DS18B读一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i )
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}*/
/*这是我补充的驱动代码仅供参考*/
/*DS18B20出厂时配置为12位,读取温度时读取16位,前5位为符号位,当前5位为1时,读取温度为负;当前5位为0时,读取温度为正。正时读取温度的方法是:将16进制数转换为10进制。负时读取温度的方法是:将16进制反后加1,再转换为10进制。例:0550H = 85 度,FC90H = -55 度。*/
#include "STC15F2K60S2.H"//建议用15的头文件代替,原来是reg52.h
#include "wdqd.h"void Delay_OneWire(unsigned int t);///一些非官方板使用劣质板ds18b20传感器,所以在最终使用之前,先声明延迟函数
sbit DQ = P1^四、//单总线接口///单总线延迟函数
void Delay_OneWire(unsigned int t)
{
unsigned char i;
while(t--){
for(i=0;i<12;i );//因为我们使用的是15的头文件,所以修改驱动,将延时增加11倍
}
}void Delay_us(void)///定义微秒延迟用于数据刷新
{
unsigned char i;i = 30;
while (--i);
}///通过单总线DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i )
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);}
/*写操作
(1) 低电平0首先放置数据线。
(2) 延迟确定时间为15微秒。
(3) 按从低到高的顺序发送字节(一次只发送一个)。
(4) 延迟时间为45微秒。
(5) 将数据线拉到高电平。
(6) 重复(1)到(6)的操作,直到所有字节全部发送。
(7) 最后将数据线拉高。*/
//从DS18B读一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i )
{
DQ = 0;
dat >>= 1;
DQ = 1;
Delay_us();//自己补充if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
/*读操作
(1)将数据线拉高1。
(2)延迟2微秒。
(3)将数据线拉低0
(4)延时3微秒。
(5)将数据线拉高“1”。
(6)延时5微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时60微秒。
*/
//DS18B20初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;Delay_OneWire(80); // 延时大于480us
DQ = 1;
Delay_OneWire(10); // 14
initflag = DQ; // initflag等于1初始化失败
Delay_OneWire(5);
return initflag;
}
/*初始化
(1) 先将数据线置高电平“1”。
(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)
(3) 数据线拉到低电平“0”。
(4) 延时750微秒(该时间的时间范围可以从480到960微秒)。
(5) 数据线拉到高电平“1”。
(6) 延时等待(如果初始化成功则在15到60微秒时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。
(7) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。
(8) 将数据线再次拉高到高电平“1”后结束。
*/
/*自己补充*/
//DS18B20温度采集程序:整数
unsigned int rd_temperature()
{
unsigned char L,H;
init_ds18b20();
Write_DS18B20(0xcc);//跳过ROM指令
Write_DS18B20(0x44);//转换温度指令
Delay_OneWire(80); // 延时大于480us
init_ds18b20();
Write_DS18B20(0xcc);//跳过ROM指令
Write_DS18B20(0xbe);//读温度指令L = Read_DS18B20();
H = Read_DS18B20();return (H<<8)+L;
}
//S:符号位 中7:整数 后4:小数
// 注:这段程序不唯一,个人习惯这样写,未经任何处理的原始数据(返回值为16位二进制数据)
/*在主函数应用*/
//unsigned int T; //存放16位原始数据
//unsigned char T1,T2; //存放整数/小数
//T=rd_temperature(); //获取完整温度数据
//T1=T>>4&0x007f; //获取整数数据
//T2=T&0x000f*100/16; //获取小数
//最后通过取整取余显示
wdqd.h
#ifndef _WDQD_H
#define _WDQD_H
//函数声明 全部声明
void Delay_OneWire();
void Delay_us();
void Write_DS18B20();
unsigned char Read_DS18B20();
bit init_ds18b20();
unsigned int rd_temperature();
#endif
main.c
#include
#include
#include#define uc unsigned char
#define ui unsigned int
ui temp;
uc temp1,temp2;
uc code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};//0-9,-,关闭,C
uc code tac[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void hc138(uc n)//138译码器
{
switch(n)
{
case 4:P2=(P2&0x1f)|0x80;break;
case 5:P2=(P2&0x1f)|0xa0;break;
case 6:P2=(P2&0x1f)|0xc0;break;
case 7:P2=(P2&0x1f)|0xe0;break;
}
}
void delay()//延时1毫秒
{
unsigned char i, j;_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
void OutputSMG(uc gqb,uc yxl)//数码管输出函数
{
hc138(6);
P0=0x01<hc138(7);
P0=gqb;
delay();
}void OutputP0(uc add,uc dat)//输出函数
{
hc138(add);
P0=dat;
}
void Initsystem()//初始化
{
OutputP0(4,0xff);
OutputP0(5,0x00);
OutputP0(6,0x00);
OutputP0(7,0x00);
}
void SMGwd()//数码管功能温度
{
temp=rd_temperature();
temp2=temp&0x000f;//获取小数
temp1=temp>>4;//获取整数
OutputSMG(tab[temp1/10],4);
OutputSMG(tac[temp1%10],5);
OutputSMG(tab[temp2/10],6);
OutputSMG(tab[temp2%10],7);
OutputSMG(tab[12],0);
}
void main()//主函数
{
Initsystem();
rd_temperature();
while(1)
{
SMGwd();
}}