AVR单片机(ATmega16L)DS18B20温度传感器驱动程序

发布者:zuiquan最新更新时间:2018-06-21 来源: eefocus关键字:AVR单片机  ATmega16L  DS18B20  温度传感器驱动 手机看文章 扫描二维码
随时随地手机看文章

  在DALLAS网站上下个英文版的datasheet,从第一行开始看,看着看着,感觉非常惊奇,不像我当初想当然的觉得那么难理解啊,除了个别单词不认识,整体上能看出大概意思,装了个金山词霸,不会的单词马上查,发现也不是很费劲的事儿。以前打开个英文的datasheet,看着密密麻麻的英语句子,看都没看就觉得头大,以前实在是太先入为主了,自己还是太浮躁,没有静下心来,认真的看一看。决定以后下芯片资料,直接下原版datasheet。

  从头看手册,对照程序完整的看了一遍,发现原因就在写时序上,程序中写字节的函数中有一句:temp_h,与时序图不符,写0时序开始后、DS18B20采样前,并没有拉高数据线,把temp_h注释掉,1602液晶马上显示出来正确的温度。心中大喜。马上把程序移植到AVR上,修改了头文件、延时参数、I/O口方向仍然不能正常运行,又纠结了一天,结果发现检测输入时,检测了PORTB,而非PINB,改正后程序终于正常了。明天把程序移植到PIC单片机上,希望不要再纠结了。

  AVR单片机的程序比51单片机的稍微麻烦点,与PIC单片机基本相同。通过宏修改寄存器名,可以直接移植到PIC上,应该没有大问题。把AVR单片机的程序贴出来,希望对新手有所帮助。

#include  

#define uchar unsigned char  

#define uint unsigned int  

#define rs_h (PORTB|=0x01)  

#define rs_l (PORTB&=0xfe)  

#define rs_o (DDRB|=0x01)  

#define rw_h (PORTB|=0x02)  

#define rw_l (PORTB&=0xfd)  

#define rw_o (DDRB|=0x02)  

#define en_h (PORTB|=0x04)   

#define en_l (PORTB&=0xfb)  

#define en_o (DDRB|=0x04)  

#define temp_h (PORTB|=0x08)   

#define temp_l (PORTB&=0xf7)   

#define LCD PORTA   

#define tmp (PINB&0x08)  

#define temp_o (DDRB|=0x08)  

#define temp_i (DDRB&=0xf7)  

uchar dat1,dat2;//保存读出的温度  

#define led_o (DDRB|=0x10)  

#define led_l (PORTB&=0xef)  

#define led_h (PORTB|=0x10)  

unsigned long int dat=0;  

uchar flag=0;  

void delayms(uint z)      //8M晶振下,延时1ms  

{  

 uint x,y;  

 for(x=z;x>0;x--)  

                 for(y=1333;y>0;y--);  

}  

void Ds18b20_reset(void)//DS18B20初始化  

{  

    uint count;  

    uint i=60000;  

    temp_o;  

    temp_l;  

    for(count=700;count>0;count--);//延时480us  

    temp_h;  

    temp_i;//不须配置PORT内部上拉电阻,MCU输入输出自动切换  

    while((tmp==0x08));//&&(i>0)) i--;  

    led_o;  

    led_l;//开指示灯  

    for(count=700;count>0;count--);//延时480us  

}  

void Ds18b20_write(uchar dat)//向DS18B20写一个字节  

{  

    uchar count;  

    uchar i;  

    temp_o;  

    for(i=8;i>0;i--)  

    {  

        temp_l;  

        for(count=2;count>0;count--);  

        //temp_h;//不能有此语句  

        if(dat&0x01==0x01)  

            temp_h;  

        else  

            temp_l;  

        for(count=120;count>0;count--);//延时60us  

        temp_h;  

        dat>>=1;    

    }     

}  

uchar Ds18b20_read(void)//从DS18B20读一个字节  

{  

    uchar i,datt;  

    uchar count;  

    for(i=8;i>0;i--)  

    {  

        datt>>=1;  

        temp_o;  

        temp_l;  

        for(count=2;count>0;count--);  

        temp_h;//此语句必须有,参考datasheet的P15  

        for(count=1;count>0;count--);  

        temp_i;  

        if(tmp==0x08)  

            datt|=0x80;  

        for(count=120;count>0;count--);    

    }  

    return datt;  

}  

void lcd_com(uchar com)//向LCD1602写命令  

{  

    rs_o;  

    rw_o;  

    en_o;  

    DDRA=0xff;  

    rs_l;  

    rw_l;  

    LCD=com;  

    delayms(1);  

    en_h;  

    delayms(1);   

    en_l;  

}  

void lcd_dat(uchar dat)//向LCD1602写数据  

{  

    rs_o;  

    rw_o;  

    DDRA=0xff;  

    en_o;  

    rs_h;  

    rw_l;  

    LCD=dat;  

    delayms(1);  

    en_h;  

    delayms(1);  

    en_l;  

}  

void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据  

{  

    lcd_com(0x80+0x40*c+r);  

    lcd_dat(dat);  

    delayms(1);  

}  

void lcd_init(void)//LCD1602初始化,初始化后第一行显示temperature:,第二行显示.C  

{  

    DDRA=0xff;  

    DDRB|=0x17;  

    lcd_com(0x38);  

    lcd_com(0x0c);  

    lcd_com(0x06);  

    lcd_write(0,2,0x54);  

    lcd_write(0,3,0x65);  

    lcd_write(0,4,0x6d);  

    lcd_write(0,5,0x70);  

    lcd_write(0,6,0x65);  

    lcd_write(0,7,0x72);  

    lcd_write(0,8,0x61);  

    lcd_write(0,9,0x74);  

    lcd_write(0,10,0x75);  

    lcd_write(0,11,0x72);  

    lcd_write(0,12,0x65);  

    lcd_write(0,13,0x3a);  

    lcd_write(1,11,0xdf);  

    lcd_write(1,12,0x43);  

}  

void show(void)//把温度值送LCD1602显示  

{  

    if(dat2>=240)//遗留问题,温度为25时读出dat1=144,dat2=1正确,但却进入if(dat2&0xf8==0xf8)分支;  

    {  

        dat=(~(dat2*256+dat1)+1)*(0.0625*10);//取反加一,保留一位小数  

        flag=1;  

    }  

    else  

    {  

        dat=(dat2*256+dat1)*(0.0625*10);  

        flag=0;  

    };  

    if(flag==1)//负温度显示  

    {  

        lcd_write(1,10,0x30+dat%10);  

        lcd_write(1,9,0xa5);  

        lcd_write(1,8,0x30+dat%100/10);  

        lcd_write(1,7,0x30+dat%1000/100);  

        lcd_write(1,6,0x30+dat/1000);  

        lcd_write(1,5,0x2d);  

    }  

    if(flag==0)//正温度显示  

    {  

        lcd_write(1,10,0x30+dat%10);  

        lcd_write(1,9,0xa5);  

        lcd_write(1,8,0x30+dat%100/10);  

        lcd_write(1,7,0x30+dat%1000/100);  

        lcd_write(1,6,0x30+dat/1000);  

        lcd_write(1,5,0x20);//显示空格,刷掉负号  

    }  

}  

void main(void)  

{  

    lcd_init();  

    while(1)  

    {  

        dat1=0x00;  

        dat2=0x00;  

        Ds18b20_reset();  

        Ds18b20_write(0xcc);  

        Ds18b20_write(0x44);//发送温度转换命令  

        delayms(1000);//延时1s,等待温度转换完成  

        Ds18b20_reset();  

        Ds18b20_write(0xcc);  

        Ds18b20_write(0xbe);//发送读温度寄存器命令  

        dat1=Ds18b20_read();  

        dat2=Ds18b20_read();  

        show();  

        led_h;//关指示灯  

        delayms(2000);  

    }  

}  

//编译前一定要在工程选项中设置好目标单片机型号;  

//输出送PORT寄存器  

//输入检测PIN寄存器  

关键字:AVR单片机  ATmega16L  DS18B20  温度传感器驱动 引用地址:AVR单片机(ATmega16L)DS18B20温度传感器驱动程序

上一篇:AVR单片机(ATMEGA16)定时器程序
下一篇:AVR单片机(ATMEGA16)控制蜂鸣器

推荐阅读最新更新时间:2024-03-16 16:06

基于DS18B20的MOA温度远程监控系统设计
金属氧化物避雷器(MOA) 是防止供电系统和用电设备免受雷电危害的主要设施, 一旦出现故障, 不但失去应有的防雷作用, 且可能带来供电事故。因而为确保MOA正常发挥作用, 需要在线监测MOA的运行状态。以MOA阀片温度作为故障特征量, 设计了基于DS18B20和AT89S52单片机的实时温度监测系统。研究表明, 该系统结构合理, 方法正确, 可满足应用需求, 大幅度减少了MOA维护成本。 避雷器监测中, 几乎所有需要测量的变量, 包括在正常电压及过电压下的能量吸收, 及由于老化和受潮产生的功耗, 都会影响MOA 阀片的温度。温度不仅是其实际工作状况的间接检测, 而且是避雷器本身的精确运行参数。MOA 的温度是各种影响参数共同作
[嵌入式]
STM32CubeMX | 33-使用GPIO读取温度传感器数据(DS18B20
本篇详细的记录了如何使用STM32CubeMX配置 STM32103RET6 的硬件GPIO外设读取温度传感器DS18B20的数据。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是一个工业DTU,主控芯片为STM32103RBT6。 DS18B20 DTU开发板板载一颗DS18B20温度传感器。 3. 使用STM32CubeMX生成工程 选择芯片型号 打开STM32CubeMX,打开MCU选择器: 搜索并选中芯片STM32F103RET6: 配置时钟源 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC; 如果使用默认内部时钟(HSI),
[单片机]
STM32CubeMX | 33-使用GPIO读取<font color='red'>温度传感器</font>数据(<font color='red'>DS18B20</font>)
基于AVR单片机熔丝位的设置经验分享
mega8的熔丝位设置以下内容根据mega8的英文手册翻译,希望对大家有所帮助。如发现错误,恳请大家指正。 mega8熔丝位: 1:未编程(不选中) 0:编程(选中) ******************************** 熔丝位说明缺省设置 ******************************** RSTDISBL:复位或I/O功能选择11:复位功能;0:I/O功能(PC6) WDTON:看门狗开关11:看门狗打开(通过WDTCR允许);0:看门狗禁止 SPIEN:SPI下载允许01:SPI下载禁止;0:SPI下载允许(注:当使用SPI编程时,该项不可用) EEAVE:烧录时EEPROM数据保留11:不
[单片机]
基于<font color='red'>AVR单片机</font>熔丝位的设置经验分享
51单片机学习——9--温度传感器DS18B20
DS18B20 简介 DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。 特点 1、适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电 2、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微 处理器与DS18B20的双向通讯。 3、DS18B20支持多点组网功能,多个
[单片机]
51单片机学习——9--<font color='red'>温度传感器</font><font color='red'>DS18B20</font>
单片机——ds18b20——代码
#include #include ../delay/delay.h #include lcd.h /*==================================================== 判断写入命令/数据函数 =====================================================*/ void lcd_write(unsigned char byte, unsigned char flag) { if(flag) { RS = 1; //选择数据寄存器
[单片机]
avr单片机八位流水灯程序
八位流水灯程序 单片机源程序如下: #include iom16v.h #define uint unsigned int #define uchar unsigned char void Delay_ms(uint k) { uint i,j; for(;k 0;k--) for(i=142;i 0;i--) for(j=2;j 0;j--); } void port_init(void) { DDRD=0xff; PORTD=0xff; } void main(void) { uchar temp,i; port_i
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved