M16温度传感器DS18B20控制示例程序
扫描二维码
随时随地手机看文章
//DS18b20的C语言驱动程序,三位数码管显示,读取当前环境温度,精度达0.1度,温度范围0-99度
//DS18B20详细引脚功能描述1、GND地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下
//也可以向器件提供电源;3、VDD可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。
//DS18B20的使用方法。DS18B20采用的是1-Wire总线协议方式
//即在一根数据线实现数据的双向传输
//编译环境AVRStudio4.13/AVRGCC
//系统时钟7.3728MHz,设置熔丝位为外部高频石英晶体振荡,启动时间4.1ms
//***********************************************************************
//包含文件
//***********************************************************************
#include
#include
#defineF_CPU7372800//单片机主频为7.3728MHz,用于延时子程序
#include
#include
#include
#include//中断信号头文件
//***********************************************************************
//定义变量区
//CH451各个功能命令值,根据需要写入
//***********************************************************************
#defineCH451_RESET0x0201//复位
#defineCH451_LEFT MOV 0x0300//设置移动方式-作移
#defineCH451_LEFTCYC0x0301//设置移动方式-左循
#defineCH451_RIGHT MOV 0x0302//设置移动方式-右移
#defineCH451_RIGHTCYC0x0303//设置移动方式-右循
#defineCH451_SYSOFF0x0400//关显示、键盘、看门狗
#defineCH451_SYSON10x0401//开显示
#defineCH451_SYSON20x0403//开显示、键盘
#defineCH451_SYSON30x0407//开显示、键盘、看门狗功能
#defineCH451_DSP0x0500//设置默认显示方式
#defineCH451_BCD0x0580//设置BCD译码方式
#defineCH451_TWINKLE0x0600//设置闪烁控制
#defineCH451_DIG00x0800//数码管位0显示
#defineCH451_DIG10x0900//数码管位1显示
#defineCH451_DIG20x0a00//数码管位2显示
#defineCH451_DIG30x0b00//数码管位3显示
#defineCH451_DIG40x0c00//数码管位4显示
#defineCH451_DIG50x0d00//数码管位5显示
#defineCH451_DIG60x0e00//数码管位6显示
#defineCH451_DIG70x0f00//数码管位7显示
#defineLED00x0000//数码管位0显示的数据
#defineled10x0000//数码管位0显示的数据;0x0010为不亮
#defineled20x0000//数码管位0显示的数据
#defineled30x0010//数码管位0显示的数据
#defineled40x0010//数码管位0显示的数据
#defineled50x0010//数码管位0显示的数据
#defineled60x0010//数码管位0显示的数据
#defineled70x0010//数码管位0显示的数据
#definedclk0PORTD&=~(1<
#defineDQ_INDDRC&=~(1<
#definedelay_us(x)_delay_us(x)//AVRGCC延时函数x(us)
#definedelay_ms(x)_delay_ms(x)//AVRGCC延时函数x(ms)
#defineucharunsignedchar
#defineuintunsignedint
uintvalue;
uinttemp,A1,A2,A3;//定义的变量,显示数据处理
ucharflag1;
uchartable[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
0x0e,0x0f};//数码管的BCD码
//*************************************************************************
//初始化子程序
//*************************************************************************
voidsystem_init()
{
SFIOR=(1<<2)|SFIOR;//PUD=1;关闭上拉电阻
PORTD=0x70;
DDRD=0x70;
}
voidch451_init()
{
din0;//先低后高,选择4线输入
din1;
}
//*************************************************************************
//输出命令子程序
//定义一无符号整型变量存储12字节的命令字
//************************************************************************
voidch451_write(unsignedintcommand)
{
unsignedchari;
load0;//命令开始
for(i=0;i<12;i++)
{//送入12位数据,低位在前
if(command&1)
{
din1;
}
else
din0;
dclk0;
dclk1;//上升沿有效
command>>=1;
}
load1;//加载数据
}
//*************************************************************************
//显示函数
//*************************************************************************
voiddisplay(uintb_d,uints_d,uintg_d)
{
ch451_init();
ch451_write(CH451_SYSOFF);//关显示、键盘、看门狗
ch451_write(CH451_SYSON1);//开显示
ch451_write(CH451_BCD);//设置BCD译码方式
ch451_write(CH451_TWINKLE);//设置闪烁控制
ch451_write(CH451_DIG0|table[b_d]);//显示百位数据
ch451_write(CH451_DIG1|table[s_d]|0x80);//显示十位数据
ch451_write(CH451_DIG2|table[g_d]);//显示个位数据
ch451_write(CH451_DIG3|led3);//其他数码管不显示,熄灭状态
ch451_write(CH451_DIG4|led4);
ch451_write(CH451_DIG5|led5);
ch451_write(CH451_DIG6|led6);
ch451_write(CH451_DIG7|led7);
}
//*************************************************************************
//DS18B20初始化
//*************************************************************************
unsignedchards1820_reset(void)//初始化和复位
{
unsignedchari;
DQ_OUT;
DQ_CLR;
delay_us(500);//延时500uS(480-960)
DQ_SET;
DQ_IN;
delay_us(80);//延时80uS
i=DQ_R;
delay_us(500);//延时500uS(保持>480uS)
if(i)
{
return0x00;
}
else
{
return0x01;
}
}
//*************************************************************************
//DS18B20读一个字节函数
//*************************************************************************
unsignedchards1820_read_byte(void)
{
unsignedchari;
unsignedcharvalue=0;
for(i=8;i!=0;i--)
{
value>>=1;
DQ_OUT;
DQ_CLR;
delay_us(4);//*延时4uS
DQ_SET;
DQ_IN;
delay_us(10);//*延时10uS
if(DQ_R)
{
value|=0x80;
}
delay_us(60);//*延时60uS
}
return(value);
}
//*************************************************************************
//向18B20写一个字节函数
//*************************************************************************
/*DS18B20字节写入函数*/
voidds1820_write_byte(unsignedcharvalue)
{
unsignedchari;
for(i=8;i!=0;i--)
{
DQ_OUT;
DQ_CLR;
delay_us(4);//延时4uS
if(value&0x01)
{
DQ_SET;
}
delay_us(80);//延时80uS
DQ_SET;//位结束
value>>=1;
}
}
//*************************************************************************
//发送温度转换命令
//*************************************************************************
/*启动ds1820转换*/
voidds1820_start(void){
ds1820_reset();
ds1820_write_byte(0xCC);//勿略地址
ds1820_write_byte(0x44);//启动转换
}
//*************************************************************************
//DS8B20读取温度信息
//*************************************************************************
unsignedintds1820_read_temp(void)
{
unsignedinti;
unsignedcharbuf[9];
ds1820_reset();
ds1820_write_byte(0xCC);//勿略地址
ds1820_write_byte(0xBE);//读取温度
for(i=0;i<9;i++)
{
buf[i]=ds1820_read_byte();
}
i=buf[1];
i<<=8;
i|=buf[0];
value=i;
value=value*0.625;//不是乘以0.0625的原因是为了把小数点后一位数据也转化为可以显示的数据
//比如温度本身为27.5度,为了在后续的数据处理程序中得到BCD码,我们先放大到275
//然后在显示的时候确定小数点的位置即可,就能显示出27.5度了
//value=value*10;
returni;
}
//*************************************************************************
//温度数据处理函数
//*************************************************************************
voiddata_do(uintd)
{
uintA2t;
A1=d/100;//分出百,十,和个位
A2t=d%100;
A2=A2t/10;
A3=A2t%10;
}
//*************************************************************************
//主程序
//*************************************************************************
voidmain(void)
{
DDRC=0x00;
PORTC=0xFF;
system_init();//系统初始化
delay_ms(250);
ds1820_reset();//复位D18B20
while(1)
{
ds1820_start();//启动一次转换
delay_ms(300);//等待转换结束
ds1820_read_temp();//读取温度数值
data_do(value);//处理数据,得到要显示的值
display(A1,A2,A3);//显示温度值
delay_ms(1000);//延时1S
}
}